> ## Documentation Index
> Fetch the complete documentation index at: https://docs.viggle.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 从角色与动作渲染视频

> 直接创建渲染任务，或提交已准备好的渲染草稿。

请求体有两种形式，由 `Content-Type` 决定。

`multipart/form-data` 直接根据角色和动作输入创建渲染任务。两类输入均可使用文件、URL 或已保存素材的 ID。该形式返回 `200`，忽略 `Idempotency-Key`。

`application/json` 使用[准备渲染](/zh/v1/api-reference/renders/prepare)返回的草稿创建任务。该形式返回 `202`，**必须提供** `Idempotency-Key`。幂等范围为当前已认证项目或 OAuth 身份：相同键和相同标准化输入返回原任务，相同键配合不同输入则返回 `IDEMPOTENCY_KEY_REUSED`。

<Note>
  **计费**（1 积分 = \$0.01）：按成品视频中每个角色每秒 \$0.01 收费。目前每次渲染仅支持 1 个角色，因此实际为 \$0.01/秒，10 秒视频为 \$0.10（10 积分）。无单次渲染最低消费。开始时根据输入预留预计费用，完成后按实际时长结算。详见[计费与保留期限](/zh/v1/pricing#video-remix)。
</Note>

## 请求参数：`multipart/form-data`

| 参数                 | 类型     |      必填      | 默认值        | 说明                                                                                             |
| ------------------ | ------ | :----------: | ---------- | ---------------------------------------------------------------------------------------------- |
| `character_id`     | string |    角色来源三选一   | —          | 当前调用者拥有的 `ready` 角色 ID，通常以 `char_` 开头。用于替代新图片。                                                 |
| `image`            | file   |    角色来源三选一   | —          | 直接上传的角色图片，与 `image_url`、`character_id` 三选一。                                                    |
| `image_url`        | string |    角色来源三选一   | —          | 服务可下载的公开角色图片 URL，替代 `image` 或 `character_id`。                                                  |
| `motion_id`        | string |    动作来源三选一   | —          | 当前调用者拥有的 `ready` 动作 ID，通常以 `mot_` 开头，用于替代新驱动视频。                                                |
| `motion_video`     | file   |    动作来源三选一   | —          | 直接上传的驱动视频，与 `motion_video_url`、`motion_id` 三选一。                                                |
| `motion_video_url` | string |    动作来源三选一   | —          | 服务可下载的公开驱动视频 URL，替代文件或动作 ID。                                                                   |
| `background_mode`  | string |       否      | `original` | `original` 保留或重建源背景；`solid` 使用 `bg_color`；`transparent` 输出 Alpha；`inpaint` 是 `original` 的兼容别名。 |
| `bg_color`         | string | `solid` 模式需要 | —          | `"R,G,B"` 格式的纯色，如 `"0,177,64"`，仅适用于 `background_mode=solid`。                                   |

若角色和动作两组输入都完全省略，服务会使用预配置的默认 `character_id`/`motion_id` 进行渲染。若只提供其中一组，例如有角色但无动作，则仍会报错。`bg_color` 仅适用于 `solid` 模式。

<Note>
  默认角色和动作按项目及环境配置，并非全站统一；不同 API 密钥提交空请求可能产生不同结果。此回退仅适合简单连通性检查，生产请求应明确提供角色和动作来源。
</Note>

## 请求参数：`application/json`（草稿模式）

| 请求头               |  必填 | 说明                                                                  |
| ----------------- | :-: | ------------------------------------------------------------------- |
| `Idempotency-Key` |  是  | 调用者生成的稳定键，长度 1–255 字符。相同标准化输入返回原任务，不同输入返回 `IDEMPOTENCY_KEY_REUSED`。 |

| 参数                                   | 类型     |   必填   | 说明                                                                            |
| ------------------------------------ | ------ | :----: | ----------------------------------------------------------------------------- |
| `draft_id`                           | string |    是   | [准备渲染](/zh/v1/api-reference/renders/prepare)返回的不透明草稿 ID。完成所有直传后原样传入；草稿仅能使用一次。 |
| `upload_completions`                 | array  | 有上传时必填 | 每个上传计划对应一项。草稿状态为 `awaiting_uploads` 时必填；无需上传时可省略或传空数组。                        |
| `upload_completions[].upload_handle` | string |  每项必填  | 对应上传计划中的不透明句柄，用于标识已完成的角色或动作上传。                                                |
| `upload_completions[].etag`          | string |    否   | 对象存储 `PUT` 返回的 ETag。若含外围引号，请保留。                                               |

## 响应参数

multipart 形式返回 `200 OK`，JSON 草稿形式返回 `202 Accepted`，两者都返回 Render 对象。但直接 multipart 的 `200` 响应仅在 `id`、`status`、`progress` 和 `created_at` 中提供有效信息。

| 字段                            | 类型             | 始终返回 | 说明                                                                        |
| ----------------------------- | -------------- | :--: | ------------------------------------------------------------------------- |
| `id`                          | string         |   是  | 以 `render_` 开头的公开 ID。                                                     |
| `status`                      | string         |   是  | `queued`、`processing`、`ready`、`failed` 或 `cancelled`。                     |
| `stage`                       | string 或 null  |   是  | 可用时提供大致阶段。multipart 流程使用 `analyzing`/`rendering`/`finishing`，草稿流程可能使用其他值。 |
| `progress`                    | integer 或 null |   是  | 可用时为 0–100 的进度。                                                           |
| `video_url`                   | string 或 null  |   是  | 就绪后的成品视频 URL。                                                             |
| `alpha_url`                   | string 或 null  |   是  | 透明输出的 Alpha 视频 URL。                                                       |
| `created_at` / `completed_at` | string 或 null  |   是  | ISO 8601 时间。                                                              |
| `error`                       | object 或 null  |   是  | 渲染失败时的错误详情。                                                               |
| `links`                       | object         |   否  | `{self, events, download}`，经过旧版迁移代理处理的任务不包含此字段。                           |

```json theme={null}
{"id":"render_789ghi","status":"queued","stage":null,"progress":0,"video_url":null,"alpha_url":null,"created_at":"2026-07-21T10:00:00+00:00","completed_at":null,"error":null,"links":{"self":"/v1/renders/render_789ghi","events":"/v1/renders/render_789ghi/events","download":"/v1/renders/render_789ghi/download"}}
```

`links.self` 仍指向已停用的 `GET /v1/renders/{render_id}`，不能继续使用。请用同一 `id` 调用[获取视频](/zh/v1/api-reference/videos/get)轮询。`links.events` 和 `links.download` 不受影响。

## 直接 multipart 示例

<CodeGroup>
  ```go Go theme={null}
  body:=&bytes.Buffer{}; w:=multipart.NewWriter(body); image,_:=os.Open("character.png"); defer image.Close(); video,_:=os.Open("dance.mp4"); defer video.Close(); p,_:=w.CreateFormFile("image","character.png"); io.Copy(p,image); p,_=w.CreateFormFile("motion_video","dance.mp4"); io.Copy(p,video); w.WriteField("background_mode","original"); w.Close(); req,_:=http.NewRequest("POST","https://apis.viggle.ai/v1/renders",body); req.Header.Set("Authorization","Bearer "+os.Getenv("VIGGLE_API_KEY")); req.Header.Set("Content-Type",w.FormDataContentType()); resp,err:=http.DefaultClient.Do(req); if err!=nil { panic(err) }; defer resp.Body.Close()
  ```

  ```javascript JavaScript theme={null}
  const form=new FormData(); form.append("image",imageFile); form.append("motion_video",videoFile); form.append("background_mode","original"); const response=await fetch("https://apis.viggle.ai/v1/renders",{method:"POST",headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`},body:form}); const render=await response.json();
  ```

  ```python Python theme={null}
  import os, requests
  with open("character.png","rb") as image, open("dance.mp4","rb") as video: response=requests.post("https://apis.viggle.ai/v1/renders",headers={"Authorization":f"Bearer {os.environ['VIGGLE_API_KEY']}"},files={"image":image,"motion_video":video},data={"background_mode":"original"})
  response.raise_for_status(); render=response.json()
  ```

  ```bash cURL theme={null}
  curl -X POST "https://apis.viggle.ai/v1/renders" -H "Authorization: Bearer $VIGGLE_API_KEY" -F "image=@character.png" -F "motion_video=@dance.mp4" -F "background_mode=original"
  ```
</CodeGroup>

## JSON 草稿示例

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://apis.viggle.ai/v1/renders" \
    -H "Authorization: Bearer $VIGGLE_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{"draft_id":"draft_abc123","upload_completions":[{"upload_handle":"up_1","etag":"\"9f...\""}]}'
  ```

  ```python Python theme={null}
  import os, uuid, requests
  response = requests.post(
      "https://apis.viggle.ai/v1/renders",
      headers={
          "Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}",
          "Idempotency-Key": str(uuid.uuid4()),
      },
      json={"draft_id": "draft_abc123", "upload_completions": [{"upload_handle": "up_1", "etag": "\"9f...\""}]},
  )
  response.raise_for_status()
  render = response.json()
  ```
