按需查阅，不是必读接入步骤。接入路线：[查询取数接入路线](/docs)

# 定期采集用户与频道

需要持续获取某个平台用户或频道的新内容时，创建周期采集订阅。Whale 按你设定的间隔派发采集任务，结果写入数据中心，你再用[检索](/docs/search)、[按用户或话题筛选](/docs/browse)或[增量同步](/docs/change-feed)读取。

| `resource_kind` | 同步什么 | 对应任务类型 |
| --- | --- | --- |
| `user` | 一个平台用户的身份、公开资料和公开内容 | `user_sync` |
| `channel` | 频道、话题、标签、RSS/feed 或其他公开信息流 | `channel_sync` |

只读取已经采集过的用户资料或内容时，直接用[用户、话题、标签与分类](/docs/browse)，不需要创建订阅。

## 使用前提

- 已按[获取与使用 API Key](/docs/authentication)配置 `WHALE_BASE_URL` 和 `WHALE_API_KEY`，本机有 curl 和 jq。
- 你的应用订阅需要**显式**包含目标数据集和平台，并由 Whale 开启周期采集权限（`collection_subscription_enabled`）。没有时创建返回 `403`，请联系你的组织管理员向 Whale 申请。
- 目标平台需要有在线、且支持对应任务类型的采集器；没有时创建返回 `403`。

## 创建订阅

同步一个 YouTube 用户，每小时一次：


```bash
subscription_response="$(curl -sS --fail-with-body -X POST "$WHALE_BASE_URL/v1/collection/subscriptions" \
  -H "Authorization: Bearer $WHALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "youtube-creator-watch",
    "dataset_id": "social_media_raw",
    "source_platform": "youtube",
    "resource_kind": "user",
    "user_id": "channel_123",
    "interval_seconds": 3600
  }')"
printf '%s' "$subscription_response" | jq .
SUBSCRIPTION_ID="$(printf '%s' "$subscription_response" | jq -er '.subscription.id')"
```


同步一个微博话题，每 15 分钟一次，请求体换成：


```json
{
  "dataset_id": "social_media_raw",
  "source_platform": "weibo",
  "resource_kind": "channel",
  "topic": "ai-agent",
  "interval_seconds": 900
}
```


| 字段 | 必填 | 说明 |
| --- | ---: | --- |
| `dataset_id` | 是 | 写入的数据集，必须在你的订阅中显式授权 |
| `source_platform` | 是 | 平台枚举，必须在你的订阅中显式授权，见[平台覆盖与能力](/docs/platforms) |
| `resource_kind` | 是 | `user` 或 `channel` |
| `user_id` / `user_url` | 条件 | `user` 时至少一个：平台用户 ID 或主页链接 |
| `channel_id` / `channel_url` / `topic` | 条件 | `channel` 时至少一个：频道 ID、频道链接或话题/标签 |
| `interval_seconds` | 是 | 执行间隔，60–604800 秒（1 分钟到 7 天） |
| `name` | 否 | 便于识别的名称 |
| `sync_mode` | 否 | `all_content`：首次执行回填全部可见内容，成功后自动转为增量；`incremental`：从上次成功的位置继续，只取新内容。`user` 默认 `all_content`，`channel` 默认 `incremental` |
| `max_items` | 否 | 每次执行最多采集的条数；省略时由采集器决定 |
| `next_run_at` | 否 | 首次执行时间，RFC 3339；省略时尽快执行 |
| `max_attempts` | 否 | 单次执行失败后的最大尝试次数，默认 3 |

请求成功返回 `201`：


```json
{
  "subscription": {
    "id": "cspec_01K...",
    "dataset_id": "social_media_raw",
    "source_platform": "youtube",
    "resource_kind": "user",
    "task_type": "user_sync",
    "payload": {"resource_kind": "user", "sync_mode": "all_content", "user_id": "channel_123"},
    "interval_seconds": 3600,
    "status": "active",
    "next_run_at": "2026-10-14T09:00:00Z",
    "created_at": "2026-10-14T08:00:00Z"
  }
}
```


后续接口都使用 `subscription.id`。

## 查看订阅与每次执行

列出你的应用的订阅（`limit` 1–200，默认 50）：


```bash
curl -sS --fail-with-body "$WHALE_BASE_URL/v1/collection/subscriptions?limit=50" \
  -H "Authorization: Bearer $WHALE_API_KEY" | jq '.subscriptions[] | {id, status, next_run_at, last_run_at}'
```


每次到期都会创建一个独立的采集任务。查看某个订阅的执行历史，可用 `status` 过滤：


```bash
curl -sS --fail-with-body "$WHALE_BASE_URL/v1/collection/subscriptions/$SUBSCRIPTION_ID/tasks?limit=20" \
  -H "Authorization: Bearer $WHALE_API_KEY" | jq '.tasks[] | {id, status, attempt_count, last_error, result, updated_at}'
```


| 任务 `status` | 含义 |
| --- | --- |
| `pending` | 已派发，等待采集器领取 |
| `leased` / `running` | 采集器已领取，正在执行 |
| `succeeded` | 本次执行完成，`result` 中有采集统计 |
| `failed` / `timeout` | 本次失败或超时，`last_error` 说明原因；未达 `max_attempts` 时会重试 |
| `paused` / `canceled` | 已暂停或取消 |

只有 `succeeded` 的任务会推进同步位置；失败或超时的任务不会跳过内容，下一次执行从上次成功的位置继续。

任务成功表示采集完成，内容随后异步入库并建立索引，可能稍晚才能查到。用[增量同步数据](/docs/change-feed)可以按变化读取，不必逐个任务对账。

## 暂停与恢复

暂停只阻止之后的派发，不会中断正在执行的任务：


```bash
curl -sS --fail-with-body -X POST "$WHALE_BASE_URL/v1/collection/subscriptions/$SUBSCRIPTION_ID/pause" \
  -H "Authorization: Bearer $WHALE_API_KEY" | jq '.subscription.status'

curl -sS --fail-with-body -X POST "$WHALE_BASE_URL/v1/collection/subscriptions/$SUBSCRIPTION_ID/resume" \
  -H "Authorization: Bearer $WHALE_API_KEY" | jq '.subscription.status'
```


订阅 `status` 为 `active`、`paused` 或 `disabled`。`disabled` 表示订阅已被 Whale 停用，你无法自行恢复，请联系你的组织管理员。

## 计费、限流与错误

订阅接口的每次调用按一次请求计量，按你的组织定价扣减积分，失败的请求会退回。请求受应用统一限流。

| HTTP | code | 含义与处理 |
| --- | --- | --- |
| 400 | `invalid_json` | 请求体不是合法 JSON |
| 400 | `collection_request_failed` | 字段校验未通过，例如缺少用户或频道标识、`interval_seconds` 超出范围；按 `message` 修正 |
| 401 | `unauthorized` | API Key 无效 |
| 402 | `credit_insufficient` | 组织积分不足 |
| 403 | `collection_request_failed` | 未开启周期采集、数据集或平台未在订阅中显式授权，或目标平台没有可用采集器 |
| 404 | `collection_request_failed` | 订阅不存在或不属于你的应用 |
| 429 | `rate_limit_exceeded` | 超过限流，按 `Retry-After` 退避 |
| 503 | `collection_request_failed` | 服务暂时不可用，稍后重试 |

完整字段见[公开 API Reference](/public-api-reference)。

## 继续当前任务

[返回接入路线](/docs)；查完所需信息后，回到正在执行的步骤。 