跳转到主要内容
POST
/
v1
/
videos
文生视频:根据文本提示词生成视频任务
curl --request POST \
  --url https://api.apiyi.com/v1/videos \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "model": "veo-3.1-fast-generate-preview",
  "prompt": "黄昏海边的灯塔,镜头缓慢推进,海浪轻拍礁石,海鸟叫声,电影级光影,稳定运镜"
}
'
{
  "id": "task_xxxxxxxxxxxxxxxx",
  "task_id": "task_xxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "queued",
  "progress": 0,
  "created_at": 1775025000,
  "completed_at": 1775025090
}

Documentation Index

Fetch the complete documentation index at: https://docs.apiyi.com/llms.txt

Use this file to discover all available pages before exploring further.

右侧的交互式 Playground 支持直接在线调试。请在 Authorization 中填入你的 API Key(格式:Bearer sk-xxx),输入 prompt、选择 model / duration / metadata.resolution 后一键发送即可。默认分组 Default 即可调用,无需切换专属分组
场景说明:本页用于「纯文本提示词生成视频」——不传 input_reference、走 application/json 请求体。如需基于一张参考图生成视频(图生视频),请使用 图生视频接口(同一端点 + input_reference 文件上传)。
⚠️ 三处最容易踩的坑
  1. duration 必须传字符串 "4" / "6" / "8",传数字会被服务端拒,报 parse_request_failed: cannot unmarshal number into Go struct field ... duration of type string
  2. 不要传 generateAudio 参数,上游会回 INVALID_ARGUMENT。音频效果(环境音、对白、BGM)直接写进 prompt
  3. 1080p / 4k 分辨率时 duration 必须 "8",传 "4" / "6" 会被上游拒
三步异步流程,本页只覆盖第一步(提交)
  • 第 1 步(本页)POST /v1/videos → 返回 task_id + status: "queued"
  • 第 2 步GET /v1/videos/{task_id} 轮询,直到 status: "completed"
  • 第 3 步GET /v1/videos/{task_id}/content 下载 MP4 文件
POST 提交本身耗时秒级,不会等到视频生成完成。完整流程见下方 Python 代码示例。

代码示例

Python(OpenAI SDK 风格 · 推荐 client.post 底层调用)

{/* OpenAI 官方 SDK 没有 videos.create 方法,/v1/videos 是自定义路径,需用底层 client.post() */}
from openai import OpenAI
import time

client = OpenAI(
    api_key="sk-your-api-key",
    base_url="https://api.apiyi.com/v1"
)

# 第 1 步:提交生成任务
resp = client.post(
    "/videos",
    body={
        "model": "veo-3.1-fast-generate-preview",
        "prompt": "黄昏海边的灯塔,镜头缓慢推进,海浪轻拍礁石,海鸟叫声,电影级光影,稳定运镜",
        "duration": "8",  # 必须字符串
        "size": "1280x720",
        "metadata": {
            "resolution": "720p",
            "aspectRatio": "16:9",
            "seed": 20260521,
            "negativePrompt": "blurry, watermark, distorted, low quality"
        }
    },
    cast_to=dict
)
task_id = resp["task_id"]
print(f"Task ID: {task_id}, status: {resp['status']}")

# 第 2 步:轮询状态(最长等 3 分钟)
deadline = time.time() + 180
while time.time() < deadline:
    status_resp = client.get(f"/videos/{task_id}", cast_to=dict)
    print(f"Status: {status_resp['status']}, progress: {status_resp.get('progress', 0)}%")
    if status_resp["status"] == "completed":
        break
    if status_resp["status"] == "failed":
        raise RuntimeError(f"Generation failed: {status_resp}")
    time.sleep(8)

# 第 3 步:下载视频(status 刚翻 completed 偶发 400,等几秒重试)
import urllib.request, urllib.error
for i in range(5):
    try:
        req = urllib.request.Request(
            f"https://api.apiyi.com/v1/videos/{task_id}/content",
            headers={"Authorization": "Bearer sk-your-api-key"}
        )
        with urllib.request.urlopen(req, timeout=180) as r, open("output.mp4", "wb") as f:
            while chunk := r.read(1 << 16):
                f.write(chunk)
        break
    except urllib.error.HTTPError as e:
        if i == 4:
            raise
        time.sleep(4)
