结果与句柄
一次调用没法在请求里答完时,不会让你一直等:它先返回 202 和一个结果句柄,之后用 GET /v1/results/{handle} 读这次调用的结果。读结果免费,可以反复读;只有发起调用的那把 Key 能读;结果在运行结束后保存 24 小时。通过 MCP 时,把同一个句柄填进工具的 handle 参数。运行结束前不扣积分,调用失败不扣。
https://api.socialtoai.com/v1/results/{handle}什么时候会返回句柄
- 慢接口。 少数接口本来就慢,它们一上来就返回句柄;接口自己的页面上写明了这一点。
- 等待到时了。 其他调用最多等平台 40 秒。到时还没有结果,请求就返回句柄,调用在后面继续跑。
- 在后台运行的工具。 报价里的
quote.mode会写明。
这时返回的是 HTTP 202,带 Retry-After 响应头和下面这个结构。status 是 running,billing.cost_credits 是 0:运行结束前不扣积分。
{ "request_id": "req_00000000-0000-4000-8000-000000000003", "schema_version": "v1", "status": "running", "handle": "res_00000000000040008000000000000003", "retry_after_seconds": 5, "billing": { "cost_credits": 0, "balance_credits": 100, "today_spend_credits": 0, "daily_limit_credits": null, "daily_remaining_credits": null, "display": "本次 0 积分,余额 100 积分" }}| 字段 | 类型 | 说明 |
|---|---|---|
request_id | string | 这次返回的编号,报告问题时带上它。 |
schema_version | "v1" | 固定是 "v1"。 |
status | "running" | 在这个返回里固定是 "running"。 |
handle | string | 读结果用的句柄。 |
retry_after_seconds | integer | 多少秒后值得来读。响应头 Retry-After 里是同一个数。 |
cells | array | 请求里有多个平台或目标时:已经结束的那几份结果,和最终返回里的一样。(可能不出现) |
steps | array | 工具运行时:已经走到的各个步骤。(可能不出现) |
billing.cost_credits | integer | 这里固定为 0:运行结束前不扣积分。 |
billing.balance_credits | integer | 当前余额。 |
billing.today_spend_credits | integer | 今天(UTC)已经花掉的积分,这次运行暂时占用的部分也算在里面。 |
billing.daily_limit_credits | integer | null | 每日上限;没设时为 null。 |
billing.daily_remaining_credits | integer | null | 每日上限还剩多少;没设时为 null。 |
billing.display | string | 一句可以直接复述给你的话。 |
waves.planned | integer | |
waves.done | integer | |
charge.quote_credits | integer | |
charge.charged_credits | integer |
读结果
curl https://api.socialtoai.com/v1/results/res_00000000000040008000000000000003 \ -H "Authorization: Bearer $SOCIALTOAI_KEY"- 还在跑: HTTP 202,结构和上面一样。等
retry_after_seconds秒再读。 - 跑完了: 就是那次调用本来会返回的内容,状态码也是它自己的:200 时是外层结构,失败时是错误结构 和对应的状态码。
billing.cost_credits是这次运行扣的积分,余额是你读的这一刻的。 - 读结果免费。 读多少次都行;运行只在结束时按平常的规则扣一次。
- 运行在我们这边出了问题: HTTP 500
internal_error,没有扣费。
谁能读
只有发起这次调用的那把 Key。对其他 Key 来说(同一个账户下的另一把也一样),这个句柄不存在:HTTP 404 not_found。光有句柄打不开结果,读的时候总要带上 Key。你在 Playground 里发起的调用,在控制台里凭登录读取。
保存多久
结果在运行结束后保存 24 小时。过了这个时间,句柄返回 HTTP 410 handle_expired。想再要数据,就重新发起调用:那是一次新的调用,照常计费。
导出成文件
加上 ?format=csv 或 ?format=ndjson,把跑完的结果里的条目导出成文件:一张表,或每行一个 JSON 对象。运行还没结束时,不管选什么格式,返回的都是上面的 202 结构。format 填了别的值会被拒绝,错误代码是 invalid_params。
- CSV 的列是各行出现过的全部字段。嵌套字段写成
a.b,列表留在一个单元格里。 - 以
=、+、-、@开头的单元格前面会加一个撇号,免得表格软件把它当公式执行。
curl "https://api.socialtoai.com/v1/results/res_00000000000040008000000000000003?format=csv" \ -H "Authorization: Bearer $SOCIALTOAI_KEY" -o result.csv通过 MCP
13 个计费工具都多一个参数 handle。带了 handle 的调用只读那个结果:别的什么都不跑,不扣积分,其他参数也不看。所以工具返回 status: "running" 时,你的 AI 带着句柄再调一次同一个工具就行。
很大的结果:more.handle
MCP 的一次返回最多放大约 60 KB 的 JSON(约 2 万 token),免得占满模型的上下文。更大的结果先给前面的若干条,外加一个 more 对象:
| 字段 | 类型 | 说明 |
|---|---|---|
more.handle | string | 带着接续位置的句柄,写成“句柄.位置”。拿它再调同一个工具,取后面的条目。 |
more.rows_left | integer | 还剩多少条没给。 |
more.note | string | 给 AI 看的一句话:怎么接着读。 |
接着读是免费的,读到返回里没有 more 为止。走 HTTP 时用同一个句柄(不带位置),一次读到完整结果。
同一个请求再发一次
有了句柄,Idempotency-Key 的用法不变。运行还没结束时,同一个键加同样的参数会被拒绝(HTTP 409);运行结束后,它返回第一次的结果,不再扣费。
最近更新: