{
  "openapi": "3.1.0",
  "info": {
    "title": "Seedance Video API",
    "version": "1.1.0",
    "description": "使用审核通过账号的 API Key 上传参考图片、创建、查询、列出视频任务及读取模型和余额。模型由后台动态启用；客户端必须先读取 /v1/models，不要把示例模型当成固定枚举。每个账号可创建多个 Key，各 Key 共用账号余额、限流、任务记录和幂等范围。成功任务的绝对内容地址支持公开 GET/HEAD 播放下载，无需 API Key、Cookie 或 token，支持 Range 和公开 CORS。图片上传不扣生成余额；视频任务和结果按原创建时间保留 24 小时，读取不延长有效期。"
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/models": {
      "get": {
        "summary": "获取可用模型",
        "description": "返回后台已启用且已绑定可用接口的模型。模型列表会随管理员配置变化，客户端必须以本响应为准。每个模型同时返回 billingMode 和同值 billing_mode：per_task 为每次计费，per_second 为按秒计费，旧模型默认 per_task。resolutions[].price 始终是 API 单价；按秒模型的任务金额为单价乘以验证后的请求时长，四舍五入到六位小数。",
        "responses": {
          "200": {
            "description": "模型列表",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/balance": {
      "get": {
        "summary": "获取账号余额",
        "responses": {
          "200": {
            "description": "余额",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Balance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/uploads/images": {
      "post": {
        "operationId": "uploadReferenceImage",
        "summary": "上传单张参考图片",
        "description": "使用有效且已审核账号的 Bearer API Key 上传单张图片；仅有网页登录 Session 不能调用。图片实际字节最大 8 MiB（8388608 字节），支持 PNG、JPEG、GIF、WebP、AVIF，按字节识别格式。推荐 multipart 的 file 字段，不要手动设置 multipart Content-Type，客户端需生成 boundary。multipart 请求体最大 8454144 字节；JSON 请求体最大 12582912 字节。上传不扣生成余额，不创建视频任务，不调用视频上游。每次成功上传产生新链接，不提供幂等；与同账号其他 /v1 请求共用每分钟 120 次限流。返回顶层 url 为供上游抓取的公开图片链接，建议上传后立即用于 POST /v1/videos 的 input.media[].url。上传图片不承诺永久保留。",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ImageUploadMultipart"
              },
              "x-max-body-bytes": 8454144
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageUploadJson"
              },
              "x-max-body-bytes": 12582912,
              "example": {
                "dataUrl": "data:image/png;base64,...",
                "originalName": "参考.png"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "上传成功。读取顶层 url 作为生成接口的参考图片地址。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageUpload"
                },
                "example": {
                  "id": "img_12345678-1234-1234-1234-123456789012",
                  "object": "image.upload",
                  "url": "https://example.invalid/api/uploaded-image/uploads/12345678-1234-1234-1234-123456789012.png",
                  "filename": "参考.png",
                  "mime_type": "image/png",
                  "size": 123
                }
              }
            }
          },
          "400": {
            "description": "invalid_upload：上传字段不正确、缺少文件或 dataUrl 无效",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_upload",
                    "message": "上传字段不正确、缺少文件或 dataUrl 无效"
                  }
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key：API Key 无效或账号尚未通过审核",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "invalid_api_key",
                    "message": "API Key 无效或账号尚未通过审核"
                  }
                }
              }
            }
          },
          "405": {
            "description": "method_not_allowed：此接口仅支持 POST",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "method_not_allowed",
                    "message": "此接口仅支持 POST"
                  }
                }
              }
            }
          },
          "413": {
            "description": "image_too_large：图片或请求体超过大小上限",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "image_too_large",
                    "message": "图片或请求体超过大小上限"
                  }
                }
              }
            }
          },
          "415": {
            "description": "unsupported_image：图片格式或上传 Content-Type 不支持",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "unsupported_image",
                    "message": "图片格式或上传 Content-Type 不支持"
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded：请求过于频繁，请等待 Retry-After 后重试",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "再次请求前等待的秒数"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "rate_limit_exceeded",
                    "message": "请求过于频繁，请等待 Retry-After 后重试"
                  }
                }
              }
            }
          },
          "503": {
            "description": "storage_unavailable：图片存储暂时不可用",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "ok": false,
                  "error": {
                    "code": "storage_unavailable",
                    "message": "图片存储暂时不可用"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/videos": {
      "post": {
        "summary": "创建视频任务",
        "description": "建议把 /v1/models 返回的正式 id 放在 model 字段；兼容 model_id、modelId、Seedance 2.0 常见缩写 sd2.0，以及可唯一识别的大小写、空格或分隔符差异，响应始终返回正式 id。按后台模型计费方式预扣余额：per_task按所选分辨率的API每次单价，per_second按API每秒单价乘以验证后的parameters.duration；省略时长使用模型最大允许秒数。总额四舍五入到六位小数并保存为任务amount。明确失败或取消时按原任务amount退回一次，不使用后来修改的价格重新计算。管理员无限余额，amount为0。计费方式由模型配置决定，不由创建请求覆盖。",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "建议填写；8-128 位字母、数字或 ._:-。网络超时或未收到确定响应时，必须用完全相同的请求体复用同一个值。",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9._:-]+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVideoRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "任务已接受",
            "headers": {
              "Idempotent-Replayed": {
                "schema": {
                  "type": "string"
                },
                "description": "幂等响应重放时为 true"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoTask"
                }
              }
            }
          },
          "202": {
            "description": "任务已受理，但结果仍需继续核对。reconciliation_required=true 表示提交结果尚未与上游完成核对，客户端必须复用原任务 ID 查询且不得重新创建；code=video_result_pending 或 result_pending=true 表示上游已完成生成但成片文件仍在准备，任务保持 processing 且 video_url/url 为空。Retry-After 仅在服务端给出建议轮询间隔时返回。",
            "headers": {
              "Retry-After": {
                "description": "可选；建议再次查询原任务前等待的秒数。",
                "schema": {
                  "type": "integer",
                  "minimum": 1
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoTask"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "get": {
        "summary": "获取当前账号的任务历史",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "任务列表",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoTaskList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/videos/{task_id}": {
      "get": {
        "summary": "刷新并获取单个任务",
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskId"
          }
        ],
        "responses": {
          "200": {
            "description": "任务详情",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VideoTask"
                }
              }
            }
          },
          "202": {
            "description": "video_result_pending：上游已完成生成，但成片文件仍在准备。任务保持 processing，不会发布 video_url；按 Retry-After 继续查询原任务，不要重新创建。",
            "headers": {
              "Retry-After": {
                "schema": { "type": "integer", "const": 20 },
                "description": "建议再次查询前等待的秒数"
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VideoTask" }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/v1/videos/{task_id}/content": {
      "get": {
        "summary": "公开播放或下载成功视频",
        "description": "此精确内容地址无需 API Key、Cookie 或 token，支持跨域公开 CORS（Access-Control-Allow-Origin: *）及 HTTP Range。仅成功、未过期、未删除且有结果的任务可读取。如供应商先报成功而成片仍在准备，返回409 video_result_pending 和 Retry-After；客户端应回到任务详情接口继续轮询。原24小时生命周期不因播放下载延长。任务输出的 video_url/url 指向本站此绝对地址。",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskId"
          },
          {
            "name": "Range",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "example": "bytes=0-1048575"
          },
          {
            "name": "download",
            "in": "query",
            "description": "传1请求附件下载；省略时可直接播放。",
            "schema": {
              "type": "integer",
              "enum": [1]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "完整视频内容；公开CORS，download=1时作为附件下载。",
            "headers": {
              "Content-Type": {
                "description": "实际视频媒体类型。",
                "schema": { "type": "string", "example": "video/mp4" }
              },
              "Content-Length": {
                "description": "上游提供长度时返回的完整视频字节数。",
                "schema": { "type": "integer", "minimum": 0 }
              },
              "Accept-Ranges": {
                "description": "视频源支持字节范围请求时为 bytes。",
                "schema": { "type": "string", "const": "bytes" }
              },
              "Access-Control-Allow-Origin": {
                "schema": { "type": "string", "const": "*" }
              },
              "Access-Control-Expose-Headers": {
                "description": "允许跨域客户端读取媒体长度、范围、类型、文件名和缓存校验响应头。",
                "schema": { "type": "string", "example": "Content-Length, Content-Range, Accept-Ranges, Content-Type, Content-Disposition, ETag, Last-Modified" }
              },
              "Content-Disposition": {
                "description": "download=1时使用 attachment；播放请求使用 inline。",
                "schema": { "type": "string" }
              }
            },
            "content": {
              "video/mp4": {
                "schema": {
                  "type": "string",
                  "contentEncoding": "binary"
                }
              }
            }
          },
          "206": {
            "description": "Range请求的部分视频内容。",
            "headers": {
              "Content-Type": { "schema": { "type": "string", "example": "video/mp4" } },
              "Content-Length": {
                "description": "本次部分响应的字节数。",
                "schema": { "type": "integer", "minimum": 1 }
              },
              "Content-Range": { "schema": { "type": "string" } },
              "Accept-Ranges": { "schema": { "type": "string", "const": "bytes" } },
              "Content-Disposition": {
                "description": "download=1时使用 attachment；播放请求使用 inline。",
                "schema": { "type": "string" }
              },
              "Access-Control-Allow-Origin": { "schema": { "type": "string", "const": "*" } },
              "Access-Control-Expose-Headers": {
                "schema": { "type": "string", "example": "Content-Length, Content-Range, Accept-Ranges, Content-Type, Content-Disposition, ETag, Last-Modified" }
              }
            },
            "content": {
              "video/mp4": {
                "schema": {
                  "type": "string",
                  "contentEncoding": "binary"
                }
              }
            }
          },
          "409": {
            "description": "video_result_pending：任务已进入成片准备阶段，当前还不能播放或下载。按 Retry-After 轮询任务详情。",
            "headers": {
              "Retry-After": { "schema": { "type": "integer", "const": 20 } }
            },
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "404": {
            "description": "任务不存在、未成功、无结果、已删除或已过期。",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "416": {
            "description": "请求的Range无效或超出视频范围。"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          }
        }
      },
      "head": {
        "summary": "公开检查视频内容",
        "description": "与GET相同的成功、未过期、未删除、有结果限制及公开CORS，无需API Key、Cookie或token。只返回响应头，不返回视频正文；不会延长原24小时有效期。",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskId"
          },
          {
            "name": "Range",
            "in": "header",
            "schema": { "type": "string" },
            "example": "bytes=0-1048575"
          },
          {
            "name": "download",
            "in": "query",
            "description": "传1使用附件下载响应头。",
            "schema": { "type": "integer", "enum": [1] }
          }
        ],
        "responses": {
          "200": {
            "description": "视频可用，只返回响应头。",
            "headers": {
              "Content-Type": { "schema": { "type": "string", "example": "video/mp4" } },
              "Content-Length": {
                "description": "上游提供长度时返回的完整视频字节数。",
                "schema": { "type": "integer", "minimum": 0 }
              },
              "Accept-Ranges": {
                "description": "视频源支持字节范围请求时为 bytes。",
                "schema": { "type": "string", "const": "bytes" }
              },
              "Content-Disposition": {
                "description": "download=1时使用 attachment；播放请求使用 inline。",
                "schema": { "type": "string" }
              },
              "Access-Control-Allow-Origin": { "schema": { "type": "string", "const": "*" } },
              "Access-Control-Expose-Headers": {
                "schema": { "type": "string", "example": "Content-Length, Content-Range, Accept-Ranges, Content-Type, Content-Disposition, ETag, Last-Modified" }
              }
            }
          },
          "206": {
            "description": "有效Range的部分内容响应头，无正文。",
            "headers": {
              "Content-Type": { "schema": { "type": "string", "example": "video/mp4" } },
              "Content-Length": {
                "description": "本次部分响应的字节数。",
                "schema": { "type": "integer", "minimum": 1 }
              },
              "Content-Range": { "schema": { "type": "string" } },
              "Accept-Ranges": { "schema": { "type": "string", "const": "bytes" } },
              "Content-Disposition": {
                "description": "download=1时使用 attachment；播放请求使用 inline。",
                "schema": { "type": "string" }
              },
              "Access-Control-Allow-Origin": { "schema": { "type": "string", "const": "*" } },
              "Access-Control-Expose-Headers": {
                "schema": { "type": "string", "example": "Content-Length, Content-Range, Accept-Ranges, Content-Type, Content-Disposition, ETag, Last-Modified" }
              }
            }
          },
          "409": {
            "description": "video_result_pending：成片文件仍在准备；返回 Retry-After，HEAD 无正文。",
            "headers": {
              "Retry-After": { "schema": { "type": "integer", "const": 20 } },
              "Access-Control-Allow-Origin": { "schema": { "type": "string", "const": "*" } },
              "Access-Control-Expose-Headers": {
                "schema": { "type": "string", "example": "Content-Length, Content-Range, Accept-Ranges, Content-Type, Content-Disposition, ETag, Last-Modified, Retry-After" }
              }
            }
          },
          "404": {
            "description": "任务不存在、未成功、无结果、已删除或已过期；无正文。"
          },
          "416": {
            "description": "请求的Range无效或超出视频范围；无正文。"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sd_live_..."
      }
    },
    "parameters": {
      "TaskId": {
        "name": "task_id",
        "in": "path",
        "required": true,
        "description": "POST /v1/videos 响应中的本站任务 id，必须原样使用。",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "Resolution": {
        "type": "object",
        "required": [
          "value",
          "label",
          "price"
        ],
        "properties": {
          "value": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "price": {
            "type": "number",
            "description": "该分辨率的API单价，可与网页单价不同。所属模型billingMode为per_task时单位为余额/次；per_second时单位为余额/秒，任务总额为price乘以验证后的parameters.duration并四舍五入到六位小数。",
            "example": 2.5
          }
        }
      },
      "Model": {
        "type": "object",
        "required": [
          "id",
          "object",
          "name",
          "billingMode",
          "billing_mode",
          "resolutions",
          "durations"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "video.model"
          },
    "name": {
      "type": "string",
      "description": "后台配置的模型显示名称。"
    },
          "billingMode": {
            "type": "string",
            "enum": ["per_task", "per_second"],
            "default": "per_task",
            "description": "模型级计费方式：per_task按次，per_second按秒；旧模型默认per_task。与billing_mode值相同。兼容旧版响应时缺失字段也按per_task处理。",
            "example": "per_task"
          },
          "billing_mode": {
            "type": "string",
            "enum": ["per_task", "per_second"],
            "default": "per_task",
            "description": "billingMode的同值API字段；两者在/v1/models中同时返回。",
            "example": "per_task"
          },
          "resolutions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Resolution"
            }
          },
          "durations": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 30
            }
          },
          "supports_reference_audio": {
            "type": "boolean"
          },
          "supports_reference_video": {
            "type": "boolean"
          }
        }
      },
      "ModelList": {
        "type": "object",
        "required": [
          "object",
          "data"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Model"
            }
          }
        }
      },
      "Balance": {
        "type": "object",
        "required": [
          "object",
          "username",
          "unlimited",
          "credits"
        ],
        "properties": {
          "object": {
            "const": "balance"
          },
          "username": {
            "type": "string"
          },
          "unlimited": {
            "type": "boolean"
          },
          "credits": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "Media": {
        "type": "object",
        "required": [
          "type",
          "url"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "reference_image",
              "reference_voice",
              "reference_video"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https?://",
            "description": "公网 HTTP(S) 素材地址。本地图片先通过 POST /v1/uploads/images 上传，使用响应的顶层 url；不要传本地路径或 Base64。"
          }
        }
      },
      "CreateVideoRequest": {
        "type": "object",
        "required": [
          "input"
        ],
        "oneOf": [
          { "required": ["model"] },
          { "required": ["model_id"] },
          { "required": ["modelId"] }
        ],
        "properties": {
          "model": {
            "type": "string"
          },
          "model_id": {
            "type": "string",
            "description": "model 的兼容别名；响应统一返回正式 model ID。"
          },
          "modelId": {
            "type": "string",
            "description": "model 的兼容别名；响应统一返回正式 model ID。"
          },
          "input": {
            "type": "object",
            "required": [
              "prompt"
            ],
            "properties": {
              "prompt": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10000
              },
              "media": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Media"
                }
              }
            }
          },
          "parameters": {
            "type": "object",
            "properties": {
              "resolution": {
                "type": "string"
              },
              "ratio": {
                "type": "string",
                "default": "16:9"
              },
              "duration": {
                "type": "integer",
                "minimum": 1,
                "maximum": 30,
                "description": "必须是所选模型durations中允许的秒数；省略时使用该模型最大允许秒数。per_second模型使用此验证后的时长计算任务总额，不按成片测量时长计费。"
              }
            }
          }
        }
      },
      "VideoTask": {
        "type": "object",
        "required": [
          "id",
          "object",
          "status",
          "model",
          "resolution",
          "ratio",
          "duration",
          "amount",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "本站任务 ID；查询和下载时原样使用，不是上游平台任务号。"
          },
          "object": {
            "const": "video.task"
          },
          "model": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "succeeded",
              "failed"
            ]
          },
          "prompt": {
            "type": "string"
          },
          "resolution": {
            "type": "string"
          },
          "ratio": {
            "type": "string"
          },
          "duration": {
            "type": [
              "integer",
              "null"
            ],
            "description": "创建请求验证后采用的时长（秒）；请求省略时使用模型最大允许秒数。per_second计费以此时长计算。"
          },
          "video_url": {
            "type": "string",
            "description": "成功且有结果时为当前站点的绝对地址 /v1/videos/{id}/content，与url相同；其他状态为空字符串。支持无需API Key、Cookie或token的GET/HEAD、公开CORS和Range，添加?download=1可下载。任务删除或达到原expires_at后不可访问。"
          },
          "url": {
            "type": "string",
            "description": "与video_url相同的本站绝对公开内容地址；未成功或无结果时为空字符串。"
          },
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "处理中的成片尚未可读时为 video_result_pending。"
          },
          "message": {
            "type": "string"
          },
          "result_pending": {
            "type": "boolean",
            "description": "true 表示上游已完成生成，但视频文件仍在准备；任务状态仍为 processing。"
          },
          "retryable": {
            "type": "boolean"
          },
          "retry_after": {
            "type": "integer",
            "description": "建议再次查询前等待的秒数。"
          },
          "reconciliation_required": {
            "type": "boolean",
            "description": "true 表示提交结果尚未与上游完成核对；客户端应继续查询此任务，不得重复创建。"
          },
          "local_task_id": {
            "type": "string",
            "description": "本站用于查询和幂等追踪的任务 ID；存在时与 id 含义一致。"
          },
          "local_task_id_type": {
            "type": "string",
            "enum": ["request_tracking_id"],
            "description": "local_task_id 的类型标记。"
          },
          "amount": {
            "type": "number",
            "description": "该任务实际记录的总余额金额，四舍五入到六位小数。per_task为API每次单价，per_second为API每秒单价乘以验证后的请求时长；例如0.18余额/秒×15秒=2.70余额。管理员无限余额，amount为0。失败或取消退款按此原始金额执行一次，不按后来修改的价格重新计算。",
            "example": 2.7
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "原任务创建后24小时的到期时间；查询、播放或下载不延长此期限。"
          }
        }
      },
      "VideoTaskList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VideoTask"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "const": false
          },
          "error": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            ]
          }
        }
      },
      "ImageUploadMultipart": {
        "type": "object",
        "required": [
          "file"
        ],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "单张图片文件，最大 8388608 字节。支持 PNG/JPEG/GIF/WebP/AVIF，按实际图片字节识别格式。"
          },
          "originalName": {
            "type": "string",
            "description": "可选原始文件名，仅用于显示，不决定图片格式。",
            "example": "参考.png"
          }
        }
      },
      "ImageUploadJson": {
        "type": "object",
        "required": [
          "dataUrl"
        ],
        "properties": {
          "dataUrl": {
            "type": "string",
            "pattern": "^data:image/(png|jpe?g|gif|webp|avif);base64,",
            "description": "含 data:image/...;base64, 前缀的完整 Data URL；Base64 解码后的图片最大 8388608 字节。仅供上传接口使用，不能直接放进生成请求的 input.media[].url。"
          },
          "originalName": {
            "type": "string",
            "description": "可选原始文件名。",
            "example": "参考.png"
          }
        }
      },
      "ImageUpload": {
        "type": "object",
        "required": [
          "id",
          "object",
          "url",
          "filename",
          "mime_type",
          "size"
        ],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^img_",
            "description": "上传图片的标识，不是视频任务 ID。"
          },
          "object": {
            "const": "image.upload"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https?://",
            "description": "供视频上游公开抓取的图片链接。直接填入生成请求 input.media[].url，建议上传后立即提交。"
          },
          "filename": {
            "type": "string",
            "description": "原始文件名经过清理后返回，最多 120 个字符；未提供时自动命名。"
          },
          "mime_type": {
            "type": "string",
            "enum": [
              "image/png",
              "image/jpeg",
              "image/gif",
              "image/webp",
              "image/avif"
            ]
          },
          "size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 8388608,
            "description": "图片字节数，不含 Base64 或 multipart 编码开销。"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "请求字段不正确",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "API Key 无效或账号未审核",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InsufficientCredits": {
        "description": "余额不足",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "任务不属于当前账号",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "任务不存在或已过期",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "幂等冲突、任务处理中或内容未完成",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "超过每分钟 120 次限制",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "BadGateway": {
        "description": "上游或视频源返回异常",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "上游服务暂时不可用，可重试",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