print("Saved: output.mp4")

Python(原生 requests)

import requests
import time

API_KEY = "sk-your-api-key"
BASE_URL = "https://api.apiyi.com/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 第 1 步:提交(JSON 请求体)
resp = requests.post(
    f"{BASE_URL}/videos",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "model": "veo-3.1-fast-generate-preview",
        "prompt": "傍晚海边的灯塔,镜头缓慢推进,稳定运镜,海浪声、远处海鸟叫声",
        "duration": "8",  # ⚠️ 必须字符串
        "size": "1280x720",
        "metadata": {
            "resolution": "720p",
            "aspectRatio": "16:9"
        }
    },
    timeout=30  # POST 提交本身只是入队,30 秒足够
).json()
task_id = resp["task_id"]
print(f"Task ID: {task_id}, status: {resp['status']}")

# 第 2 步:轮询(最长等 3 分钟,4K 用 10 分钟)
deadline = time.time() + 180
while time.time() < deadline:
    status_resp = requests.get(f"{BASE_URL}/videos/{task_id}", headers=HEADERS).json()
    print(f"Status: {status_resp['status']}, progress: {status_resp.get('progress', 0)}%")
    if status_resp["status"] == "completed":
        break
    if status_resp["status"] == "failed":
        raise RuntimeError(f"Generation failed: {status_resp}")
    time.sleep(8)

# 第 3 步:下载(带 3 次重试兜底 status=completed 后的 CDN 同步延迟)
for i in range(5):
    try:
        with requests.get(
            f"{BASE_URL}/videos/{task_id}/content",
            headers=HEADERS, stream=True, timeout=180
        ) as r:
            r.raise_for_status()
            with open("output.mp4", "wb") as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        break
    except requests.HTTPError:
        if i == 4:
            raise
        time.sleep(4)
print("Saved: output.mp4")

cURL

{/* 1 步:提交任务(注意 duration 是字符串 "8",不是数字 8)*/}
RESP=$(curl -sS -X POST "https://api.apiyi.com/v1/videos" \
  -H "Authorization: Bearer sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1-fast-generate-preview",
    "prompt": "黄昏海边的灯塔,镜头缓慢推进,海浪声,电影级光影",
    "duration": "8",
    "size": "1280x720",
    "metadata": {"resolution": "720p", "aspectRatio": "16:9"}
  }')
TASK_ID=$(echo "$RESP" | python3 -c 'import sys,json;print(json.load(sys.stdin)["task_id"])')
echo "task_id=$TASK_ID"

{/* 2 步:轮询状态(每 8 秒)*/}
while :; do
  S=$(curl -sS -H "Authorization: Bearer sk-your-api-key" "https://api.apiyi.com/v1/videos/$TASK_ID")
  ST=$(echo "$S" | python3 -c 'import sys,json;print(json.load(sys.stdin)["status"])')
  echo "status=$ST"
  [ "$ST" = "completed" ] && break
  [ "$ST" = "failed" ] && { echo "$S"; exit 1; }
  sleep 8
done

{/* 3 步:下载视频文件(--retry 兜底 status 刚翻 completed 后的偶发 400)*/}
sleep 4
curl -sSL --retry 3 --retry-delay 4 \
  -H "Authorization: Bearer sk-your-api-key" \
  "https://api.apiyi.com/v1/videos/$TASK_ID/content" \
  -o output.mp4
ls -lh output.mp4

Node.js(原生 fetch)

import fs from 'node:fs';

const API_KEY = 'sk-your-api-key';
const BASE_URL = 'https://api.apiyi.com/v1';

