# 创建生成任务

`createGeneration`

`POST /v1/generations`

下面的接口说明为英文原文。

Each accepted POST durably records a separate generation. The response has status processing and billing_status pending; the reserved amount is zero until Credits are held. A funding rejection closes the task with error.code set; read it again to see it. Submitting the same request twice can incur two charges. After a lost response, check the generation list before deciding to create another task. HTTP 429 with code concurrency_limited means the organization already has as many unfinished tasks of this media type (video, image, audio or other) as its concurrency limit allows (by default 3 video, 10 image and 10 audio tasks at once per organization; see /docs/rate-limits); nothing is recorded or held, so retry after the Retry-After seconds or queue on your side. Other 429 answers use rate_limited.

## 鉴权

在请求头带上项目 API Key，例如 `Authorization: Bearer $VIZO_API_KEY`。API Key 只放在服务端。

## 请求体

- `input` (object, 必填) The model input. Its schema is the model's inputSchema in the catalog.
- `metadata` (map<string, string>, 可选) 你自己的字符串键值，原样返回。建议写入 client_reference，回包丢失时用它找回任务。
- `model` (string, 必填) 模型 ID，来自 listModels 或模型页。 至少 1 个字符
- `webhook_endpoint_id` (string, 可选) 任务状态变化时通知的 Webhook 端点，在控制台创建。

```json
{
  "model": "seedance-2-5",
  "input": {
    "content": [
      {
        "type": "text",
        "text": "A paper boat drifting on a pond"
      }
    ],
    "resolution": "720p",
    "duration": 5
  }
}
```

## 响应

### 202 Accepted

- `allowed_actions` (string[], 必填, 可为 null) 当前可以执行的操作，例如 cancel。以这个列表为准，不要根据状态自行推断。
- `billing_closed_at` (date-time, 可选) When the hold was settled or released; absent while Credits are still held.
- `billing_status` (string, 必填) Pending awaits funding; unfunded closed without a hold; held means Credits are held for the task; settled charges verified delivery at the existing pricing rules; released returns the hold after failure, cancellation, timeout or zero-charge delivery; refunded reverses previously consumed generation Credits. 可选值: `pending`, `unfunded`, `held`, `settled`, `released`, `refunded`
- `closed_at` (date-time, 必填, 可为 null) 任务关闭时间。不为空即可停止轮询。
- `created_at` (date-time, 必填) When the generation was accepted. Lists are ordered by this time, newest first.
- `customer_resolution_deadline` (date-time, 必填) 受理后 24 小时。到期仍未结算的冻结积分全部释放。
- `delivery_status` (string, 必填) Output delivery: pending before upstream success; copying into managed storage; ready after verified delivery; failed when delivery cannot complete. 可选值: `pending`, `copying`, `ready`, `failed`
- `error` (object, 必填, 可为 null) 任务未产出结果就关闭时才有值，读取 error.code。
  - `code` (string, 必填) Funding: insufficient_balance, balance_negative (Credits were owed when the task came to be funded), budget_exceeded or spending_blocked; recovery_review when recovery closes an unfunded task for manual reconciliation. Provider: provider_unavailable after capacity/recovery exhaustion; input/output_moderated for safety refusal; input_media_invalid or input_media_unreachable for media refusal; draft_expired for an expired draft; input_rejected for unsupported input; delivery_failed when the provider succeeded but the output could not be stored; generation_failed for other terminal provider failures. Failed tasks release their customer hold. 可选值: `insufficient_balance`, `balance_negative`, `budget_exceeded`, `spending_blocked`, `recovery_review`, `provider_unavailable`, `input_moderated`, `output_moderated`, `input_media_invalid`, `input_media_unreachable`, `draft_expired`, `input_rejected`, `delivery_failed`, `generation_failed`
- `execution_status` (string, 必填) Supplier execution state, separate from delivery and billing: processing until execution ends. Succeeded means upstream execution finished, not that output delivery is ready. 可选值: `processing`, `succeeded`, `failed`, `canceled`, `unresolved`
- `held_at` (date-time, 可选) When Credits were held for the task; absent while it awaits funding or when it closed unfunded.
- `id` (string, 必填) 资源 ID，收到后立即保存。
- `input` (any, 可选) The model input as accepted, after normalization, with media as sent: asset ids or your own URLs. Returned when reading a single task; list entries omit it.
- `key_id` (string, 可选) API key that created the task; empty for console tasks.
- `key_name` (string, 可选)
- `late_result_available` (boolean, 必填) 关闭后才到的结果，免费提供。
- `metadata` (map<string, string>, 可选) 你自己的字符串键值，原样返回。建议写入 client_reference，回包丢失时用它找回任务。
- `model` (string, 必填) Public model id the generation was created with.
- `price` (object, 必填) 这个任务的积分：estimated 是预估额，也就是冻结额，实际扣费按实际用量计算，可能与预估略有差异；reserved 是当前冻结的积分；charged 是按实际用量和固定费率扣的积分，结算前为 0.000；refunded 是退款退回的积分。
  - `charged` (string, 必填) Credits consumed by this task. Set when billing_status is settled: the actual usage the model reported at the fixed rate, which may be above or below estimated; any unused part of the hold returns to the balance, and usage above the hold is charged too. 0.000 in every other state, including after a refund.
  - `estimated` (string, 必填) The estimated cost of this task, in Credits, fixed when the task was accepted. This is the amount held for the task. The charge follows actual usage and may differ slightly from it, above or below.
  - `refunded` (string, 必填) Credits a refund returned to the balance: what this task had been charged. 0.000 unless billing_status is refunded.
  - `reserved` (string, 必填) Credits held for this task right now, as a decimal string with 3 places. Equal to estimated while billing_status is held, otherwise 0.000.
  - `unit` (string, 必填) Every amount is in Credits. 可选值: `credit`
