{"openapi":"3.1.0","info":{"title":"SD2 Commercial Merchant API","version":"2.0.0","summary":"下游商户完整视频生产 API","description":"一个 Key 只代表一个商户消费主体。平台不建立、识别或结算“商户的客户”层级；商户自己调用或其自建前端代用户调用，素材、任务、视频、额度预占、扣费、退款释放和流水全部归到该商户。多个 Key 属于同一商户时共享额度、任务和消费记录。API 覆盖素材上传、外链素材、音频转黑屏视频、人脸彩铅、人脸网格、异步视频生成、去水印、1080P/2K 超分、封面、编辑还原、取消、删除、播放下载、额度流水和终态 Webhook，可实现与 SD2 用户工作台等价的商户网站。"},"servers":[{"url":"https://sd2.kontony.asia","description":"生产环境"}],"externalDocs":{"description":"面向开发者与 Codex 的完整中文文档","url":"https://sd2.kontony.asia/merchant/docs"},"security":[{"SD2Key":[],"SD2Timestamp":[],"SD2Nonce":[],"SD2Signature":[]}],"tags":[{"name":"System","description":"鉴权、能力与健康检查"},{"name":"Quota","description":"额度、计费和流水"},{"name":"Media","description":"图片、视频、音频素材"},{"name":"Jobs","description":"完整异步生产链"}],"components":{"securitySchemes":{"SD2Key":{"type":"apiKey","in":"header","name":"X-SD2-Key","description":"商户 Key ID；鉴权后所有资源和消费统一归属该 Key 所在商户"},"SD2Timestamp":{"type":"apiKey","in":"header","name":"X-SD2-Timestamp","description":"Unix 秒，服务器允许 ±300 秒"},"SD2Nonce":{"type":"apiKey","in":"header","name":"X-SD2-Nonce","description":"8-120 字符；同一 Key 10 分钟内唯一"},"SD2Signature":{"type":"apiKey","in":"header","name":"X-SD2-Signature","description":"lowercase hex HMAC-SHA256(Secret, CanonicalRequest)"}},"parameters":{"JobId":{"name":"merchant_job_id","in":"path","required":true,"schema":{"type":"string"},"description":"商户任务 id，不是 jobId"},"MediaId":{"name":"media_id","in":"path","required":true,"schema":{"type":"string"}},"Limit100":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},"Before":{"name":"before","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"第一页传 0；下一页传响应 nextBefore"}},"schemas":{"Error":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string","description":"稳定错误码或具体问题"}}},"Media":{"type":"object","required":["id","name","mime"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"mime":{"type":"string"},"size":{"type":"integer"},"url":{"type":"string"},"created":{"type":"integer"},"expires":{"type":"integer"}}},"JobInput":{"type":"object","required":["prompt","duration","ratio","mediaIds","pencilFaces","gridFaces"],"properties":{"prompt":{"type":"string"},"duration":{"type":"integer"},"ratio":{"type":"string"},"mediaIds":{"type":"array","items":{"type":"string"}},"pencilFaces":{"type":"boolean"},"gridFaces":{"type":"boolean"}}},"PipelineNode":{"type":"object","properties":{"enabled":{"type":"boolean"},"target":{"type":"string"},"status":{"type":"string"},"message":{"type":"string"}}},"MerchantJob":{"type":"object","required":["id","requestId","jobId","status","stage","message","quotaReserved","resultUrl","resultExpires","input","pipeline","created","updated"],"properties":{"id":{"type":"string","description":"商户任务 id；查询、取消、删除均使用它"},"requestId":{"type":"string","description":"商户幂等订单号；可映射商户自己系统的订单，但平台不据此建立下级客户"},"jobId":{"type":"string","description":"SD2 内部生产任务 id，仅用于日志关联"},"status":{"type":"string","description":"终态仅 success/failed；其他值均为处理中","examples":["queued","claimed","uploading","generating","recovering","processing","success","failed"]},"stage":{"type":"string","enum":["generation","watermark","super_resolution","complete","failed"]},"message":{"type":"string"},"watermark":{"type":"boolean"},"superResolution":{"type":"string","enum":["","1080p","2k"]},"quotaReserved":{"type":"integer"},"quotaFinal":{"type":"integer"},"settled":{"type":"boolean"},"callbackSent":{"type":"boolean"},"resultUrl":{"type":"string","description":"success 时为最终处理结果；可能返回 307，请跟随重定向"},"resultExpires":{"type":"integer","description":"当前 resultUrl 的最后有效 Unix 秒；热资源通常为创建后 7200 秒，归档成功后延长至归档时间（259200 秒）"},"archiveUrl":{"type":"string","format":"uri","description":"Filebin 临时归档地址；归档成功后由平台自动使用，商户应优先使用 resultUrl"},"archiveExpires":{"type":"integer","description":"Filebin 归档地址的 Unix 过期时间；0 表示尚未归档"},"archiveStatus":{"type":"string","enum":["","uploading","uploaded","failed","expired"],"description":"归档后台状态；failed 时香港热资源保留并稍后重试"},"posterUrl":{"type":"string","description":"需要同样 HMAC 请求头访问"},"input":{"$ref":"#/components/schemas/JobInput"},"pipeline":{"type":"object","properties":{"generation":{"$ref":"#/components/schemas/PipelineNode"},"watermark":{"$ref":"#/components/schemas/PipelineNode"},"superResolution":{"$ref":"#/components/schemas/PipelineNode"}}},"canCancel":{"type":"boolean"},"canDelete":{"type":"boolean"},"created":{"type":"integer"},"updated":{"type":"integer"}}},"CreateJob":{"type":"object","required":["request_id","prompt"],"properties":{"request_id":{"type":"string","minLength":1,"maxLength":180,"description":"同一商户永久幂等；超时后重试必须复用原值"},"prompt":{"type":"string","minLength":1,"maxLength":50000},"duration":{"type":"integer","minimum":4,"maximum":15,"default":15},"ratio":{"type":"string","enum":["16:9","9:16","1:1","4:3","3:4","21:9"],"default":"16:9"},"mediaIds":{"type":"array","maxItems":12,"uniqueItems":true,"items":{"type":"string"},"description":"按前端素材顺序传入；@引用时在 prompt 中使用素材完整文件名和扩展名，如 @小视频.mp4、@图片.jpg"},"pencil_faces":{"type":"boolean","default":false,"description":"人脸参考图彩铅润色；与前端一致默认关闭"},"grid_faces":{"type":"boolean","default":false,"description":"本地人脸网格；与前端一致默认关闭，通常建议需要时单独开启"},"watermark":{"type":"boolean","default":true,"description":"生成成功后自动进入 HitPaw 去水印"},"super_resolution":{"type":"string","enum":["","1080p","2k"],"default":"","description":"有值时强制先去水印，再由 SoulLens 超分"},"callback_url":{"type":"string","format":"uri","description":"必须 HTTPS；覆盖商户后台默认回调"}}},"Quota":{"type":"object","properties":{"merchantId":{"type":"string"},"quota":{"type":"integer"},"reserved":{"type":"integer"},"available":{"type":"integer"},"consumed":{"type":"integer"},"costs":{"type":"object","properties":{"video":{"type":"integer"},"1080p":{"type":"integer"},"2k":{"type":"integer"}}}}},"DeleteResult":{"type":"object","required":["ok","id"],"properties":{"ok":{"type":"boolean"},"id":{"type":"string"}}}},"responses":{"BadRequest":{"description":"参数、素材、哈希或 URL 错误","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Key、签名、时间戳或状态错误","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PaymentRequired":{"description":"可用额度不足","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Nonce 重放、资源占用或状态冲突","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"TooMany":{"description":"每分钟速率或并发任务上限","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/merchant/v1/health":{"get":{"tags":["System"],"operationId":"getMerchantHealth","summary":"鉴权与能力检查","responses":{"200":{"description":"版本、功能、限制和网关状态"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/merchant/v1/quota":{"get":{"tags":["Quota"],"operationId":"getMerchantQuota","summary":"商户统一额度与计费","description":"商户自身调用和商户自建前端发起的全部任务共用这一份额度；平台不拆分下级客户。","responses":{"200":{"description":"总额度、预占、可用、已消耗和成本","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quota"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/merchant/v1/quota/ledger":{"get":{"tags":["Quota"],"operationId":"listMerchantQuotaLedger","summary":"额度流水","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"$ref":"#/components/parameters/Before"}],"responses":{"200":{"description":"grant/redeem_code/consume/refund_release/admin_set/admin_adjust 流水"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/merchant/v1/media":{"post":{"tags":["Media"],"operationId":"registerMerchantMediaUrls","summary":"登记外部 HTTPS 素材","description":"域名必须在平台允许列表。外部音频请先自行转换成带音轨的黑屏 MP4；要自动转换音频请使用 uploads。","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["media"],"properties":{"media":{"type":"array","maxItems":12,"items":{"type":"object","required":["url","name","mime"],"properties":{"url":{"type":"string","format":"uri"},"name":{"type":"string"},"mime":{"type":"string"}}}}}},"example":{"media":[{"url":"https://files.catbox.moe/example.jpg","name":"人物.jpg","mime":"image/jpeg"}]}}}},"responses":{"200":{"description":"素材 ID 列表"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/merchant/v1/uploads":{"post":{"tags":["Media"],"operationId":"uploadMerchantMedia","summary":"上传图片、视频或音频","description":"原始二进制请求体。音频自动转换为 1280x720 黑屏 MP4 并保留原音轨；返回的 name/mime 是转换后值。","parameters":[{"name":"X-File-Name","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-SD2-Content-SHA256","in":"header","required":true,"schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"image/*":{"schema":{"type":"string","format":"binary"}},"video/*":{"schema":{"type":"string","format":"binary"}},"audio/*":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"临时素材","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Media"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"413":{"description":"普通文件超过 200MB 或音频超过能力接口返回的 audioBytes"},"503":{"description":"音频转换队列繁忙"},"507":{"description":"临时存储保护"}}}},"/merchant/v1/media/{media_id}":{"parameters":[{"$ref":"#/components/parameters/MediaId"}],"get":{"tags":["Media"],"operationId":"getMerchantMedia","summary":"读取素材元数据","responses":{"200":{"description":"素材信息","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Media"}}}},"404":{"description":"素材不存在"}}},"delete":{"tags":["Media"],"operationId":"deleteMerchantMedia","summary":"删除未被任务引用的素材","responses":{"200":{"description":"已删除"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/merchant/v1/jobs":{"post":{"tags":["Jobs"],"operationId":"createMerchantJob","summary":"创建完整生产链","description":"同步返回任务快照，实际处理异步进行。任务永远归当前商户；request_id 幂等，网络超时后必须复用。创建时预占额度，完整链成功结算，任一节点失败释放。","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJob"},"example":{"request_id":"order_20260818_0001","prompt":"产品在自然光下缓慢旋转展示","duration":15,"ratio":"9:16","mediaIds":[],"pencil_faces":false,"grid_faces":false,"watermark":true,"super_resolution":"1080p"}}}},"responses":{"200":{"description":"创建或幂等返回原任务","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantJob"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"402":{"$ref":"#/components/responses/PaymentRequired"},"429":{"$ref":"#/components/responses/TooMany"}}},"get":{"tags":["Jobs"],"operationId":"listMerchantJobs","summary":"分页查询当前商户全部任务","description":"同一商户下所有 Key 看到同一任务池；平台不按商户自定义用户拆分。","parameters":[{"$ref":"#/components/parameters/Limit100"},{"$ref":"#/components/parameters/Before"}],"responses":{"200":{"description":"jobs、额度摘要和 nextBefore"}}}},"/merchant/v1/jobs/{merchant_job_id}":{"parameters":[{"$ref":"#/components/parameters/JobId"}],"get":{"tags":["Jobs"],"operationId":"getMerchantJob","summary":"查询任务与处理链","description":"建议前 60 秒每 2 秒轮询，此后每 5 秒；收到 Webhook 后仍应 GET 一次确认。","responses":{"200":{"description":"完整任务快照","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantJob"}}}},"404":{"description":"任务不存在"}}},"delete":{"tags":["Jobs"],"operationId":"deleteMerchantJob","summary":"删除终态任务及结果","description":"仅 settled=true 且 success/failed 的任务可删除。不会删除素材。","responses":{"200":{"description":"已删除","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"409":{"$ref":"#/components/responses/Conflict"}}}},"/merchant/v1/jobs/{merchant_job_id}/restore":{"get":{"tags":["Jobs"],"operationId":"restoreMerchantJobInput","summary":"还原编辑所需的全部设置和素材","parameters":[{"$ref":"#/components/parameters/JobId"}],"responses":{"200":{"description":"job、input、media；创建新任务时使用新的 request_id"},"409":{"description":"历史素材已过期或缺失"}}}},"/merchant/v1/jobs/{merchant_job_id}/poster":{"get":{"tags":["Jobs"],"operationId":"downloadMerchantPoster","summary":"获取视频首帧封面","parameters":[{"$ref":"#/components/parameters/JobId"}],"responses":{"200":{"description":"JPEG","content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"封面尚未生成"}}}},"/merchant/v1/jobs/{merchant_job_id}/cancel":{"post":{"tags":["Jobs"],"operationId":"cancelMerchantJob","summary":"取消尚未被本地软件领取的任务","parameters":[{"$ref":"#/components/parameters/JobId"}],"responses":{"200":{"description":"取消后任务快照，预占额度立即释放","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantJob"}}}},"409":{"description":"任务已经领取，继续轮询终态"}}}}},"webhooks":{"merchantJobTerminal":{"post":{"summary":"终态 Webhook","description":"平台 POST MerchantJob 的 UTF-8 紧凑 JSON 原始字节。X-SD2-Webhook-Signature = lowercase hex HMAC-SHA256(callbackSecret, rawBody)。返回任意 2xx 表示接收成功；平台未收到 2xx 时继续重试。","parameters":[{"name":"X-SD2-Webhook-Signature","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantJob"}}}},"responses":{"200":{"description":"已接收"}}}}}}