# SkyReels 视频生成
> 文生视频、首尾帧、关键帧、主体与运动参考、视频延长
> 素材用 `@标签` 在提示词里引用，提示词就是脚本
> 支持拼图参考与声纹同步
`POST /v1/videos`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 请求参数
> **Note:** 
> 提交成功只返回任务 ID，不含视频本身。拿成片用 `task_id` 轮询[获取任务状态](../tasks/status.html)，成片地址在 `result.videos[0].url`，该地址约 24 小时后过期，请及时转存。
- `model` (string / 必填) — 取值 `skyreels-v4-fast` 或 `skyreels-v4-std`。 必须显式传，没有默认值。
- `prompt` (string / 必填) — 画面描述，最多 1280 token。 用到 `@标签` 时，标签必须同时出现在提示词里。
- `duration` (integer / 可选) — 时长，3 到 15 秒，默认 `5`。 带 `ref_videos` 且 `type` 为 `reference` 时，改用参考视频长度，上限 10 秒。
- `resolution` (string / 可选) — 取值 `480p`、`720p`、`1080p`，默认 `1080p`。1080p 成本远高于 480p 与 720p。
- `aspect_ratio` (string / 可选) — 取值 `16:9`、`4:3`、`1:1`、`9:16`、`3:4`，默认 `16:9`。 图生视频与带参考视频的多模态模式下不生效。
- `first_frame_image` (string / 可选) — 首帧地址，格式 jpg、jpeg、png、gif、bmp。
- `end_frame_image` (string / 可选) — 尾帧地址，可与 `first_frame_image` 配对。
- `mid_frame_images` (object[] / 可选) — 关键帧数组，最多 6 项，每项含 `tag`、`image_url`、`time_stamp`。 `tag` 必须以 `@` 开头；`time_stamp` 为 `-1` 或落在 0 到时长之间的开区间。
- `ref_images` (object[] / 可选) — 参考图数组，每项含 `tag`、`type`、`image_urls`、可选的 `audio_url`。 `type` 取值 `image` 或 `grid`。`image` 时 `image_urls` 为 1 到 3 组、每组 1 到 5 张；`grid` 时只有 1 组 1 张，用于拼图参考。`audio_url` 只在 `type` 为 `image` 时可用，音频不超过 15 秒。
- `ref_videos` (object[] / 可选) — 参考视频数组，最多 1 段，每项含 `tag`、`type`、`video_url`。 `type` 取值 `reference` 运动或主体参考、`extend` 视频延长。视频为 MP4 或 MOV，不超过 15 秒。
- `prompt_optimizer` (boolean / 可选) — 自动改写提示词，默认 `true`。
- `nsfw_check` (boolean / 可选) — 为 `true` 时先做内容审查，默认 `false`。
## 模式判定
只有提示词与通用字段是文生视频。
传 `first_frame_image`、`end_frame_image` 或 `mid_frame_images` 走图生视频，可分别控制首帧、尾帧与关键帧。
传 `ref_images` 或 `ref_videos` 走多模态参考，覆盖主体参考、拼图参考、运动参考、视频延长与声纹同步。
图生视频字段与多模态字段不能同时出现，混用返回 422，且不计费。
## 支持的模型列表
| 模型 ID | 定位 |
|---|---|
| `skyreels-v4-std` | 画质优先，适合关键镜头与成片交付，价格比 Fast 高约 25 到 30% |
| `skyreels-v4-fast` | 速度优先，适合快速预览与批量生成 |
## 使用限制
- `ref_images` 里所有元素的 `type` 必须一致
- `ref_videos` 最多 1 段
- 带参考视频时成本约为纯文本或纯图片输入的 1.5 到 2 倍
- 参数冲突返回 422，不计费
- 目前不能同时输出音频与视频
## 响应
提交成功返回统一的受理结构：
```json
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
- `code` (integer / 总是返回) — 状态码，`200` 表示任务已受理。
- `data` (array / 总是返回) — 本次提交的任务列表，逐项提交时按顺序排列。
- `data[].status` (string / 总是返回) — 受理状态，提交成功时为 `submitted`。
- `data[].task_id` (string / 总是返回) — 任务 ID，用它轮询结果。
## 错误
| HTTP | type | 说明 |
|---|---|---|
| 400 | invalid_request_error | 请求参数无效，或参数组合冲突 |
| 401 | authentication_error | 身份验证失败，需检查 API Key |
| 402 | payment_required | 账户余额不足，需先充值 |
| 429 | rate_limit_error | 调用频率过高，稍后重试 |
参数错误在提交阶段同步返回，不创建任务、不扣费。
参数冲突或取值非法时返回 422，同样不计费。
更多状态码与重试建议见[错误码与限流](../../support/errors.html)，常见报错的排查步骤见[常见问题](../../support/faq.html)。
## 查询任务
`GET /v1/tasks/{task_id}` 返回任务进度与结果，`status` 为 `completed` 时成片地址在 `result.videos[0].url`，元素带 `expires_at` 过期时间戳。
建议每 5 到 10 秒轮询一次，客户端总超时设为 10 到 15 分钟。`status` 取值 `pending`、`processing`、`completed`、`failed`、`cancelled`，以状态判定完成，不要依赖 `progress`。
失败任务自动退回费用，`error.message` 给出原因。
**文生视频{Text to video}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "skyreels-v4-std",
  "prompt": "清晨的竹林，薄雾流动，镜头缓慢穿行",
  "duration": 8,
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}'
```
**文生视频{Text to video}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "skyreels-v4-std",
  "prompt": "清晨的竹林，薄雾流动，镜头缓慢穿行",
  "duration": 8,
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**文生视频{Text to video}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "skyreels-v4-std",
  "prompt": "清晨的竹林，薄雾流动，镜头缓慢穿行",
  "duration": 8,
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}),
});
console.log(await res.json());
```
**200 文生视频{Text to video}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**首尾帧{First and last frame}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "skyreels-v4-std",
  "prompt": "季节从春转到冬",
  "first_frame_image": "https://example.com/spring.jpg",
  "end_frame_image": "https://example.com/winter.jpg",
  "duration": 8
}'
```
**首尾帧{First and last frame}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "skyreels-v4-std",
  "prompt": "季节从春转到冬",
  "first_frame_image": "https://example.com/spring.jpg",
  "end_frame_image": "https://example.com/winter.jpg",
  "duration": 8
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**首尾帧{First and last frame}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "skyreels-v4-std",
  "prompt": "季节从春转到冬",
  "first_frame_image": "https://example.com/spring.jpg",
  "end_frame_image": "https://example.com/winter.jpg",
  "duration": 8
}),
});
console.log(await res.json());
```
**200 首尾帧{First and last frame}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**关键帧{Keyframes}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "skyreels-v4-std",
  "prompt": "镜头依次经过 @mid1 与 @mid2 两个画面",
  "first_frame_image": "https://example.com/start.jpg",
  "mid_frame_images": [
    {
      "tag": "@mid1",
      "image_url": "https://example.com/m1.jpg",
      "time_stamp": 2
    },
    {
      "tag": "@mid2",
      "image_url": "https://example.com/m2.jpg",
      "time_stamp": 5
    }
  ],
  "duration": 8
}'
```
**关键帧{Keyframes}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "skyreels-v4-std",
  "prompt": "镜头依次经过 @mid1 与 @mid2 两个画面",
  "first_frame_image": "https://example.com/start.jpg",
  "mid_frame_images": [
    {
      "tag": "@mid1",
      "image_url": "https://example.com/m1.jpg",
      "time_stamp": 2
    },
    {
      "tag": "@mid2",
      "image_url": "https://example.com/m2.jpg",
      "time_stamp": 5
    }
  ],
  "duration": 8
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**关键帧{Keyframes}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "skyreels-v4-std",
  "prompt": "镜头依次经过 @mid1 与 @mid2 两个画面",
  "first_frame_image": "https://example.com/start.jpg",
  "mid_frame_images": [
    {
      "tag": "@mid1",
      "image_url": "https://example.com/m1.jpg",
      "time_stamp": 2
    },
    {
      "tag": "@mid2",
      "image_url": "https://example.com/m2.jpg",
      "time_stamp": 5
    }
  ],
  "duration": 8
}),
});
console.log(await res.json());
```
**200 关键帧{Keyframes}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**主体参考{Subject reference}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "skyreels-v4-std",
  "prompt": "@hero 在雨夜街道上奔跑",
  "ref_images": [
    {
      "tag": "@hero",
      "type": "image",
      "image_urls": [
        [
          "https://example.com/hero.png"
        ]
      ]
    }
  ],
  "duration": 8
}'
```
**主体参考{Subject reference}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "skyreels-v4-std",
  "prompt": "@hero 在雨夜街道上奔跑",
  "ref_images": [
    {
      "tag": "@hero",
      "type": "image",
      "image_urls": [
        [
          "https://example.com/hero.png"
        ]
      ]
    }
  ],
  "duration": 8
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**主体参考{Subject reference}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "skyreels-v4-std",
  "prompt": "@hero 在雨夜街道上奔跑",
  "ref_images": [
    {
      "tag": "@hero",
      "type": "image",
      "image_urls": [
        [
          "https://example.com/hero.png"
        ]
      ]
    }
  ],
  "duration": 8
}),
});
console.log(await res.json());
```
**200 主体参考{Subject reference}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**视频延长{Extend video}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "skyreels-v4-std",
  "prompt": "镜头继续向前推进",
  "ref_videos": [
    {
      "tag": "@base",
      "type": "extend",
      "video_url": "https://example.com/source.mp4"
    }
  ],
  "duration": 8
}'
```
**视频延长{Extend video}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "skyreels-v4-std",
  "prompt": "镜头继续向前推进",
  "ref_videos": [
    {
      "tag": "@base",
      "type": "extend",
      "video_url": "https://example.com/source.mp4"
    }
  ],
  "duration": 8
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**视频延长{Extend video}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "skyreels-v4-std",
  "prompt": "镜头继续向前推进",
  "ref_videos": [
    {
      "tag": "@base",
      "type": "extend",
      "video_url": "https://example.com/source.mp4"
    }
  ],
  "duration": 8
}),
});
console.log(await res.json());
```
**200 视频延长{Extend video}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
