{"openapi":"3.0.0","paths":{"/v1/intl/id/text/checks":{"post":{"description":"提交一段文案做合规检测，**立即返回 id**，检测在后台异步进行。\n拿到 id 后轮询 `GET {id}`，直到 `status` 变成 `completed` 或 `failed`（通常 3–15 秒）。\n\n检测的是**当地语言的内容本身**；风险说明用哪种语言返回由 `explainLocale` 决定，两者互不影响。\n提交即扣积分；入队失败会自动全额退回。","operationId":"textCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlTextCheckDto"}}}},"responses":{"201":{"description":"已受理，返回检测 id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAcceptedResponseDto"}}}},"402":{"description":"积分不足"}},"security":[{"ApiKey":[]}],"summary":"提交文案检测","tags":["文案检测"]},"get":{"description":"按创建时间倒序分页返回，仅含概览字段（文案摘要截断到 100 字）。只返回本站点的记录。","operationId":"textList","parameters":[{"name":"page","required":false,"in":"query","description":"页码，从 1 开始。","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"每页条数，上限 50。","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"分页结果","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlTextCheckListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"文案检测历史","tags":["文案检测"]}},"/v1/intl/id/text/checks/{id}":{"get":{"description":"`status` 为 `processing` 时表示还在检测中，稍后重试；`completed` 时 `risks` 才是最终结果。\n\n风险分两层，**互不混淆**：\n- `risks` — 合规风险。`kind=violation` 是硬性违规，`kind=scene-hint` 是场景限制类提示。\n- `customRisks` — 你自己配的违禁词命中，**不计入** `riskLevel`，配了替换词会给 `replacement`。","operationId":"textGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"检测详情","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlTextCheckResponseDto"}}}},"404":{"description":"记录不存在、不属于你的账户，或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"取文案检测结果","tags":["文案检测"]},"delete":{"description":"不可恢复。","operationId":"textRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"已删除","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"记录不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"删除文案检测记录","tags":["文案检测"]}},"/v1/intl/id/text/checks/{id}/fix":{"post":{"description":"对已完成的检测触发 AI 改写，**立即返回**，改写在后台进行。\n轮询 `GET {id}`，改写完成后结果在 `fixedText`（`fixStatus` 变成 `completed`）。\n会额外扣除改写积分，失败自动退回。","operationId":"textFix","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"201":{"description":"已受理，改写在后台进行","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlTextFixAcceptedDto"}}}},"400":{"description":"该记录无需改写（无违规项），或已有一次改写在执行中"},"402":{"description":"积分不足"},"404":{"description":"记录不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"触发 AI 改写","tags":["文案检测"]}},"/v1/intl/id/image/checks":{"post":{"description":"提交一个公网可访问的图片地址做合规检测。\n\n图片检测是**同步完成**的：这个接口返回时结果已经就绪，响应体就是完整的检测结果，\n不需要再轮询。（`GET {id}` 保留供事后回查。）\n\n**务必检查 `status`**：正常是 `completed`；引擎异常时是 `failed`（此时积分已自动退回，\n`labels` 为空），这种情况仍然返回 201 而不是 5xx —— 记录本身创建成功了。\n\n**计费**：2 积分/张。","operationId":"imageCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlImageCheckDto"}}}},"responses":{"201":{"description":"检测完成，直接返回完整结果","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlImageCheckResponseDto"}}}},"400":{"description":"参数不合法"},"402":{"description":"积分不足"}},"security":[{"ApiKey":[]}],"summary":"提交图片检测","tags":["图片检测"]},"get":{"description":"按创建时间倒序分页返回，仅含概览字段。","operationId":"imageList","parameters":[{"name":"page","required":false,"in":"query","description":"页码，从 1 开始。","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"每页条数，上限 50。","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"分页结果","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlImageCheckListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"图片检测历史","tags":["图片检测"]}},"/v1/intl/id/image/checks/{id}":{"get":{"description":"回查已提交的图片检测。","operationId":"imageGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"检测详情","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlImageCheckResponseDto"}}}},"404":{"description":"记录不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"取图片检测结果","tags":["图片检测"]},"delete":{"description":"软删除，并异步清理已上传的图片文件。","operationId":"imageRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"已删除","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"记录不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"删除图片检测记录","tags":["图片检测"]}},"/v1/intl/id/video/checks":{"post":{"description":"提交一个公网可访问的视频地址做合规检测，**立即返回 id**，检测在后台异步进行。\n轮询 `GET {id}`，检测耗时约为**视频时长的一半**（最少 30 秒），建议每 5–10 秒轮询一次。\n\n检测覆盖三个维度：画面（`frames`）、语音（`audios`）、口播文案（`transcriptRisks`，\n转写后走与文案检测同一套引擎）。\n\n**计费**：按视频时长 1 积分/秒，提交即扣。请如实申报 `videoDuration`。","operationId":"videoCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlVideoCheckDto"}}}},"responses":{"201":{"description":"已受理，返回检测 id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAcceptedResponseDto"}}}},"402":{"description":"积分不足"}},"security":[{"ApiKey":[]}],"summary":"提交视频检测","tags":["视频检测"]},"get":{"description":"按创建时间倒序分页返回，仅含概览字段。","operationId":"videoList","parameters":[{"name":"page","required":false,"in":"query","description":"页码，从 1 开始。","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"每页条数，上限 50。","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"按状态过滤。","schema":{"enum":["processing","completed","failed"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"分页结果","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlVideoCheckListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"视频检测历史","tags":["视频检测"]}},"/v1/intl/id/video/checks/{id}":{"get":{"description":"每次调用会顺带向检测引擎推进一次轮询，所以**直接轮询这个接口即可**，不需要额外的状态接口。\n\n⚠️ **轮询的终止条件是两个**：`status` 出终态（completed / failed），\n**并且** `transcriptStatus` 不再是 `processing`。口播转写通常晚于画面审核完成，\n只看 `status` 会在口播还在转的时候就收工，永远拿不到 `transcriptRisks`。\n\n`explainLocale` 决定口播风险用哪种语言解释。它放在读侧而不是提交侧 ——\n结果是异步出的，提交那一刻的语言选择到不了落库的时候。","operationId":"videoGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"explainLocale","required":false,"in":"query","description":"风险说明用哪种语言返回。不传按 zh-CN。","schema":{"default":"zh-CN","enum":["zh-CN","id-ID"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"检测详情","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlVideoCheckResponseDto"}}}},"404":{"description":"记录不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"取视频检测结果","tags":["视频检测"]},"delete":{"description":"软删除，并异步清理已上传的视频文件。","operationId":"videoRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"已删除","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"记录不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"删除视频检测记录","tags":["视频检测"]}},"/v1/intl/id/batches":{"post":{"description":"一次提交多条文案 + 多张图片 + 多个视频，统一跑检测并聚合结论。\n文案 ≤10 条、图片 ≤20 张、视频 ≤10 个，单包总计 ≤40 项。\n\n**立即返回 id**，各子项在后台并行检测。轮询 `GET {id}` 看进度：\n`progress.done / progress.total` 是完成度，全部完成后 `result` 给出整包结论（PASS / REJECT）。\n每个子项都带 `checkId`，可以拿去调对应的单项接口取完整明细。\n\n**计费**：按各子项单价分别计费（文案按条、图片按张、视频按秒）。余额不足会在提交时整单拒绝。","operationId":"batchCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlBatchDto"}}}},"responses":{"201":{"description":"已受理，返回素材包 id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAcceptedResponseDto"}}}},"400":{"description":"素材包为空，或超出单次项数上限"},"402":{"description":"积分不足以覆盖整包成本"},"403":{"description":"素材包批量需要旗舰版及以上订阅"}},"security":[{"ApiKey":[]}],"summary":"提交素材包批量检测","tags":["素材包批量检测"]},"get":{"description":"按创建时间倒序分页返回，含各包的进度与结论。会顺带推进少量进行中包的状态。","operationId":"batchList","parameters":[{"name":"page","required":false,"in":"query","description":"页码，从 1 开始。","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"每页条数，上限 50。","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"explainLocale","required":false,"in":"query","description":"风险说明用哪种语言返回（列表会顺带推进子项状态，可能在此刻落库）。","schema":{"default":"zh-CN","enum":["zh-CN","id-ID"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"分页结果","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlBatchListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"素材包列表","tags":["素材包批量检测"]}},"/v1/intl/id/batches/{id}":{"get":{"description":"每次调用会顺带推进一次子项状态刷新，直接轮询这个接口即可。`items[].checkId` 可用于取单项完整明细。","operationId":"batchGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"explainLocale","required":false,"in":"query","description":"风险说明用哪种语言返回。不传按 zh-CN。","schema":{"default":"zh-CN","enum":["zh-CN","id-ID"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"素材包详情","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlBatchResponseDto"}}}},"404":{"description":"素材包不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"取素材包进度与结果","tags":["素材包批量检测"]},"delete":{"description":"软删除素材包及其全部子项检测记录，并异步清理已上传的图片 / 视频文件。","operationId":"batchRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"已删除","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"素材包不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"删除素材包","tags":["素材包批量检测"]}},"/v1/intl/id/custom-rules":{"get":{"description":"按创建时间倒序，不分页。**只返回本站点的词** —— 同一个词在不同站点各存一条，互不命中。","operationId":"customRuleList","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"规则列表","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"列出本站点的全部自定义违禁词","tags":["自定义违禁词"]},"post":{"operationId":"customRuleCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlCustomRuleDto"}}}},"responses":{"201":{"description":"创建成功","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleResponseDto"}}}},"400":{"description":"该词在本站点已存在，或已达套餐词库上限"},"403":{"description":"自定义违禁词是付费功能，当前订阅不可用"}},"security":[{"ApiKey":[]}],"summary":"新增一条自定义违禁词","tags":["自定义违禁词"]}},"/v1/intl/id/custom-rules/quota":{"get":{"description":"返回已用条数与套餐上限。⚠️ **`used` 是账户级的**（含你在其他站点登记的词），`isPaid` 则是本站点的订阅状态 —— 会员按站点隔离，词库额度不隔离。","operationId":"customRuleQuota","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"配额信息","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleQuotaDto"}}}}},"security":[{"ApiKey":[]}],"summary":"查词库配额","tags":["自定义违禁词"]}},"/v1/intl/id/custom-rules/settings":{"get":{"description":"关闭时所有自定义词都不参与检测（数据保留）。**开关是账户级的，不分站点。**","operationId":"customRuleGetSettings","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"开关状态","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleSettingsDto"}}}}},"security":[{"ApiKey":[]}],"summary":"查总开关状态","tags":["自定义违禁词"]},"patch":{"description":"与每条规则自身的 `enabled` 正交：总开关关掉时，逐条的 enabled 不生效。","operationId":"customRuleSetSettings","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlToggleSettingsDto"}}}},"responses":{"200":{"description":"更新后的开关状态","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleSettingsDto"}}}},"403":{"description":"自定义违禁词是付费功能，当前订阅不可用"}},"security":[{"ApiKey":[]}],"summary":"切换总开关","tags":["自定义违禁词"]}},"/v1/intl/id/custom-rules/bulk-import":{"post":{"description":"单次最多 2000 条。**幂等友好**：批内重复与库中已存在的词会被跳过而不是报错，\n响应里分别给出 `imported` / `skippedDuplicate` / `rejectedQuota` 三个计数。\n超出配额的部分会被拒收，已接受的部分照常写入。","operationId":"customRuleBulkImport","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlBulkImportDto"}}}},"responses":{"201":{"description":"导入结果统计","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleImportResultDto"}}}},"403":{"description":"自定义违禁词是付费功能，当前订阅不可用"}},"security":[{"ApiKey":[]}],"summary":"批量导入违禁词","tags":["自定义违禁词"]}},"/v1/intl/id/custom-rules/{id}":{"patch":{"description":"只更新传了的字段。","operationId":"customRuleUpdate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateIntlCustomRuleDto"}}}},"responses":{"200":{"description":"更新后的规则","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleResponseDto"}}}},"404":{"description":"规则不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"修改自定义违禁词","tags":["自定义违禁词"]},"delete":{"description":"物理删除，不可恢复。","operationId":"customRuleRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"已删除","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"规则不存在或属于别的站点"}},"security":[{"ApiKey":[]}],"summary":"删除自定义违禁词","tags":["自定义违禁词"]}},"/v1/intl/id/account":{"get":{"description":"返回**本站点**的积分余额、订阅方案和本月各类检测的调用次数。\n\n⚠️ 积分与订阅**按站点隔离**：这里的余额不含你在其他站点的积分，反之亦然。\n接入前建议先调一次确认额度 —— 否则只能靠 402 撞墙才知道余额不够。\n\n用量统计含所有入口（网页、接口），不只是接口调用。","operationId":"accountGetAccount","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"账户信息","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAccountResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"查账户余额与用量","tags":["账户"]}},"/v1/intl/id/uploads/policy":{"post":{"description":"**只有在你没有公网可访问的素材存储时才需要这个接口。**\n如果素材已经在你自己的对象存储或 CDN 上，直接把 URL 填进检测接口即可，跳过这一步。\n\n返回一份 POST Policy 直传凭证，用标准表单直传：\n\n```bash\ncurl -X POST \"$host\" \\\n  -F \"key=$dir<你的文件名>\" \\\n  -F \"policy=$policy\" \\\n  -F \"OSSAccessKeyId=$accessKeyId\" \\\n  -F \"signature=$signature\" \\\n  -F \"file=@./promo-01.mp4\"\n```\n\n上传成功后素材地址为 `{cdnHost}/{key}`，把它填进检测接口的 `videoUrl` / `imageUrl`。\n**凭证 5 分钟过期**，且只允许写入你账户在本站点的专属目录前缀。","operationId":"uploadCreatePolicy","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"你自己系统里的终端租户号。带上它，该租户的自定义违禁词与检测历史会被隔离在独立的域中；积分与订阅仍算在 API Key 所属账户头上。首次出现自动创建，取值限 1–64 位的字母、数字、_ . : -。","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlUploadPolicyDto"}}}},"responses":{"201":{"description":"直传凭证","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlUploadPolicyResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"获取素材直传凭证","tags":["素材上传"]}}},"info":{"title":"ByeRisk 开放 API · 印尼站","description":"ByeRisk 内容合规检测 API（印尼站）—— 把本地平台的文案、视频、图片合规检测能力，\n以及自定义违禁词库，开放给你的系统和 AI agent 调用。与网页版共用同一套检测引擎和积分账户。\n\n## 快速开始\n\n1. 在 [控制台 → 开放 API](https://www.byerisk.com/id/open-api) 创建一把 Key（形如 `brsk_live_…`，**只显示一次**）\n2. 每个请求带上 `Authorization: Bearer brsk_live_…`\n3. 提交检测拿到 `id`，轮询结果直到 `status` 变成 `completed`\n\n```bash\n# 1) 提交文案检测\ncurl -X POST https://www.byerisk.com/api/v1/intl/id/text/checks \\\n  -H \"Authorization: Bearer $BYERISK_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"text\": \"Serum ini 100% ampuh memutihkan wajah dalam 3 hari, garansi uang kembali!\",\n    \"platform\": \"tiktok_id\",\n    \"vertical\": \"beauty\"\n  }'\n# → { \"success\": true, \"data\": { \"id\": \"cm5abc…\", \"status\": \"processing\" } }\n\n# 2) 轮询结果\ncurl https://www.byerisk.com/api/v1/intl/id/text/checks/cm5abc… \\\n  -H \"Authorization: Bearer $BYERISK_API_KEY\"\n```\n\n## 一把 Key 只属于一个站点\n\n这是接入前最需要知道的一条：**API Key 与站点绑定**。印尼站控制台签发的 Key 只能调\n`/v1/intl/id/*`；拿它去调中文站的 `/v1/*` 会返回 401，反之亦然。\n\n不这么设计的话，同一个请求既可能按中文规则集检测印尼语文案（结果几乎恒为「通过」），\n也可能从另一个站点的账户扣钱 —— 两种都不会报错，只会静默给出错的答案。\n\n同理，积分、订阅、检测历史、自定义词库**全部按站点隔离**。你在中文站的余额不能用在这里。\n\n## 响应格式\n\n所有接口统一包封：成功 `{ \"success\": true, \"data\": … }`，失败 `{ \"success\": false, \"error\": \"…\" }`。\n下文各接口列出的 schema 指的是 `data` 的内容。\n\n## 如果你自己也是多租户系统\n\n如果你把 ByeRisk 转卖 / 集成给你自己的多个客户用，加一个 `X-End-Tenant` 头，\n把你系统里的租户号带上，我们会为它单独开一个隔离域：\n\n```bash\ncurl -X POST https://www.byerisk.com/api/v1/intl/id/text/checks \\\n  -H \"Authorization: Bearer $BYERISK_API_KEY\" \\\n  -H \"X-End-Tenant: toko-4271\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"text\": \"…\", \"platform\": \"tiktok_id\", \"vertical\": \"general\" }'\n```\n\n- **隔离的是数据**：自定义违禁词库、检测历史、素材上传目录，各租户各一份，互不可见。\n- **不隔离的是账户**：积分、订阅档位都算在你（Key 所属账户）头上，不需要给每个终端租户充值。\n- 第一次出现的租户号会自动建好，**不需要预先注册**。取值限 1–64 位的字母、数字、`_`、`.`、`:`、`-`。\n- **请传稳定的租户标识**，不要传每次请求都变的值（如请求 id）—— 那会瞬间耗尽单把 Key 的隔离域上限。\n\n限流按 **API Key** 计（不按终端租户），需要更高并发就多签几把 Key。\n\n## 检测什么、不检测什么\n\n| 维度 | 覆盖 | 说明 |\n|---|---|---|\n| 文案 | 平台规则库 + 语义复核 | 当地法规与平台规则；语义复核负责跨句风险与误报过滤 |\n| 图片 | 画面风险 + 图上文字识别 | 画面判定与内容语言无关 |\n| 视频 | 画面 + 语音 + 口播文案 | 口播转写后走与文案检测**同一套引擎** |\n\n**图片检测不做商业合规判定**：它判的是画面本身的风险，不核验功效宣称、认证标识这类\n需要读懂图上文案的商业合规问题。这类风险请把文案单独提交文案检测。\n\n## 风险结论：两套取值，不要混用\n\n这是最容易接错的一处 —— **文案与图片 / 视频的 `riskLevel` 不是同一套枚举**：\n\n| 接口 | `riskLevel` 取值 | 含义 |\n|---|---|---|\n| 文案检测 | `safe` / `low` / `medium` / `high` | 按命中的违规项里最高的 `severity` 得出 |\n| 图片、视频检测 | `PASS` / `REVIEW` / `REJECT` | 内容审核给出的处置建议 |\n\n两者来自两种不同的判定链路，没有换算关系。请按接口分别处理，不要写一个统一的 `riskLevel` 枚举。\n\n文案的每条风险还带两个维度：\n\n- `kind` —— `violation` 硬性违规（必须改）；`scene-hint` 场景限制类提示\n- `severity` —— `high` / `medium` / `low`，顶层 `riskLevel` 取所有 violation 里最高的一档\n\n自定义违禁词的命中**单独放在 `customRisks` 里**，不计入 `riskLevel` —— 它是你自己的偏好，\n不是合规判定。配了替换词的会带 `replacement`，可直接做精确替换。\n\n## 内容语言与解释语言是两回事\n\n检测的永远是**当地语言的内容**；风险说明、修改建议用哪种语言返回，由 `explainLocale` 决定\n（`zh-CN` 或 `id-ID`，不传按 `zh-CN`）。两者正交 —— 中文团队可以看中文解释，\n但被检测的文案仍然是印尼语。\n\n条款出处（`legalRef`）**不随它翻译**：条款编号与出处必须可核对。\n\n## 异步与轮询\n\n文案、视频、素材包检测都是**异步**的：提交返回 `id`，轮询 `GET` 取结果。\n图片检测是同步的，提交时直接返回完整结果。\n\n轮询建议间隔：文案 2 秒、视频 5–10 秒。视频检测耗时约为视频时长的一半（最少 30 秒）。\nGET 接口本身会顺带推进检测状态，所以不需要额外的状态查询接口。\n\n⚠️ **视频的轮询终止条件是两个**：`status` 出终态，**并且** `transcriptStatus` 不再是\n`processing`。口播转写通常晚于画面审核完成，只看 `status` 会让你永远拿不到口播风险。\n\n## 计费\n\n与网页版共用同一个站点积分账户，价格一致：\n\n| 动作 | 消耗 |\n|---|---|\n| 文案检测 | 按套餐单价，每次 |\n| AI 改写 | 按套餐单价，每次 |\n| 视频检测 | 1 积分 / 秒 |\n| 图片检测 | 2 积分 / 张 |\n| 自定义违禁词管理 | 免费 |\n\n余额不足返回 `402`。接入前可以先调 `GET /v1/intl/{country}/account` 查余额。\n\n## 限流\n\n按 API Key 计算，**每档独立计数**：提交类（POST 检测 / 批量）60 次/分钟，\n查询类（GET）600 次/分钟，配置类（自定义违禁词管理、上传凭证）120 次/分钟。\n超限返回 `429` 并带 `Retry-After` 头，每个响应都有 `X-RateLimit-Remaining`。\n\n## 错误码\n\n| 码 | 含义 |\n|---|---|\n| 400 | 参数不合法 |\n| 401 | API Key 无效、已吊销、已过期，**或不属于你正在调用的站点** |\n| 402 | 积分不足 |\n| 403 | 功能需要更高订阅档（API 接入与素材包批量均需旗舰版起；已签发的 Key 不受门槛调整影响） |\n| 404 | 记录不存在、不属于你的账户，或站点不存在 |\n| 429 | 触发限流 |\n| 500 | 服务端错误，可重试 |","version":"1.0.0","contact":{}},"tags":[],"servers":[{"url":"https://www.byerisk.com/api","description":"生产环境"}],"components":{"securitySchemes":{"ApiKey":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"在对应站点的控制台创建的 API Key，形如 brsk_live_…"}},"schemas":{"CreateIntlTextCheckDto":{"type":"object","properties":{"text":{"type":"string","description":"待检测的文案，10–5000 字符。检测的是印尼语内容本身，与下面的解释语言无关。","minLength":10,"maxLength":5000,"example":"Serum ini 100% ampuh memutihkan wajah dalam 3 hari, sudah bersertifikat BPOM, garansi uang kembali!"},"platform":{"type":"string","description":"内容要发布的平台，决定命中哪套平台规则集。","enum":["tiktok_id","shopee_id","tokopedia"],"example":"tiktok_id"},"vertical":{"type":"string","description":"内容行业。声明具体行业 = 通用规则集 + 该行业专属规则集；general = 只跑通用集。","enum":["general","beauty","health","food","fashion"],"example":"beauty"},"explainLocale":{"type":"string","description":"风险说明与修改建议用哪种语言返回。与被检测内容的语种正交 —— 检测的永远是印尼语文案，这个参数只决定我们把结论讲给你听时用什么语言。不传按 zh-CN。","enum":["zh-CN","id-ID"],"default":"zh-CN"}},"required":["text","platform","vertical"]},"IntlAcceptedResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"本次检测的 id，用于轮询结果。","example":"cms8xhc5x0006sp59vrks7zkf"},"object":{"type":"string","description":"对象类型。","example":"intl_text_check"},"status":{"type":"string","description":"当前状态。刚提交时为 processing。","example":"processing"}},"required":["id","object","status"]},"IntlTextCheckListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"检测 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_text_check"},"status":{"type":"string","description":"状态。"},"platform":{"type":"string","description":"发布平台。"},"vertical":{"type":"object","description":"内容行业。","nullable":true},"preview":{"type":"string","description":"文案摘要（截断到 100 字）。全文请调详情。"},"riskLevel":{"type":"string","description":"顶层结论。","enum":["safe","low","medium","high"],"nullable":true},"riskCount":{"type":"number","description":"风险条数。"},"fixStatus":{"type":"object","description":"AI 改写状态。","nullable":true},"createdAt":{"type":"object","description":"创建时间。"}},"required":["id","object","status","platform","vertical","preview","riskLevel","riskCount","fixStatus","createdAt"]},"IntlTextCheckListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型，恒为 list。","example":"list"},"page":{"type":"number","description":"当前页码。","example":1},"pageSize":{"type":"number","description":"每页条数。","example":20},"total":{"type":"number","description":"符合条件的总条数。","example":128},"hasMore":{"type":"boolean","description":"是否还有下一页。","example":true},"data":{"description":"本页数据。","type":"array","items":{"$ref":"#/components/schemas/IntlTextCheckListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"IntlSummaryDto":{"type":"object","properties":{"violation":{"type":"number","description":"法规 / 平台硬性违规的条数。","example":3},"sceneHint":{"type":"number","description":"场景限制类提示的条数。","example":1},"custom":{"type":"number","description":"自定义词库命中条数。**不计入** riskLevel。","example":0},"semantic":{"type":"number","description":"语义风险标签数（定位不到具体位置的整体提示）。","example":2}},"required":["violation","sceneHint"]},"IntlTextRiskDto":{"type":"object","properties":{"id":{"type":"object","description":"风险 id。","nullable":true},"kind":{"type":"string","description":"风险归属：`violation` 法规 / 平台硬性违规（必须改）；`scene-hint` 场景限制类提示。","enum":["violation","scene-hint"]},"severity":{"type":"string","description":"严重度。顶层 `riskLevel` 取所有 violation 里最高的一档。","enum":["high","medium","low"]},"matchedText":{"type":"string","description":"命中的原文片段。","example":"garansi uang kembali"},"startIndex":{"type":"number","description":"命中片段在原文中的起始下标。**语义类命中定位不到位置时为 `-1`**（不是 null）—— 此时请用 `matchedText` 自己在原文里检索，或只把它当整体提示展示。","example":42},"endIndex":{"type":"number","description":"命中片段的结束下标；同样可能是 `-1`。","example":62},"category":{"type":"object","description":"风险类别，已按 explainLocale 本地化。","nullable":true},"suggestion":{"type":"object","description":"修改建议，已按 explainLocale 本地化。","nullable":true},"legalRef":{"type":"object","description":"法规 / 平台条款出处。**不随 explainLocale 翻译** —— 条款编号与出处必须可核对。","nullable":true,"example":"UU No. 8 Tahun 1999 Pasal 9"},"source":{"type":"string","description":"判定来源：`rule` 确定性规则命中；`model` 模型判定；`custom` 自定义词。","enum":["rule","model","custom"]}},"required":["id","kind","severity","matchedText","startIndex","endIndex","category","suggestion","legalRef","source"]},"IntlCustomRiskDto":{"type":"object","properties":{"matchedText":{"type":"string","description":"命中的原文片段。"},"startIndex":{"type":"number","description":"起始下标（可能为 -1）。"},"endIndex":{"type":"number","description":"结束下标（可能为 -1）。"},"replacement":{"type":"object","description":"你给这条词配的替换目标。为空表示只提醒、没有替换建议。","nullable":true},"note":{"type":"object","description":"你给这条词写的备注。","nullable":true}},"required":["matchedText","startIndex","endIndex","replacement","note"]},"IntlTextCheckResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"检测 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_text_check"},"status":{"type":"string","description":"`processing` 表示还在检测中，稍后重试；`completed` 时 risks 才是最终结果。","enum":["processing","completed","failed"]},"platform":{"type":"string","description":"发布平台。","enum":["tiktok_id","shopee_id","tokopedia"]},"vertical":{"type":"string","description":"内容行业。","enum":["general","beauty","health","food","fashion"]},"text":{"type":"string","description":"被检测的原文。"},"riskLevel":{"type":"string","description":"顶层结论，按 violation 类风险里最高的 severity 得出。⚠️ 与图片 / 视频的 `PASS` / `REVIEW` / `REJECT` **不是同一套取值**。","enum":["safe","low","medium","high"],"nullable":true},"summary":{"description":"各类计数。","allOf":[{"$ref":"#/components/schemas/IntlSummaryDto"}]},"risks":{"description":"合规风险逐条。","type":"array","items":{"$ref":"#/components/schemas/IntlTextRiskDto"}},"customRisks":{"description":"自定义词库命中。**独立于 risks，不计入 riskLevel** —— 它是你自己的偏好，不是合规判定。","type":"array","items":{"$ref":"#/components/schemas/IntlCustomRiskDto"}},"semanticLabels":{"description":"模型判定有风险、但定位不到具体片段的整体提示。","type":"array","items":{"type":"string"}},"fixStatus":{"type":"object","description":"AI 改写状态：null 未触发 | processing 改写中 | completed 已完成 | failed 失败。","nullable":true},"fixedText":{"type":"object","description":"AI 改写后的全文，改写完成后才有值。","nullable":true},"createdAt":{"type":"object","description":"创建时间（ISO 8601）。"},"updatedAt":{"type":"object","description":"最后更新时间（ISO 8601）。"}},"required":["id","object","status","platform","vertical","text","riskLevel","summary","risks","customRisks","semanticLabels","fixStatus","fixedText","createdAt","updatedAt"]},"IntlTextFixAcceptedDto":{"type":"object","properties":{"id":{"type":"string","description":"检测 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_text_check"},"fixStatus":{"type":"string","description":"改写状态，受理后为 processing。","example":"processing"},"creditCost":{"type":"number","description":"本次改写消耗的积分。","example":2}},"required":["id","object","fixStatus"]},"IntlDeletedResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"被删除记录的 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_text_check"},"deleted":{"type":"boolean","description":"恒为 true。","example":true}},"required":["id","object","deleted"]},"CreateIntlImageCheckDto":{"type":"object","properties":{"imageUrl":{"type":"string","description":"图片地址，必须公网可访问（我们的检测服务要能直接拉取）。没有自己的对象存储时，先调 `POST /v1/intl/{country}/uploads/policy` 拿直传凭证。","example":"https://cdn.example.com/products/serum-01.jpg"},"imageTitle":{"type":"string","description":"图片标题 / 文件名，用于在历史里认出这张图。","example":"serum-01.jpg"},"imageSize":{"type":"number","description":"图片体积（字节）。","example":254112,"minimum":1},"imageWidth":{"type":"number","description":"图片宽度（像素）。","example":1080},"imageHeight":{"type":"number","description":"图片高度（像素）。","example":1080},"vertical":{"type":"string","description":"内容行业声明。**不影响本次画面判定**（画面策略绑在账号侧配置上，与行业无关），只用于记录与历史回显。如实填写即可，不填留空。","enum":["general","beauty","health","food","fashion"]},"explainLocale":{"type":"string","description":"风险标签用哪种语言返回。同文案检测，与图中文字的语种无关。","enum":["zh-CN","id-ID"],"default":"zh-CN"}},"required":["imageUrl","imageTitle","imageSize"]},"IntlImageFileDto":{"type":"object","properties":{"url":{"type":"string","description":"图片地址（你提交的那个）。"},"title":{"type":"string","description":"图片标题 / 文件名。"},"sizeBytes":{"type":"object","description":"体积（字节）。","nullable":true},"width":{"type":"object","description":"宽度（像素）。","nullable":true},"height":{"type":"object","description":"高度（像素）。","nullable":true}},"required":["url","title","sizeBytes","width","height"]},"IntlImageLabelDto":{"type":"object","properties":{"description":{"type":"string","description":"风险标签，已按 explainLocale 本地化。","example":"色情低俗"},"riskLevel":{"type":"string","description":"这条标签自身的档位。早期记录没有逐条档位，此时为 null（不会编一个出来）。","enum":["PASS","REVIEW","REJECT"],"nullable":true}},"required":["description","riskLevel"]},"IntlImageCheckResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"检测 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_image_check"},"status":{"type":"string","description":"**务必检查**：引擎异常时为 `failed`（积分已自动退回，labels 为空），此时仍返回 201。","enum":["processing","completed","failed"]},"image":{"description":"图片信息。","allOf":[{"$ref":"#/components/schemas/IntlImageFileDto"}]},"vertical":{"type":"string","description":"提交时声明的行业。仅记录，**不影响画面判定**。","enum":["general","beauty","health","food","fashion"],"nullable":true},"riskLevel":{"type":"string","description":"顶层结论。⚠️ 与文案检测的 safe/low/medium/high **不是同一套取值**。","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"命中的风险标签。无风险时为空数组。","type":"array","items":{"$ref":"#/components/schemas/IntlImageLabelDto"}},"createdAt":{"type":"object","description":"创建时间。"},"updatedAt":{"type":"object","description":"最后更新时间。"}},"required":["id","object","status","image","vertical","riskLevel","labels","createdAt","updatedAt"]},"IntlImageCheckListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"检测 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_image_check"},"status":{"type":"string","description":"状态。"},"image":{"type":"object","description":"图片地址与标题。"},"vertical":{"type":"object","description":"行业声明。","nullable":true},"riskLevel":{"type":"string","description":"顶层结论。","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"风险标签文字（列表不含逐条档位）。","type":"array","items":{"type":"string"}},"createdAt":{"type":"object","description":"创建时间。"}},"required":["id","object","status","image","vertical","riskLevel","labels","createdAt"]},"IntlImageCheckListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型，恒为 list。","example":"list"},"page":{"type":"number","description":"当前页码。","example":1},"pageSize":{"type":"number","description":"每页条数。","example":20},"total":{"type":"number","description":"符合条件的总条数。","example":128},"hasMore":{"type":"boolean","description":"是否还有下一页。","example":true},"data":{"description":"本页数据。","type":"array","items":{"$ref":"#/components/schemas/IntlImageCheckListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"CreateIntlVideoCheckDto":{"type":"object","properties":{"videoUrl":{"type":"string","description":"视频地址，必须公网可访问。没有自己的对象存储时先调直传凭证接口。","example":"https://cdn.example.com/videos/promo-01.mp4"},"videoTitle":{"type":"string","description":"视频标题 / 文件名。","example":"promo-01.mp4"},"videoSize":{"type":"number","description":"视频体积，单位 **MB**（不是字节）。上限 1024（1GB）。","example":12.4,"minimum":0.01,"maximum":1024},"videoDuration":{"type":"number","description":"视频时长（秒）。**计费按它算**（1 积分/秒），请如实申报。","example":45,"minimum":1},"videoWidth":{"type":"number","description":"视频宽度（像素）。","example":1080},"videoHeight":{"type":"number","description":"视频高度（像素）。","example":1920},"platform":{"type":"string","description":"发布平台。只决定**口播文案**用哪套平台规则集；不传按本站默认平台。","enum":["tiktok_id","shopee_id","tokopedia"]},"vertical":{"type":"string","description":"内容行业。只决定**口播文案**用哪些行业规则集：声明具体行业 = 通用集 + 该行业集；不声明或 general = 放宽到全部行业集（宁可多报）。画面与语音判定与它无关。","enum":["general","beauty","health","food","fashion"]}},"required":["videoUrl","videoTitle","videoSize","videoDuration"]},"IntlVideoCheckListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"检测 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_video_check"},"status":{"type":"string","description":"视频审核状态。"},"video":{"type":"object","description":"视频地址、标题与时长。"},"vertical":{"type":"object","description":"行业声明。","nullable":true},"riskLevel":{"type":"string","description":"顶层结论。","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"风险标签。","type":"array","items":{"type":"string"}},"transcriptStatus":{"type":"object","description":"口播转写状态。","nullable":true},"createdAt":{"type":"object","description":"创建时间。"}},"required":["id","object","status","video","vertical","riskLevel","labels","transcriptStatus","createdAt"]},"IntlVideoCheckListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型，恒为 list。","example":"list"},"page":{"type":"number","description":"当前页码。","example":1},"pageSize":{"type":"number","description":"每页条数。","example":20},"total":{"type":"number","description":"符合条件的总条数。","example":128},"hasMore":{"type":"boolean","description":"是否还有下一页。","example":true},"data":{"description":"本页数据。","type":"array","items":{"$ref":"#/components/schemas/IntlVideoCheckListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"IntlVideoFileDto":{"type":"object","properties":{"url":{"type":"string","description":"视频地址。"},"title":{"type":"string","description":"视频标题 / 文件名。"},"sizeMb":{"type":"object","description":"体积（MB）。","nullable":true},"durationSeconds":{"type":"object","description":"时长（秒）。","nullable":true},"width":{"type":"object","description":"宽度（像素）。","nullable":true},"height":{"type":"object","description":"高度（像素）。","nullable":true}},"required":["url","title","sizeMb","durationSeconds","width","height"]},"IntlVideoFrameDto":{"type":"object","properties":{"timeSeconds":{"type":"number","description":"命中画面在视频中的时间点（秒）。","example":12},"riskLevel":{"type":"string","description":"该画面的档位。","enum":["PASS","REVIEW","REJECT"],"nullable":true},"description":{"type":"string","description":"命中说明。"},"imageUrl":{"type":"object","description":"命中画面的截图地址。**短时签名 URL，会过期** —— 需要长期留存请自行转存。","nullable":true},"ocrText":{"type":"object","description":"画面中识别出的文字。","nullable":true}},"required":["timeSeconds","riskLevel","description","imageUrl","ocrText"]},"IntlVideoAudioDto":{"type":"object","properties":{"startSeconds":{"type":"number","description":"命中片段起点（秒）。"},"endSeconds":{"type":"number","description":"命中片段终点（秒）。"},"riskLevel":{"type":"string","description":"该片段的档位。","enum":["PASS","REVIEW","REJECT"],"nullable":true},"description":{"type":"string","description":"命中说明。"},"text":{"type":"object","description":"命中片段的语音文字。","nullable":true}},"required":["startSeconds","endSeconds","riskLevel","description","text"]},"IntlTranscriptRiskDto":{"type":"object","properties":{"matchedText":{"type":"string","description":"命中的口播原文片段。"},"severity":{"type":"string","description":"严重度。","enum":["high","medium","low"]},"category":{"type":"object","description":"风险类别，已本地化。","nullable":true},"suggestion":{"type":"object","description":"修改建议，已本地化。","nullable":true},"legalRef":{"type":"object","description":"条款出处，不随语言翻译。","nullable":true},"replacement":{"type":"object","description":"可直接替换 matchedText 的合规说法；为空表示只能删。","nullable":true},"startSeconds":{"type":"number","description":"命中所在句的起点（秒），可直接拿去 seek。"},"endSeconds":{"type":"number","description":"命中所在句的终点（秒）。"},"sentence":{"type":"object","description":"命中所在的完整句子，给你上下文。","nullable":true},"source":{"type":"string","description":"判定来源。","enum":["rule","model","custom"]}},"required":["matchedText","severity","category","suggestion","legalRef","replacement","startSeconds","endSeconds","sentence","source"]},"IntlVideoCheckResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"检测 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_video_check"},"status":{"type":"string","description":"视频审核状态。⚠️ **它不是轮询的唯一终止条件** —— 还要看 `transcriptStatus`，口播转写通常晚于画面审核完成。","enum":["processing","completed","failed"]},"video":{"description":"视频信息。","allOf":[{"$ref":"#/components/schemas/IntlVideoFileDto"}]},"platform":{"type":"string","description":"口播文案检测用的平台。","enum":["tiktok_id","shopee_id","tokopedia"],"nullable":true},"vertical":{"type":"string","description":"口播文案检测用的行业。","enum":["general","beauty","health","food","fashion"],"nullable":true},"riskLevel":{"type":"string","description":"顶层结论（画面 + 语音）。","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"整体风险标签。","type":"array","items":{"type":"string"}},"frames":{"description":"画面命中，带秒级时间点。","type":"array","items":{"$ref":"#/components/schemas/IntlVideoFrameDto"}},"audios":{"description":"语音命中，带起止秒。","type":"array","items":{"$ref":"#/components/schemas/IntlVideoAudioDto"}},"transcript":{"type":"object","description":"口播全文转写。","nullable":true},"transcriptStatus":{"type":"object","description":"口播转写状态：`null` 未启用 | `processing` 转写中 | `completed` | `failed` | `empty` 无音轨。**它是 processing 时说明口播风险还没出齐，请继续轮询。**","nullable":true},"transcriptRisks":{"description":"口播话术违规。走与文案检测同一套引擎，与画面 / 语音同等计入结论。","type":"array","items":{"$ref":"#/components/schemas/IntlTranscriptRiskDto"}},"createdAt":{"type":"object","description":"创建时间。"},"updatedAt":{"type":"object","description":"最后更新时间。"}},"required":["id","object","status","video","platform","vertical","riskLevel","labels","frames","audios","transcript","transcriptStatus","transcriptRisks","createdAt","updatedAt"]},"IntlBatchImageDto":{"type":"object","properties":{"url":{"type":"string","description":"图片地址，公网可访问。"},"name":{"type":"string","description":"图片标题 / 文件名。"},"size":{"type":"number","description":"图片体积（字节）。","example":254112},"width":{"type":"number","description":"宽度（像素）。"},"height":{"type":"number","description":"高度（像素）。"}},"required":["url","name","size"]},"IntlBatchVideoDto":{"type":"object","properties":{"url":{"type":"string","description":"视频地址，公网可访问。"},"name":{"type":"string","description":"视频标题 / 文件名。"},"size":{"type":"number","description":"视频体积，单位 **MB**（与单条视频检测同口径，不是字节）。","example":12.4},"duration":{"type":"number","description":"视频时长（秒），计费按它算。","example":45},"width":{"type":"number","description":"宽度（像素）。"},"height":{"type":"number","description":"高度（像素）。"}},"required":["url","name","size","duration"]},"CreateIntlBatchDto":{"type":"object","properties":{"name":{"type":"string","description":"素材包名称，1–60 字符。","example":"Kampanye Ramadan · batch 1"},"platform":{"type":"string","description":"发布平台，整包统一。","enum":["tiktok_id","shopee_id","tokopedia"],"example":"tiktok_id"},"vertical":{"type":"string","description":"内容行业，整包统一。","enum":["general","beauty","health","food","fashion"],"example":"beauty"},"texts":{"description":"文案子项，最多 10 条。**不足 10 字符的会被丢弃而不是整包报错** —— 一次提交十条，因为其中一条太短就全被拒、而错误信息又说不清是哪条，不是好契约。","type":"array","items":{"type":"string"}},"images":{"description":"图片子项，最多 20 张。","type":"array","items":{"$ref":"#/components/schemas/IntlBatchImageDto"}},"videos":{"description":"视频子项，最多 10 个。","type":"array","items":{"$ref":"#/components/schemas/IntlBatchVideoDto"}},"explainLocale":{"type":"string","description":"风险说明用哪种语言返回。","enum":["zh-CN","id-ID"],"default":"zh-CN"}},"required":["name","platform","vertical"]},"IntlBatchCountsDto":{"type":"object","properties":{"texts":{"type":"number","description":"文案子项数。"},"images":{"type":"number","description":"图片子项数。"},"videos":{"type":"number","description":"视频子项数。"}},"required":["texts","images","videos"]},"IntlBatchProgressDto":{"type":"object","properties":{"total":{"type":"number","description":"子项总数。","example":12},"done":{"type":"number","description":"已完成的子项数。","example":9},"percent":{"type":"number","description":"完成百分比（0–100）。","example":75}},"required":["total","done","percent"]},"IntlBatchItemSummaryDto":{"type":"object","properties":{"violation":{"type":"number","description":"违规条数。"},"sceneHint":{"type":"number","description":"场景提示条数。"}},"required":["violation","sceneHint"]},"IntlBatchListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"素材包 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_batch"},"name":{"type":"string","description":"素材包名称。"},"status":{"type":"string","description":"整包状态。"},"counts":{"description":"各类型子项数量。","allOf":[{"$ref":"#/components/schemas/IntlBatchCountsDto"}]},"progress":{"description":"进度。","allOf":[{"$ref":"#/components/schemas/IntlBatchProgressDto"}]},"result":{"type":"object","description":"整包结论。","nullable":true},"summary":{"description":"整包计数。","allOf":[{"$ref":"#/components/schemas/IntlBatchItemSummaryDto"}]},"createdAt":{"type":"object","description":"创建时间。"},"finishedAt":{"type":"object","description":"完成时间。","nullable":true}},"required":["id","object","name","status","counts","progress","result","summary","createdAt","finishedAt"]},"IntlBatchListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型，恒为 list。","example":"list"},"page":{"type":"number","description":"当前页码。","example":1},"pageSize":{"type":"number","description":"每页条数。","example":20},"total":{"type":"number","description":"符合条件的总条数。","example":128},"hasMore":{"type":"boolean","description":"是否还有下一页。","example":true},"data":{"description":"本页数据。","type":"array","items":{"$ref":"#/components/schemas/IntlBatchListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"IntlBatchItemDto":{"type":"object","properties":{"id":{"type":"string","description":"子项 id（不是检测 id）。"},"kind":{"type":"string","description":"子项类型。注意是 `text` 而不是内部的 script，与单项接口的路径一致。","enum":["text","image","video"]},"checkId":{"type":"string","description":"对应的**单项检测 id**。拿它去调 `/text|image|video/checks/{id}` 取完整明细。"},"index":{"type":"number","description":"子项在提交时的顺序下标。","example":0},"status":{"type":"string","description":"子项状态。","enum":["processing","completed","failed"]},"riskLevel":{"type":"object","description":"子项结论。文案是 safe/low/medium/high，图片视频是 PASS/REVIEW/REJECT。","nullable":true},"summary":{"description":"子项计数。","allOf":[{"$ref":"#/components/schemas/IntlBatchItemSummaryDto"}]},"text":{"type":"string","description":"文案子项：原文。"},"riskCount":{"type":"number","description":"文案子项：风险条数。"},"image":{"type":"object","description":"图片子项：地址与标题。"},"video":{"type":"object","description":"视频子项：地址、标题与时长。"},"labels":{"description":"图片 / 视频子项：风险标签。","type":"array","items":{"type":"string"}},"transcriptStatus":{"type":"object","description":"视频子项：口播转写状态。","nullable":true}},"required":["id","kind","checkId","index","status","riskLevel","summary"]},"IntlBatchResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"素材包 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_batch"},"name":{"type":"string","description":"素材包名称。"},"platform":{"type":"string","description":"发布平台。","enum":["tiktok_id","shopee_id","tokopedia"]},"vertical":{"type":"string","description":"内容行业。","enum":["general","beauty","health","food","fashion"]},"status":{"type":"string","description":"整包状态。","enum":["processing","completed","failed"]},"progress":{"description":"进度。","allOf":[{"$ref":"#/components/schemas/IntlBatchProgressDto"}]},"result":{"type":"string","description":"整包结论，全部子项完成后才有值。","enum":["PASS","REJECT"],"nullable":true},"summary":{"description":"整包计数。","allOf":[{"$ref":"#/components/schemas/IntlBatchItemSummaryDto"}]},"items":{"description":"子项明细。","type":"array","items":{"$ref":"#/components/schemas/IntlBatchItemDto"}},"createdAt":{"type":"object","description":"创建时间。"},"finishedAt":{"type":"object","description":"完成时间。","nullable":true}},"required":["id","object","name","platform","vertical","status","progress","result","summary","items","createdAt","finishedAt"]},"IntlCustomRuleResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"规则 id。"},"object":{"type":"string","description":"对象类型。","example":"intl_custom_rule"},"keyword":{"type":"string","description":"检测词。","example":"garansi uang kembali"},"matchType":{"type":"string","description":"匹配方式。","enum":["keyword","phrase"]},"replacement":{"type":"object","description":"替换词；为空则仅提醒。","nullable":true},"note":{"type":"object","description":"备注，仅自己可见。","nullable":true},"enabled":{"type":"boolean","description":"是否启用。"},"createdAt":{"type":"object","description":"创建时间。"},"updatedAt":{"type":"object","description":"最后更新时间。"}},"required":["id","object","keyword","matchType","replacement","note","enabled","createdAt","updatedAt"]},"IntlCustomRuleListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型，恒为 list。","example":"list"},"data":{"description":"本站点的全部规则（词库规模不大，不分页）。","type":"array","items":{"$ref":"#/components/schemas/IntlCustomRuleResponseDto"}},"total":{"type":"number","description":"规则总数。"}},"required":["object","data","total"]},"IntlCustomRuleQuotaDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型。","example":"intl_custom_rule_quota"},"used":{"type":"number","description":"已用条数。**配额是账户级的，跨站点共用一份** —— 含你在其他站点登记的词。","example":12},"limit":{"type":"number","description":"当前套餐的词库上限。免费版为 0。","example":500},"isPaid":{"type":"boolean","description":"本站点当前是否为付费订阅。","example":true}},"required":["object","used","limit","isPaid"]},"IntlCustomRuleSettingsDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型。","example":"intl_custom_rule_settings"},"enabled":{"type":"boolean","description":"账户级总开关。关闭时所有自定义词都不参与检测（数据保留）。"}},"required":["object","enabled"]},"IntlToggleSettingsDto":{"type":"object","properties":{"enabled":{"type":"boolean","description":"租户级总开关。关闭后所有自定义词都不参与检测（数据保留），与每条规则的 enabled 正交。**开关本身不分国家站**：它回答的是「这个账户要不要用自定义词库」。"}},"required":["enabled"]},"IntlBulkImportItemDto":{"type":"object","properties":{"keyword":{"type":"string","description":"要检测的词。","maxLength":100},"replacement":{"type":"string","description":"替换词。","maxLength":100},"note":{"type":"string","description":"备注。","maxLength":200}},"required":["keyword"]},"IntlBulkImportDto":{"type":"object","properties":{"items":{"description":"要导入的词条，单次上限 2000 条。批内重复、库里已存在的会被自动跳过（在响应里分别计数），不会报错。","type":"array","items":{"$ref":"#/components/schemas/IntlBulkImportItemDto"}}},"required":["items"]},"IntlCustomRuleImportResultDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型。","example":"intl_custom_rule_import_result"},"total":{"type":"number","description":"本次提交的词条总数。"},"imported":{"type":"number","description":"实际写入的条数。"},"skippedDuplicate":{"type":"number","description":"因批内重复或库中已存在而跳过的条数。"},"rejectedQuota":{"type":"number","description":"因超出套餐配额而被拒收的条数。"}},"required":["object","total","imported","skippedDuplicate","rejectedQuota"]},"CreateIntlCustomRuleDto":{"type":"object","properties":{"keyword":{"type":"string","description":"要检测的词。印尼站请填印尼语词 —— 检测的是印尼语文案，中文词永远不会命中。","example":"garansi uang kembali","maxLength":100},"matchType":{"type":"string","description":"匹配方式：keyword=子串匹配（默认，任何位置出现都算）、phrase=词边界匹配。**印尼语等以空格分词的语言建议用 phrase**，子串匹配会让短词误伤更长的词。","enum":["keyword","phrase"],"default":"keyword"},"replacement":{"type":"string","description":"替换词。配了之后命中项会带 `replacement`，可用于一键精确替换；留空则仅提醒。","example":"kebijakan pengembalian berlaku","maxLength":100},"note":{"type":"string","description":"备注，仅自己可见。","maxLength":200},"enabled":{"type":"boolean","description":"是否启用。停用后保留数据但不参与检测。","default":true}},"required":["keyword"]},"UpdateIntlCustomRuleDto":{"type":"object","properties":{"keyword":{"type":"string","description":"要检测的词。","maxLength":100},"replacement":{"type":"string","description":"替换词。","maxLength":100},"note":{"type":"string","description":"备注。","maxLength":200},"enabled":{"type":"boolean","description":"是否启用。"}}},"IntlAccountCreditsDto":{"type":"object","properties":{"total":{"type":"number","description":"本站点可用积分总额。","example":8420},"subscription":{"type":"number","description":"订阅赠送部分。"},"activity":{"type":"number","description":"活动赠送部分。"},"booster":{"type":"number","description":"加油包部分。"},"expiringSoon":{"type":"object","description":"7 天内即将过期的部分；没有则为 null。","nullable":true}},"required":["total","subscription","activity","booster","expiringSoon"]},"IntlAccountResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型。","example":"intl_account"},"country":{"type":"string","description":"本次调用所属的站点。","example":"id"},"credits":{"description":"**本站点的**积分余额。积分按站点隔离，中文站的余额不在这里。","allOf":[{"$ref":"#/components/schemas/IntlAccountCreditsDto"}]},"subscription":{"type":"object","description":"本站点的订阅档位。"},"usageThisMonth":{"type":"object","description":"本月（自然月）本站点各类检测次数，含网页与接口全部入口。"}},"required":["object","country","credits","subscription","usageThisMonth"]},"CreateIntlUploadPolicyDto":{"type":"object","properties":{"kind":{"type":"string","description":"素材类型，决定体积上限：video 上限 1GB，image 上限 10MB。","enum":["video","image"]}},"required":["kind"]},"IntlUploadPolicyResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"对象类型。","example":"intl_upload_policy"},"kind":{"type":"string","description":"素材类型。","enum":["video","image"]},"host":{"type":"string","description":"直传的目标地址（表单 POST 到这里）。"},"cdnHost":{"type":"string","description":"上传成功后素材的访问域名，素材地址 = `{cdnHost}/{key}`。"},"dir":{"type":"string","description":"允许写入的目录前缀。key 必须以它开头，否则会被拒收。"},"policy":{"type":"string","description":"上传策略（base64）。"},"accessKeyId":{"type":"string","description":"直传用的 AccessKeyId。"},"signature":{"type":"string","description":"策略签名。"},"maxSizeBytes":{"type":"number","description":"该类型的体积上限（字节）。"},"expiresAt":{"type":"string","description":"凭证过期时间（ISO 8601），5 分钟后失效。"}},"required":["object","kind","host","cdnHost","dir","policy","accessKeyId","signature","maxSizeBytes","expiresAt"]}}}}