Seedance 幂等提交与异常恢复
Seedance 幂等提交与异常恢复 — Idempotency-Key, HTTP 409, acceptance_unknown.
Seedance 幂等提交与异常恢复
为 seedance-2.0、seedance-2.0-fast、seedance-2.0-mini、seedance-2.5 的生成请求添加 Idempotency-Key。支持 POST /v1/videos、POST /v1/videos/generations 和 POST /v1/video/generations,三个路径共享键空间。图片生成、报价、remix 路径及其他视频模型不在本次支持范围内。不带键的请求保留现有行为,不具备通用提交去重保证。
范围与键
键的范围是 APIMaster 用户账户内的 Seedance 视频生成操作,不限于某一 API Key 或某一模型。每次新生成使用新的随机键,长度为 8–128 个可见 ASCII 字符。同一账户的有效 API Key 可查询回执;额度耗尽的令牌仍可查询或重放已有回执,过期、撤销、删除的令牌及被禁用的账户不能访问。新生成仍要求有效凭证和足够额度。
原子去重与冲突
路由、计费及联系生成供应商前,数据库先原子保存受理记录。同键同内容返回 HTTP 202、原受理记录和预生成任务 ID,并发重试及服务器重启也不会再次提交或预扣。同键改内容返回 HTTP 409(idempotency_conflict)。忽略 JSON 对象字段顺序与空白;数组顺序、数字、省略参数与显式默认值、模型、通知设置、路由分组及指定渠道均参与比较。multipart 忽略边界和文件名,但比较文件字节及顺序。请保持原正文和路由设置不变;JSON 与 multipart 不视为相同请求。记录至少保留 30 天,本版本不自动删除或允许旧键重新使用;新生成始终用新键。
响应
首次请求保留正常创建响应,请保存 X-Video-Submission-Id、请求 ID 和任务 ID。重放返回受理回执,不保证与首次响应格式相同。预生成的任务 ID 本身不代表上游已受理。accepted 表示供应商受理,不表示生成完成;只有 task_ready=true 时才查询原任务,否则联系支持,勿重新提交。
提交状态
pending:网关已记录,尚未开始提交供应商。submitting:已开始提交,结果待确认。accepted:已收到供应商任务 ID。not_accepted:已确认未受理:请求尚未发送,或上游已明确拒绝且未返回任务 ID。仅在回执 new_submission_safe=true 时,修正请求并使用新键提交;HTTP 400 本身不能证明未受理。 acceptance_unknown:供应商可能已受理,但没有确认回执,不能再次创建生成。崩溃遗留的未完成记录由后台在 30 分钟后分类:提交前变为 not_accepted,提交后变为 acceptance_unknown,任何状态都不会自动重提。这些是提交状态,不是账务状态;现有预扣、结算和退款对账流程继续适用。
恢复流程
超时或 5xx 后,即使没有任务 ID,也先用原键查询。在支持范围内,同键同内容重放是安全的,但不会重启失败的提交。查询 404、任务列表为空或没有消费日志都不能证明未受理:原请求可能仍在途中,也可能未带键或发生在功能上线前。same_key_replay_safe 表示可安全取回同一回执;只有明确的 not_accepted 回执才会返回 new_submission_safe=true。结果未知或 accepted 且 task_ready=false 时,提供受理/请求 ID、模型及 UTC 时间给支持,勿发送 API Key。不承诺上游幂等,直接给官方接口传此请求头不等于获得本网关保证。历史真人素材回执保留原重放流程,按键查询可能返回旧版结构。
调用示例
curl --fail-with-body 'https://apimaster.ai/v1/videos' \
-H "Authorization: Bearer $APIMASTER_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: seedance-order-20261014-001' \
-d '{"model":"seedance-2.0","prompt":"A paper boat on a pond","duration":4,"resolution":"480p","generate_audio":false}'
curl --fail-with-body 'https://apimaster.ai/v1/video-submissions/by-key' \
-H "Authorization: Bearer $APIMASTER_KEY" \
-H 'Idempotency-Key: seedance-order-20261014-001'
{
"code": 200,
"data": {
"submission_id": "HASH",
"task_id": "task_PUBLIC_ID",
"request_id": "ORIGINAL_REQUEST_ID",
"model": "seedance-2.0",
"status": "accepted",
"task_ready": true,
"created_at": 1791936000,
"updated_at": 1791936001,
"next_action": "query_task",
"same_key_replay_safe": true,
"new_submission_safe": false,
"retention": "at_least_30_days_no_automatic_key_reuse"
}
}
curl --fail-with-body 'https://apimaster.ai/v1/videos/task_PUBLIC_ID' \
-H "Authorization: Bearer $APIMASTER_KEY"
curl --fail-with-body 'https://apimaster.ai/v1/videos/task_PUBLIC_ID/billing' \
-H "Authorization: Bearer $APIMASTER_KEY"
受理、最终账务与人工处理(2026-10-21)
GET /v1/video-submissions/by-key 只读取已保存的本地回执,不发起供应商查询、不恢复任务、不预扣、不生成替代任务。支持原供应商核对的请求由现有后台独立处理。使用原服务、原账户的有效认证及原 Idempotency-Key;APIMaster 与 RomaAPI 不共享回执。 保留原 API 基址和区域;使用独立数据库的区域部署不共享原子占用记录,跨区域或跨服务切换不属于同 key 恢复保证。
新增 data.recovery,明确区分已确认事实与未知状态:
| 字段 | 含义 |
|---|---|
acceptance_final |
本地回执已为 accepted 或 not_accepted;受理最终态不等于任务成功或账务完成。 |
original_generation_billing_final、original_generation_zero_net |
仅在已保存并校验原身份的供应商明确 not_accepted、无任务、无预留、四类账本均为 not_applicable,且客户退款完成时同时为 true。只证明这笔原生成,不包含独立素材认证费用。false 表示尚无此最终零净额证明。 |
safe_new_attempt |
自动恢复的保守门槛:只有 status=not_accepted 且上述最终零净额证据齐全才为 true;旧 key 仍不能启动另一次生成。 |
independent_asset_fees_status |
unverified,不能由生成回执推断独立素材认证费用为零。 |
manual_review_required、escalation_status、review_after |
submitting、acceptance_unknown 或 accepted 但任务不可读的请求,自原创建时间满 30 分钟后显示 manual_review_required 并进入管理员待处理列表。不会自动拒绝、取消或重提。 |
support_reference、external_ticket_status |
用提交 ID 联系现有客服渠道。外部供应商工单为 not_tracked;待处理条目不代表已经向供应商发送工单。 |
lookup_attempts、last_lookup_at、last_lookup_code |
已保存的后台核对次数、最近时间和结构化诊断;旧记录可能无最近时间或诊断。provider_observation_recorded 表示已保存有效观察,观察仍可能是未知;provider_reconciliation_unavailable 表示发现、证据应用或原任务刷新未完成。两种诊断都不授权重提。 |
next_check_at、next_check_is_resolution_deadline |
下次调度可处理时间,Unix 秒或 null,期限标记始终 false。退避、租约、排队及上游可用性可能推迟实际查询。 |
resolution_deadline、cancellation_supported |
null 和 false;没有已承诺的最终对账 SLA,也没有可保证封锁已发送未知请求的公开取消接口。 |
temporary_technical_failure、error_allows_new_submission |
可识别临时技术失败,但错误本身永不授权新提交。 |
自动创建替代任务前,应同时要求认证后的原回执满足:status=not_accepted、new_submission_safe=true、recovery.acceptance_final=true、recovery.safe_new_attempt=true,以及两个原生成账务标记均为 true。对于缺少最终账务证明的本地发送前拒绝,保守门槛仍可为 false;旧字段 new_submission_safe 只描述受理安全,不代表最终账务。退款、客户净额为零、任务或面板行不存在,以及 HTTP 404/408/429/5xx 均不足以证明可重提。只有 task_ready=true 才查询原公开 task ID 的任务。
识别的技术错误为 do_request_failed、read_response_body_failed、submission_storage_unavailable、refund_receipt_unavailable、build_request_failed。通用 video_service_error 需具体检查,不仅凭名称认定临时失败。以上错误和核对诊断均不能证明未受理;保留原身份查询,不能按 30–60 秒超时推断安全重提。
lookup 404 后的同 key 交付仍要求首次请求已经处于受支持的账户、模型、操作和带 key 合同范围内,正文及有效路由相同;原子占用仍覆盖并发和重启。如果记录尚未建立,该 POST 可能成为第一次执行并预扣,并非只读查询。仅获准调查时不得发送 POST。原本不带 key、功能上线前或不支持的操作不能事后获得此保证;旧人像回执保持原有 schema。保留原路径、账户、正文、路由及 key。本次不改变既有 fallback 策略。
至少 30 天的保留期保护回执与 key 的对应关系,不是完成期限、结果链接有效期或旧 key 重用许可。网关可阻止发送前已过期的原执行者继续发送;已经发送且结果未知的请求,仍需原供应商权威证据或持久封锁证明。当前没有可为此情况提供确定性封锁的公开取消接口。
超过处理提醒阈值后,向现有客服渠道提供 submission ID、request ID、公开 task ID、模型及 UTC 时间,不提供 API key。人工应核对原尝试,要求原任务/结果和最终账本,或最终未受理、封锁及账务证据。调查期间不创建替代任务或新预留。管理员可认证访问 GET /api/admin/video-submissions/reviews?page=1,每页 50 条,按 has_more 继续翻页;仅列已启用核对的未决请求,不查询供应商、不写入数据。30 分钟是进入待处理列表的阈值,不是外部响应或最终结案承诺。