</CodeGroup>

使用 JSON 模式前，获取 `draft_id` 和上传角色、动作素材的方法见[准备渲染](/zh/v1/api-reference/renders/prepare)。


## OpenAPI

````yaml zh/openapi.yaml POST /v1/renders
openapi: 3.0.3
info:
  title: Viggle API
  description: 使用 AI 生成角色动画视频。
  version: 2.0.0
  contact:
    name: Viggle Support
    url: https://viggle.ai
servers:
  - url: https://apis.viggle.ai
    description: 生产服务器
security:
  - bearerAuth: []
tags:
  - name: Renders
    description: 准备输入、创建渲染、观察进度并获取结果。
  - name: Credits
    description: 查询当前调用者可用的积分余额。
  - name: Characters
    description: 创建、列出、查询和删除可复用角色。type 决定是否同时提取 3D vsplat，就绪后通过导出接口获取下载链接。
  - name: Motions
    description: 创建、列出、查询和删除可复用动作，也可从官方模板导入。type 决定是否提取或生成 3D 动画，就绪后通过导出接口获取下载链接。
  - name: Videos
    description: 生成 MiniMax H3 视频（vid_）或角色动画视频（anim_），并统一查询调用者的 H3、角色动画及角色动作渲染（render_）结果。
paths:
  /v1/renders:
    post:
      tags:
        - Renders
      summary: 从角色与动作渲染视频
      description: 直接创建渲染任务，或提交已准备好的渲染草稿。
      operationId: createRender
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/SourceChannel'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateRenderForm'
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRenderRequest'
      responses:
        '200':
          description: 请求成功。
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Render'
        '202':
          description: 请求成功。
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Render'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/V1Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: 调用者生成的稳定幂等键，最长 255 字符。POST /v1/renders 的 JSON 草稿模式必填，multipart 模式忽略。
      schema:
        type: string
        minLength: 1
        maxLength: 255
    RequestId:
      name: X-Request-Id
      in: header
      required: false
      description: 可选的调用者自定义关联 ID，最长 128 字符。服务会在响应头返回实际使用的值，便于追踪和支持排查。
      schema:
        type: string
        minLength: 1
        maxLength: 128
    SourceChannel:
      name: X-Viggle-Source
      in: header
      required: false
      description: 可选来源标签，最长 128 字符，用于识别 SDK、集成、产品入口或内部工作流。
      schema:
        type: string
        minLength: 1
        maxLength: 128
  schemas:
    CreateRenderForm:
      description: >-
        角色在 image、image_url、character_id 中三选一，动作在
        motion_video、motion_video_url、motion_id
        中三选一。两组都完全省略时服务使用预配置默认角色和动作；仅提供一组仍会报错。
      type: object
      properties:
        image:
          type: string
          format: binary
          description: 直接上传的角色图片，与 `image_url`、`character_id` 三选一。
        image_url:
          type: string
          format: uri
          description: 服务可下载的公开角色图片 URL，替代 `image` 或 `character_id`。
        character_id:
          type: string
          description: 当前调用者拥有的 `ready` 角色 ID，通常以 `char_` 开头。用于替代新图片。
          minLength: 1
        motion_video:
          type: string
          format: binary
          description: 直接上传的驱动视频，与 `motion_video_url`、`motion_id` 三选一。
        motion_video_url:
          type: string
          format: uri
          description: 服务可下载的公开驱动视频 URL，替代文件或动作 ID。
        motion_id:
          type: string
          description: 当前调用者拥有的 `ready` 动作 ID，通常以 `mot_` 开头，用于替代新驱动视频。
          minLength: 1
        background_mode:
          description: >-
            `original` 保留或重建源背景；`solid` 使用 `bg_color`；`transparent` 输出
            Alpha；`inpaint` 是 `original` 的兼容别名。
          type: string
          enum:
            - original
            - solid
            - transparent
            - inpaint
          default: original
        bg_color:
          description: '`"R,G,B"` 格式的纯色，如 `"0,177,64"`，仅适用于 `background_mode=solid`。'
          type: string
          example: 0,177,64
    CreateRenderRequest:
      type: object
      additionalProperties: false
      required:
        - draft_id
      properties:
        draft_id:
          type: string
          description: >-
            [准备渲染](/zh/v1/api-reference/renders/prepare)返回的不透明草稿
            ID。完成所有直传后原样传入；草稿仅能使用一次。
          minLength: 1
        upload_completions:
          type: array
          description: 每个上传计划对应一项。草稿状态为 `awaiting_uploads` 时必填；无需上传时可省略或传空数组。
          items:
            $ref: '#/components/schemas/UploadCompletion'
    Render:
      description: >-
        不含相关信息的渲染中，stage、progress、created_at 为 null，迁移代理处理的渲染可能省略
        links，读取时应容忍缺失。响应提供结果 URL，但不提供媒体尺寸、时长、缩略图 URL 或链接过期元数据，不应自行推断这些字段。
      type: object
      additionalProperties: false
      required:
        - id
        - status
        - stage
        - progress
        - video_url
        - alpha_url
        - created_at
        - completed_at
        - error
      properties:
        id:
          type: string
          description: 以 `render_` 开头的公开 ID。
          minLength: 1
        status:
          description: '`queued`、`processing`、`ready`、`failed` 或 `cancelled`。'
          allOf:
            - $ref: '#/components/schemas/RenderStatus'
        stage:
          type: string
          description: >-
            可用时提供大致阶段。multipart 流程使用
            `analyzing`/`rendering`/`finishing`，草稿流程可能使用其他值。
          nullable: true
          allOf:
            - $ref: '#/components/schemas/RenderStage'
        progress:
          type: integer
          description: 可用时为 0–100 的进度。
          nullable: true
          minimum: 0
          maximum: 100
        video_url:
          type: string
          description: 就绪后的成品视频 URL。
          nullable: true
          format: uri
        alpha_url:
          type: string
          description: 透明输出的 Alpha 视频 URL。
          nullable: true
          format: uri
        created_at:
          type: string
          description: ISO 8601 时间。
          nullable: true
          format: date-time
        completed_at:
          type: string
          description: ISO 8601 时间。
          nullable: true
          format: date-time
        error:
          type: object
          description: 渲染失败时的错误详情。
          nullable: true
          allOf:
            - $ref: '#/components/schemas/RenderFailure'
        links:
          description: '`{self, events, download}`，经过旧版迁移代理处理的任务不包含此字段。'
          allOf:
            - $ref: '#/components/schemas/RenderLinks'
    UploadCompletion:
      type: object
      additionalProperties: false
      required:
        - upload_handle
      properties:
        upload_handle:
          type: string
          description: 对应上传计划中的不透明句柄，用于标识已完成的角色或动作上传。
          minLength: 1
        etag:
          type: string
          description: 对象存储 `PUT` 返回的 ETag。若含外围引号，请保留。
          minLength: 1
    RenderStatus:
      type: string
      enum:
        - queued
        - processing
        - ready
        - failed
        - cancelled
    RenderStage:
      description: >-
        大致处理阶段。multipart 渲染使用
        analyzing、rendering、finishing，其他值来自草稿流程。未知值应按处理中处理，不要直接失败。
      type: string
      enum:
        - queued
        - preparing
        - generating
        - finalizing
        - ready
        - failed
        - cancelled
        - analyzing
        - rendering
        - finishing
    RenderFailure:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: 稳定的机器可读失败码，请用其处理程序逻辑，不要解析 message。
        message:
          type: string
          description: 供人阅读的渲染失败说明。
        details:
          type: object
          description: 失败服务提供的补充结构化信息，具体键随错误码变化。
          additionalProperties: true
        request_id:
          type: string
          description: 可提供给支持团队的请求或工作进程关联 ID，无法关联时为 null。
          nullable: true
    RenderLinks:
      type: object
      additionalProperties: false
      required:
        - self
        - events
        - download
      properties:
        self:
          type: string
          description: 获取渲染最新持久化状态的相对路径。旧 self 路径已停用，请改用统一视频查询。
        events:
          type: string
          description: 通过 SSE 监听此渲染的相对 API 路径。
        download:
          type: string
          description: 渲染就绪后获取新的短期下载链接的相对 API 路径。
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          description: 草稿流程的顶层错误，包含稳定错误码、说明、重试建议、关联 ID 和错误详情。
          allOf:
            - $ref: '#/components/schemas/ErrorBody'
    ErrorBody:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - retryable
        - request_id
        - details
        - remediation
      properties:
        code:
          description: 恢复方法
          allOf:
            - $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
          description: 供人阅读的描述，不要解析其文本做逻辑判断。
        retryable:
          type: boolean
          description: 重试相同请求是否可能成功。
        request_id:
          type: string
          description: 用于关联 Viggle 日志与支持排查。仅当异步工作进程无法恢复原请求 ID 时为 `null`。
        details:
          type: object
          description: 补充结构化信息，可能为空。
          additionalProperties: true
        remediation:
          description: >-
            `{action, retry_after_ms}`，表示下一步操作。除非建议定时重试，否则 `retry_after_ms` 为
            `null`。
          allOf:
            - $ref: '#/components/schemas/ErrorRemediation'
    ErrorCode:
      description: 草稿渲染流程的错误码集合。资源操作将相应错误映射为 ResourceError 说明的小写下划线形式。
      type: string
      enum:
        - UNAUTHENTICATED
        - INVALID_CREDENTIAL
        - FORBIDDEN
        - INVALID_REQUEST
        - INVALID_CHARACTER
        - INVALID_MOTION
        - UNSUPPORTED_MEDIA
        - CONTENT_POLICY_VIOLATION
        - UPLOAD_REQUIRED
        - UPLOAD_MISMATCH
        - UPLOAD_EXPIRED
        - DRAFT_NOT_FOUND
        - DRAFT_ALREADY_CONSUMED
        - RENDER_NOT_FOUND
        - RENDER_NOT_CANCELLABLE
        - CHARACTER_NOT_FOUND
        - MOTION_NOT_FOUND
        - MOTION_NOT_READY
        - MOTION_TEMPLATE_NOT_FOUND
        - AVATAR_NOT_FOUND
        - ANIMATION_NOT_FOUND
        - EXTRACTION_UNAVAILABLE
        - EXTRACTION_FAILED
        - IDEMPOTENCY_KEY_REUSED
        - INSUFFICIENT_CREDITS
        - RATE_LIMITED
        - SERVICE_BUSY
        - INTERNAL_ERROR
    ErrorRemediation:
      type: object
      additionalProperties: false
      required:
        - action
        - retry_after_ms
      properties:
        action:
          type: string
          description: 建议的下一步操作，供程序或人工读取，例如稍后重试、重新上传或修正输入。
        retry_after_ms:
          type: integer
          description: 建议重试等待的毫秒数；无需定时重试时为 null。
          nullable: true
          format: int64
          minimum: 0
  headers:
    RequestId:
      description: 用于支持排查和追踪的稳定请求 ID。
      schema:
        type: string
  responses:
    BadRequest:
      description: 请求失败，详情见错误响应。
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    V1Unauthorized:
      description: 请求失败，详情见错误响应。
      headers:
        WWW-Authenticate:
          schema:
            type: string
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    PaymentRequired:
      description: 请求失败，详情见错误响应。
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: 请求失败，详情见错误响应。
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: 请求失败，详情见错误响应。
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Conflict:
      description: 请求失败，详情见错误响应。
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnprocessableEntity:
      description: 请求失败，详情见错误响应。
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: 请求失败，详情见错误响应。
      headers:
        Retry-After:
          schema:
            type: integer
            minimum: 0
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: 请求失败，详情见错误响应。
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ServiceUnavailable:
      description: 请求失败，详情见错误响应。
      headers:
        Retry-After:
          schema:
            type: integer
            minimum: 0
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key or OAuth access token
      description: 服务端 SDK 使用项目 API 密钥，Remote MCP 使用 OAuth 访问令牌。不要在浏览器代码中暴露项目密钥。

````