APIMaster.ai

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 分钟是进入待处理列表的阈值,不是外部响应或最终结案承诺。