- `queue_ms` (integer, 可选) Milliseconds from acceptance to first dispatch.
- `result` (object, 必填, 可为 null) 交付后的素材。
  - `asset_id` (string, 可选)
  - `last_frame_asset_id` (string, 可选)
  - `metadata` (object, 可选)
    - `duration` (integer, 可选)
    - `frames` (integer, 可选)
    - `framespersecond` (integer, 可选)
    - `generate_audio` (boolean, 可选)
    - `ratio` (string, 可选)
    - `resolution` (string, 可选)
    - `seed` (integer, 可选)
  - `outputs` (object[], 可选, 可为 null)
    - `asset_id` (string, 必填)
    - `content_type` (string, 必填)
    - `index` (integer, 必填)
  - `voice_id` (string, 可选)
- `run_ms` (integer, 可选) Milliseconds from first dispatch to close.
- `source` (string, 必填) Where the generation was created: api (API key) or console (signed-in session). 可选值: `api`, `console`
- `started_at` (date-time, 可选) When the task was first dispatched to run.
- `status` (string, 必填) processing from acceptance until the task closes, including while it awaits funding and while outputs are copied; succeeded has delivered outputs; failed, canceled and unresolved are closed. Canceled is set by the system only, for example when a task is not funded or not started in time. Unresolved closes after the resolution deadline. A late result may still arrive without a new charge. 可选值: `processing`, `succeeded`, `failed`, `canceled`, `unresolved`
- `version` (integer, 必填)

```json
{
  "allowed_actions": [],
  "billing_closed_at": "2026-11-02T08:00:00Z",
  "billing_status": "held",
  "closed_at": null,
  "created_at": "2026-11-02T08:01:43Z",
  "customer_resolution_deadline": "2026-11-03T08:00:12Z",
  "delivery_status": "pending",
  "error": null,
  "execution_status": "processing",
  "held_at": "2026-11-02T08:00:00Z",
  "id": "gen_01JD8Z5QW3XR",
  "input": {},
  "key_id": "string",
  "key_name": "string",
  "late_result_available": false,
  "metadata": {
    "client_reference": "order-1042"
  },
  "model": "MODEL_ID",
  "price": {
    "charged": "0.000",
    "estimated": "157.000",
    "refunded": "0.000",
    "reserved": "157.000",
    "unit": "credit"
  },
  "queue_ms": 1,
  "result": null,
  "run_ms": 1,
  "source": "api",
  "started_at": "2026-11-02T08:00:00Z",
  "status": "processing",
  "version": 1
}
```

### 401 Unauthorized

