目录
概述
用户扫描活动方生成的二维码,领取店铺稿件并发布至抖音;平台获取作品后自动核验,并将任务状态变更推送至活动方配置的回调地址;活动方服务端使用 API 密钥回查结果,状态为 verified 时按自有规则发放奖励。
活动方无需预先调用接口创建任务或选择稿件:二维码中携带自定义任务号,用户首次成功领取稿件时平台才会创建任务。
活动方生成二维码 → 用户扫码 → 平台分配稿件 → 用户发布 / 回填作品
↓
活动方接收状态通知 ← 平台核验(或人工补核) ← 获取作品
↓
活动方服务端回查任务 → verified → 按 (shop, task_id) 幂等发放奖励
接入准备
以下步骤均在控制台完成:
| 步骤 | 说明 |
|---|---|
| 申请开通 | 在「店铺与开通」中选择本人名下的种草码店铺,提交品牌、活动信息及回调地址,经运营审核后开通。回调地址须为公网 HTTPS 地址,提交时校验其可解析性 |
| 测试回调地址 | 在「接入配置」中发送测试通知,确认可正常接收;如需更换地址也在此修改 |
| 创建 API 密钥 | 在「API 密钥」中创建,完整密钥仅显示一次,请妥善保存至服务端 |
| 生成二维码 | 按下文规则拼接链接生成二维码;控制台提供测试二维码,可用于完整验证流程 |
shop为店铺 ID(非店铺名称),可在控制台店铺列表中复制。- API 密钥仅限服务端使用,请勿写入二维码、网页、小程序代码或日志。种草专用密钥仅可调用本文所述查询接口。
- 每位参与者核验通过后占用一篇稿件,该稿件不再分配给其他用户;可参与人数取决于店铺笔记库中可发布的稿件数量,请在活动期间保持稿件储备。
- 计费沿用种草码既有额度,不按任务单独计费。
生成二维码
将以下链接生成二维码,无需预先调用平台接口:
https://justailab.com/task?shop=<店铺 ID>&task_id=<任务号>
参数须进行 URL 编码,避免 &、+、空格或中文字符改变语义:
const url = new URL('https://justailab.com/task');
url.searchParams.set('shop', 'mch_example_shop');
url.searchParams.set('task_id', 'activity_20261012_user_1001');
// 将 url.toString() 生成二维码;请勿在链接中附加 API 密钥
shop、task_id去除首尾空白后长度为 1–128 个字符。(shop, task_id)唯一确定一个任务,重试时须使用相同任务号。- 同一任务号重复扫码将返回同一稿件;未通过时重新扫码将更换稿件;核验通过后不可再次领取。
- 同一用户参与新一期活动且允许再次获奖时,请使用新的任务号;长期复用同一用户 ID 将返回原任务。
- 二维码参数仅用于定位任务,不校验扫码人身份。参与资格、任务号与获奖人的对应关系由活动方自行管理。
- 店铺可发布稿件不足时,扫码页提示活动暂停,不会创建任务,同时推送店铺级提醒。
查询任务
GET https://justailab.com/openapi/seeding/tasks?shop=<店铺 ID>&task_id=<任务号>
Authorization: Bearer <种草专用 API 密钥>
仅支持 GET 方法,路径末尾不带 /,两个参数均为必填。仅可查询密钥所属账号名下的店铺。查询为只读操作,不会领取稿件,也不会延长时限。
curl --get "https://justailab.com/openapi/seeding/tasks" \
-H "Authorization: Bearer $ZHONGCAO_API_KEY" \
--data-urlencode "shop=mch_example_shop" \
--data-urlencode "task_id=activity_20261012_user_1001"
成功响应:
{
"status": "ok",
"data": {
"shop": "mch_example_shop",
"task_id": "activity_20261012_user_1001",
"status": "verified",
"reason": "",
"publish_link": "https://www.douyin.com/video/1234567890",
"deadline_at": "2026-10-12T14:00:00+08:00"
}
}
| 字段 | 说明 |
|---|---|
顶层 status | 请求结果:ok 或 error,不代表任务状态 |
data.status | 任务状态,详见下一节 |
data.reason | 状态原因,无原因时为空字符串 |
data.publish_link | 本次领取对应的抖音作品链接,无作品时为空字符串 |
data.deadline_at | 带时区偏移的 ISO 8601 时间,为本次自动核验的截止时间,请按偏移解析 |
存在作品链接不代表核验通过,发放奖励须以 data.status=verified 为准。
错误处理
{"status":"error","code":"shop_forbidden","message":"无权查询该店铺"}
除请求方法错误返回 HTTP 405 外,业务、鉴权及内部错误通常同样返回 HTTP 200,请以顶层 status 判断请求结果。
| code | 含义 | 处理建议 |
|---|---|---|
missing_api_key | 未携带 Authorization | 补充 Bearer 请求头 |
invalid_api_key | 密钥格式错误或无效 | 核对密钥,避免循环重试 |
disabled_api_key / expired_api_key | 密钥或账号不可用 | 在控制台重新创建密钥 |
auth_policy_unavailable | 鉴权服务暂不可用 | 退避重试,暂不发放奖励 |
insufficient_scope | 非种草专用密钥 | 在控制台创建种草专用密钥 |
invalid_request / invalid_shop / invalid_task_id | 参数缺失或超长 | 修正参数 |
shop_forbidden | 店铺不属于该密钥所属账号,或尚未开通 | 核对店铺与密钥 |
task_not_found | 任务不存在(用户尚未领取稿件) | 核对任务号,不得据此发放奖励 |
method_not_allowed | 请求方法不是 GET | 改用 GET |
internal_error | 服务暂时异常 | 退避重试,并保留本地待处理任务 |
任务状态与规则
| 状态 | 含义 | 用户后续操作 | 是否发放奖励 |
|---|---|---|---|
claimed 已领取 | 用户已领取稿件 | 按页面指引发布 | 否 |
clicked 已点击发布 | 用户已点击发布,尚未确认作品 | 完成发布,必要时回填作品链接 | 否 |
verifying 核验中 | 已获取作品,正在核验 | 等待结果,截止前可重新回填 | 否 |
verified 已完成 | 核验通过,不可再次领取 | 返回活动查看奖励 | 回查确认后发放一次 |
failed 未通过 | 本次领取结束,可重新参与 | 使用同一二维码重新扫码更换稿件 | 否 |
unverifiable 待人工确认 | 暂无法完成自动核验 | 等待平台人工确认,期间不可更换稿件 | 否 |
unverifiable 状态后,平台将再次推送 verified 或 failed,该状态不存在自动失败或自动释放时限;请勿自行视为失败并更换任务号重试。
时限自本次领取起计算:
- 领取后 4 小时内未获取作品:判定为
failed,reason=expired,稿件释放。 - 截止前首次获取作品:核验截止时间调整为「获取作品后 4 小时」与「领取后 8 小时」中较早者。
- 点击发布不延长时限,重新回填亦不再延长。获取作品后第 5、15、30、60 分钟各核验一次,此后每 30 分钟一次,截止时进行最终核验;实际处理与通知可能略晚于截止时间。
- 核验期间作品不可见或内容不匹配时将继续等待,不提前判定失败;作品可见且匹配即判定通过。截止时作品明确不存在判定为
failed/not_found,内容不匹配判定为failed/mismatch,无法取得核验结果判定为unverifiable/fetch_unavailable。
作品来源以抖音发布回传为主、用户回填为辅;获取作品仅表示开始核验。平台将作品文本与本次领取的原稿进行比对,链接、话题标签、空白及标点会先行归一化;请引导用户按原稿发布,明显删改可能导致核验不通过。当前不以图片、播放量或点赞量作为核验条件,核验通过后作品被删除亦不会自动撤销结果。
常见原因包括空字符串、expired、not_found、mismatch、fetch_unavailable;人工补核可能附带运营填写的原因,请勿仅凭 reason 判断是否发放奖励。
接收状态通知
平台向活动方配置的回调地址发送 POST application/json 请求,请求体即任务字段,不含外层 data:
{
"shop": "mch_example_shop",
"task_id": "activity_20261012_user_1001",
"status": "verifying",
"reason": "",
"publish_link": "https://www.douyin.com/video/1234567890",
"deadline_at": "2026-10-12T14:00:00+08:00"
}
| 规则 | 说明 |
|---|---|
| 状态变更即通知 | 领取、点击发布、进入核验、自动或人工核验结果、失败后重新领取均会触发通知 |
| 同一任务顺序投递 | 前一条收到 HTTP 2xx 后才投递下一条;不同任务之间不保证顺序 |
| 返回 2xx 即视为送达 | 对响应体无要求;建议先可靠落库或入队后快速返回 200/204,再异步回查与发奖 |
| 失败自动重试 | 非 2xx 或网络失败时,自约 30 秒起按指数退避重试,最长间隔 1 小时;不跟随重定向 |
| 可能重复或延迟 | 不提供事件 ID 与签名,奖励须按 (shop, task_id) 去重 |
| 仅支持公网 HTTPS | 不得为 localhost、内网地址或包含账号信息的 URL,证书须有效 |
接收通知时,任务实际状态可能已晚于通知中的状态,请以查询结果为准,不得以过期通知覆盖已确认的完成状态。通知不含签名,仅作为回查触发信号,不能作为发放奖励的依据。
稿件不足提醒
{"shop":"mch_example_shop","task_id":"","status":"out_of_stock","reason":"pool_empty","publish_link":""}
表示店铺当前无可分配稿件,扫码页提示活动暂停。该通知为店铺级提醒,不对应任务,不含 deadline_at,也无法以空任务号回查。连续缺货仅提醒一次;补充稿件并有用户成功领取后再次缺货,将再次提醒。请及时在笔记库补充稿件,不得为该通知创建奖励记录。
测试通知
控制台「发送测试通知」将推送一条 test=true、status=test、reason=webhook_test、任务号以 __test__ 开头的通知,deadline_at 为 null,不对应真实任务,亦无法查询。请识别后直接返回 2xx,不得据此发放奖励。
推荐的奖励发放流程
接收通知
├─ out_of_stock 或 test:记录后返回 2xx
└─ 正常任务:可靠入队后返回 2xx
↓ 业务系统异步处理
使用种草专用密钥查询该任务
├─ 查询异常:保留待处理任务,退避重试
├─ 非 verified:更新展示状态,暂不发放奖励
└─ verified:按 (shop, task_id) 创建唯一奖励任务
↓ 使用同一幂等键调用奖励发放系统
发放成功后标记完成;失败则继续重试
请先校验该 shop/task_id 为本活动已登记的任务,防止伪造通知触发奖励发放。接收通知成功与奖励发放成功须分别记录;返回 2xx 后,后续查询或发放失败应由活动方自有队列恢复,不应依赖平台再次通知。并发收到重复通知时,请通过数据库唯一约束或奖励系统的幂等能力确保仅发放一次。
联调自查清单
- 控制台显示店铺已开通,测试通知可正常接收并返回 2xx,API 密钥可查询本店铺任务。
- 首次扫码领取一篇稿件,重复扫码返回同一稿件;点击发布不会直接判定通过,提交作品后进入核验。
- 回调地址返回一次非 2xx,确认平台会重试,且不会重复发放奖励。
- 收到
verified后服务端回查再发放奖励;重复通知、并发回查及发放失败恢复后仍仅发放一次。 - 自动核验失败后使用同一任务号重新扫码可更换稿件,查询与通知仍使用原任务号。
- 待人工确认期间不可更换稿件;人工确认完成后将再次推送通知。
- 稿件不足时不创建任务,店铺级提醒不触发奖励发放;使用其他账号的店铺或普通密钥查询将被拒绝。