// 第 1 步:提交
const submitResp = await fetch(`${BASE_URL}/videos`, {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${API_KEY}`
    },
    body: JSON.stringify({
        model: 'veo-3.1-fast-generate-preview',
        prompt: '一只柯基犬在金色沙滩上奔跑,慢动作,黄昏时分,电影质感',
        duration: '8',  // ⚠️ 必须字符串
        size: '1280x720',
        metadata: {
            resolution: '720p',
            aspectRatio: '16:9'
        }
    })
});
const { task_id } = await submitResp.json();
console.log(`Task ID: ${task_id}`);

// 第 2 步:轮询
let status = 'queued';
while (status !== 'completed' && status !== 'failed') {
    await new Promise(r => setTimeout(r, 8000));
    const statusResp = await fetch(`${BASE_URL}/videos/${task_id}`, {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
    });
    const data = await statusResp.json();
    status = data.status;
    console.log(`Status: ${status}, progress: ${data.progress ?? 0}%`);
}

if (status === 'failed') throw new Error('Generation failed');

// 第 3 步:下载(最多重试 3 次,每次间隔 4 秒)
await new Promise(r => setTimeout(r, 4000));
let buffer;
for (let i = 0; i < 4; i++) {
    try {
        const contentResp = await fetch(`${BASE_URL}/videos/${task_id}/content`, {
            headers: { 'Authorization': `Bearer ${API_KEY}` }
        });
        if (!contentResp.ok) throw new Error(`HTTP ${contentResp.status}`);
        buffer = Buffer.from(await contentResp.arrayBuffer());
        break;
    } catch (e) {
        if (i === 3) throw e;
        await new Promise(r => setTimeout(r, 4000));
    }
}
fs.writeFileSync('output.mp4', buffer);
console.log('Saved: output.mp4');

浏览器 JavaScript

{/* 仅作演示,生产请走后端代理避免 Key 泄露;视频文件较大也不适合直接在浏览器下载 */}
const submitResp = await fetch('https://api.apiyi.com/v1/videos', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer sk-your-api-key'
    },
    body: JSON.stringify({
        model: 'veo-3.1-fast-generate-preview',
        prompt: '水彩风格的极光在雪山上空缓缓流动,柔和镜头',
        duration: '4',
        size: '720x1280',
        metadata: { resolution: '720p', aspectRatio: '9:16' }
    })
});
const { task_id } = await submitResp.json();
console.log('Task ID:', task_id);

{/* 轮询完成后,把 /content 端点交给后端代理下载,再回流给前端展示 */}

参数说明速查

参数类型必填默认说明
modelstringveo-3.1-fast-generate-preview($0.3/次)或 veo-3.1-generate-preview($1.2/次)
promptstring视频描述提示词,建议详细描述场景、镜头运动、风格、光线、音频意图(不要传 generateAudio
durationstring"8"视频时长,字符串枚举"4" / "6" / "8"1080p/4k 必须 "8"
sizestring1280x720输出像素,如 1280x720 / 1920x1080 / 3840x2160,优先级低于 metadata.resolution
metadata.resolutionstring720p720p / 1080p / 4k,优先级高于 size
metadata.aspectRatiostring16:916:9(横屏)或 9:16(竖屏)
metadata.seedint随机数种子,固定 seed 可让多次输出风格聚集(但不能字节级复现
metadata.negativePromptstring反向提示词,推荐传 "blurry, watermark, distorted, low quality"
不要传 generateAudio 字段!Veo 3.1 原生带音轨,传该参数会被上游回 INVALID_ARGUMENT。要控制音频,把意图写进 prompt"海浪声、远处海鸟叫声、低沉的风声"
参数识别优先级:
  • 秒数:metadata.durationSeconds > duration > seconds > 8
  • 分辨率:metadata.resolution > size > 720p
  • 比例:显式 metadata.aspectRatio > 由 size 推导 > 16:9

响应格式

第 1 步 - 提交后立即返回

{
  "id": "task_xxxxxxxxxxxxxxxx",
  "task_id": "task_xxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "queued",
  "progress": 0,
  "created_at": 1775025000
}

第 2 步 - 轮询返回(生成中)

{
  "id": "task_xxxxxxxxxxxxxxxx",
  "task_id": "task_xxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "in_progress",
  "progress": 50,
  "created_at": 1775025000
}

第 2 步 - 轮询返回(完成)

{
  "id": "task_xxxxxxxxxxxxxxxx",
  "task_id": "task_xxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "completed",
  "progress": 100,
  "created_at": 1775025000,
  "completed_at": 1775025090
}
⚠️ 响应字段陷阱
  • idtask_id 字段同时返回且值一致,下游建议统一用 task_id(与既有 VEO 官逆兼容)
  • 没有任何 CDN / 公网 URL 返回——响应字段里没有 video_url / data.url,视频只能通过 GET /v1/videos/{task_id}/content 拉取 MP4 二进制流(需鉴权头)。前端不能直连此端点,建议后端下载后落地到自己的 OSS / CDN 再分发
  • progress 字段是粗粒度,只在 0 / 50 / 100 三档跳,不要拿来做百分比进度条
  • status: "failed" 时上游有时不带详细 error 字段,多见于内容审核或参数错误,直接重试或调整 prompt 即可
  • /content 端点在 status 刚翻 completed 后偶发 400,等 4 秒重试即可(上面所有代码示例都内置了重试)
本端点是异步任务式入口,计费在任务进入 completed 时按模型名按次结算(fast $0.3 / standard $1.2,见 概览页定价表)。POST 提交、轮询查询、视频下载本身不计费,失败任务也不计费

授权

Authorization
string
header
必填

在 API易控制台获取的 API Key(默认分组 + 任意计费模式都能调通)

请求体

application/json
model
enum<string>
默认值:veo-3.1-fast-generate-preview
必填

模型 ID(按次计费,时长 / 分辨率不影响单价):

  • veo-3.1-fast-generate-preview —— $0.3/次,试水 / 批量出片首选
  • veo-3.1-generate-preview —— $1.2/次,最终交付 / 4K 高清场景
可用选项:
veo-3.1-fast-generate-preview,
veo-3.1-generate-preview
prompt
string
必填

视频生成提示词,建议详细描述:场景 + 主体 + 动作 + 镜头 + 光影 + 风格。

音频意图也写进 prompt(如 "海浪声、远处海鸟叫声、低沉的风声"),不要传 generateAudio 参数——上游会拒 INVALID_ARGUMENT

示例:

"黄昏海边的灯塔,镜头缓慢推进,海浪轻拍礁石,海鸟叫声,电影级光影,稳定运镜"

duration
enum<string>
默认值:8

视频时长,字符串枚举(不是数字):

  • "4" —— 4 秒,720p 可用
  • "6" —— 6 秒,720p 可用
  • "8" —— 8 秒(默认),1080p / 4k 必须用这档

传数字(8)会报 parse_request_failed: cannot unmarshal number into Go struct field ... duration of type string

可用选项:
4,
6,
8
size
enum<string>
默认值:1280x720

输出像素,优先级低于 metadata.resolution

  • 1280x720 / 720x1280 —— 720p(默认)
  • 1920x1080 / 1080x1920 —— 1080p(duration 必须 "8"
  • 3840x2160 / 2160x3840 —— 4k(duration 必须 "8",渲染慢 4–6 倍)
可用选项:
1280x720,
720x1280,
1920x1080,
1080x1920,
3840x2160,
2160x3840
metadata
object

生成参数细节包装对象。优先级高于顶层的 size 等字段

  • 秒数识别顺序:metadata.durationSeconds > duration > seconds > 8
  • 分辨率识别顺序:metadata.resolution > size > 720p

响应

任务已提交,返回 task_id 与 queued 状态

id
string

任务 ID(与 task_id 同值,下游建议统一用 task_id

示例:

"task_xxxxxxxxxxxxxxxx"

task_id
string

任务 ID,用于后续轮询和下载

示例:

"task_xxxxxxxxxxxxxxxx"

object
string

对象类型,固定 video

示例:

"video"

model
string

本次任务使用的模型 ID

示例:

"veo-3.1-fast-generate-preview"

status
enum<string>

任务状态:

  • queued —— 已提交,排队等待
  • in_progress —— 正在生成
  • completed —— 完成,可下载(/v1/videos/{task_id}/content
  • failed —— 失败(不计费),可重试
可用选项:
queued,
in_progress,
completed,
failed
示例:

"queued"

progress
integer

生成进度(粗粒度,只在 0 / 50 / 100 三档跳,不要拿来做百分比进度条)

示例:

0

created_at
integer

任务创建 Unix 时间戳(秒)

示例:

1775025000

completed_at
integer

任务完成 Unix 时间戳(秒),仅 completed 状态返回

示例:

1775025090