```json
{
  "error": {
    "code": "invalid_credentials",
    "message": "API key is missing, malformed, expired or revoked.",
    "retryable": false,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 402 Payment Required

```json
{
  "error": {
    "code": "insufficient_balance",
    "message": "Available credits cannot cover the hold.",
    "retryable": false,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 403 Forbidden

```json
{
  "error": {
    "code": "scope_denied",
    "message": "The key does not allow this operation for this project.",
    "retryable": false,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 404 Not Found

```json
{
  "error": {
    "code": "resource_not_found",
    "message": "The resource is not available to this project.",
    "retryable": false,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 409 Conflict

```json
{
  "error": {
    "code": "conflict",
    "message": "The request conflicts with the current state of the resource.",
    "retryable": false,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 422 Unprocessable Entity

```json
{
  "error": {
    "code": "invalid_input",
    "message": "Input does not match the published schema.",
    "retryable": false,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 429 Too many requests. Code concurrency_limited: the organization already has as many unfinished tasks of this media type as its concurrency limit allows, by default 3 video tasks at once per organization (see /docs/rate-limits); nothing is recorded or held. Code rate_limited: the per-minute rate or the queued-task backlog is full. Retry after Retry-After seconds.

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Check Retry-After.",
    "retryable": true,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 500 Internal Server Error

```json
{
  "error": {
    "code": "request_failed",
    "message": "The request failed. Check recent generations before submitting again.",
    "retryable": false,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

### 503 Service Unavailable

```json
{
  "error": {
    "code": "temporarily_unavailable",
    "message": "Service is temporarily unavailable.",
    "retryable": true,
    "request_id": "9f2c41d07ab3e5c8"
  }
}
```

## 错误

所有错误使用同一种响应体。联系支持时请附上 request_id。

### 错误响应体

- `error` (object, 必填) 错误详情。
  - `code` (string, 必填) Stable request error code. invalid_input rejects the request schema; invalid_credentials/scope_denied reject authentication/authorization; ip_not_allowed/model_not_allowed reject API key IP/model restrictions; resource_not_found hides missing or inaccessible resources; conflict rejects incompatible state; insufficient_balance/budget_exceeded/spending_blocked reject funding; balance_negative (402) refuses new tasks while the organization owes Credits from a charge above its hold, until a top-up repays them; rate_limited/concurrency_limited ask for a later retry; temporarily_unavailable is transient service capacity; request_failed covers other HTTP failures. tier_not_sold, draft_not_found, draft_expired and input_duration_out_of_range reject model-specific input. input_media_invalid rejects a detected format/type mismatch; input_media_too_large rejects a probed byte size above the model limit. storage_quota_exceeded rejects an upload when the organization's storage is full. See errors for field-level details. 可选值: `invalid_input`, `invalid_credentials`, `insufficient_balance`, `balance_negative`, `scope_denied`, `resource_not_found`, `conflict`, `rate_limited`, `concurrency_limited`, `temporarily_unavailable`, `request_failed`, `ip_not_allowed`, `model_not_allowed`, `tier_not_sold`, `draft_not_found`, `draft_expired`, `input_duration_out_of_range`, `input_media_invalid`, `input_media_too_large`, `budget_exceeded`, `spending_blocked`, `storage_quota_exceeded`
  - `errors` (object[], 可选, 可为 null)
    - `path` (string, 必填)
    - `rule` (string, 必填)
  - `message` (string, 必填) 可读的说明，不要解析它。
  - `request_id` (string, 必填) 联系支持时请附上。
  - `retryable` (boolean, 必填) 仅 429 和 503 为 true。即便如此，重发创建请求前也要先查看近期任务。
  - `task_id` (string, 可选) 错误所属的任务（如果有）。

| 状态码 | 含义与处理 |
| --- | --- |
| 401 | API Key 缺失、格式错误、已过期或已撤销。在服务端更正 API Key 后继续。 |
| 402 | 可用积分不足以支付这次请求。充值并等待到账后，再查询余额。 |
| 403 | API Key 权限、邮箱验证、预算上限或账户限制阻止了操作。检查 API Key 类型、权限和项目预算。 |
| 404 | 模型或资源不存在，或不在当前项目范围内。确认项目、ID 和模型是否已开通。 |
| 409 | 请求与当前状态冲突。重新读取资源，再决定是否重新发送。 |
| 422 | 字段或取值无效。对照字段表和模型页修改请求。 |
| 429 | 请求过于频繁，没有创建任务。等到 Retry-After 指定的时间后再发送。 |
| 500 | 服务端出错，任务可能已经受理。不要直接重发，先查看近期任务。 |
| 503 | 服务暂时不可用。创建请求要先查看近期任务，确认没有受理，再重新提交。 |
| 超时或断连 | 没有响应或连接中断，任务可能已经受理。有任务 ID 就查询原任务；没有就按 client_reference 在任务列表中找回。 |

### cURL

```bash
curl -X POST "https://api.vizoapi.com/v1/generations" \
  -H "Authorization: Bearer $VIZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2-5",
    "input": {
      "content": [
        {
          "type": "text",
          "text": "A paper boat drifting on a pond"
        }
      ],
      "resolution": "720p",
      "duration": 5
    }
  }'
```

### Python

```python
import os, requests

res = requests.post(
    "https://api.vizoapi.com/v1/generations",
    headers={"Authorization": f"Bearer {os.environ['VIZO_API_KEY']}"},
    json={
      "model": "seedance-2-5",
      "input": {
        "content": [
          {
            "type": "text",
            "text": "A paper boat drifting on a pond"
          }
        ],
        "resolution": "720p",
        "duration": 5
      }
    },
    timeout=60,
)
print(res.status_code, res.json())
```

### Node.js

```javascript
const res = await fetch("https://api.vizoapi.com/v1/generations", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.VIZO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "seedance-2-5",
    "input": {
      "content": [
        {
          "type": "text",
          "text": "A paper boat drifting on a pond"
        }
      ],
      "resolution": "720p",
      "duration": 5
    }
  }),
});
console.log(res.status, await res.json());
```
