curl --request POST \
--url https://api.apiyi.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=veo-3.1-fast-generate-preview \
--form 'prompt=镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音' \
--form input_reference='@example-file'import requests
url = "https://api.apiyi.com/v1/videos"
files = { "input_reference": ("example-file", open("example-file", "rb")) }
payload = {
"model": "veo-3.1-fast-generate-preview",
"prompt": "镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'veo-3.1-fast-generate-preview');
form.append('prompt', '镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音');
form.append('input_reference', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.apiyi.com/v1/videos', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.apiyi.com/v1/videos",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.apiyi.com/v1/videos"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.apiyi.com/v1/videos")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apiyi.com/v1/videos")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"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
}VEO 3.1 Official 圖生影片 API 參考
VEO 3.1 Official 圖生影片 API 參考與線上除錯 — multipart 上傳 input_reference 單張參考圖,讓靜態畫面動起來。
curl --request POST \
--url https://api.apiyi.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form model=veo-3.1-fast-generate-preview \
--form 'prompt=镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音' \
--form input_reference='@example-file'import requests
url = "https://api.apiyi.com/v1/videos"
files = { "input_reference": ("example-file", open("example-file", "rb")) }
payload = {
"model": "veo-3.1-fast-generate-preview",
"prompt": "镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('model', 'veo-3.1-fast-generate-preview');
form.append('prompt', '镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音');
form.append('input_reference', '{
"fileName": "example-file"
}');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.apiyi.com/v1/videos', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.apiyi.com/v1/videos",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.apiyi.com/v1/videos"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.apiyi.com/v1/videos")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.apiyi.com/v1/videos")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nveo-3.1-fast-generate-preview\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\n镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"input_reference\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n{\r\n \"fileName\": \"example-file\"\r\n}\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"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
}Bearer sk-xxx),上傳一張參考圖、輸入 prompt、選擇 model / seconds / resolution 後一鍵傳送即可。預設分組 Default 即可呼叫,無需切換專屬分組。- Content-Type 必須是
multipart/form-data(不是 JSON) - 僅支援 1 張參考圖,欄位名固定
input_reference,傳多張只取第一張 - 不接受遠端 URL,必須是檔案上傳或 Base64
- 接受格式:
image/jpeg/image/png/image/webp - 時長欄位名是
seconds(不是duration),且必須傳字串"4"/"6"/"8"。寫成duration會被靜默忽略、回落預設 4 秒;傳數字會被拒 - 1080p / 4k 時
seconds必須"8"
-fl 系列模型。程式碼示例
Python(OpenAI SDK 風格 · 推薦 client.post 底層呼叫)
{/* OpenAI 官方 SDK 沒有 videos.create 方法,/v1/videos 是自定義路徑,需用底層 client.post() */}
from openai import OpenAI
import time, mimetypes
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api.apiyi.com/v1"
)
# 第 1 步:multipart 上傳(OpenAI SDK 底層 client.post 自動處理 multipart 邊界)
with open("./lighthouse.png", "rb") as f:
resp = client.post(
"/videos",
body=None,
files={
"input_reference": ("lighthouse.png", f, "image/png")
},
extra_body={
"model": "veo-3.1-fast-generate-preview",
"prompt": "鏡頭從燈塔基座緩慢上升至塔頂,黃昏光線,海浪聲",
"seconds": "8", # ⚠️ 必須字串
"size": "1280x720",
"resolution": "720p",
"aspectRatio": "16:9"
},
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 步:下載(帶重試兜底)
import urllib.request, urllib.error
time.sleep(4)
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 + multipart)
import requests
import time
API_KEY = "sk-your-api-key"
BASE_URL = "https://api.apiyi.com/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 第 1 步:multipart 上傳參考圖 + 表單欄位
with open("./lighthouse.png", "rb") as f:
resp = requests.post(
f"{BASE_URL}/videos",
headers=HEADERS, # 不要手動加 Content-Type,requests 會自動處理 multipart 邊界
data={
"model": "veo-3.1-fast-generate-preview",
"prompt": "鏡頭從燈塔基座緩慢上升至塔頂,黃昏光線,海浪輕拍礁石的聲音",
"seconds": "8", # ⚠️ 字串,不是數字
"size": "1280x720",
"resolution": "720p",
"aspectRatio": "16:9",
"seed": "20260521"
},
files={
"input_reference": ("lighthouse.png", f, "image/png")
},
timeout=60 # multipart 上傳大圖可能慢,超時建議 60 秒
).json()
task_id = resp["task_id"]
print(f"Task ID: {task_id}")
# 第 2 步:輪詢
deadline = time.time() + 180
while time.time() < deadline:
s = requests.get(f"{BASE_URL}/videos/{task_id}", headers=HEADERS).json()
print(f"Status: {s['status']}, progress: {s.get('progress', 0)}%")
if s["status"] == "completed":
break
if s["status"] == "failed":
raise RuntimeError(s)
time.sleep(8)
# 第 3 步:下載(帶 3 次重試)
time.sleep(4)
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(multipart 上傳)
{/* 只想用已有 task_id 查詢/下載?見下方「已有 task_id?兩條 cURL 直接查狀態 / 下載」章節 */}
{/* 第 1 步:multipart 上傳(注意 -F 欄位順序,input_reference 用 @ 引用本地檔案)*/}
RESP=$(curl -sS -X POST "https://api.apiyi.com/v1/videos" \
-H "Authorization: Bearer sk-your-api-key" \
-F "model=veo-3.1-fast-generate-preview" \
-F "prompt=鏡頭從燈塔基座緩慢上升至塔頂,黃昏光線" \
-F "seconds=8" \
-F "size=1280x720" \
-F "resolution=720p" \
-F "aspectRatio=16:9" \
-F "input_reference=@./lighthouse.png;type=image/png")
TASK_ID=$(echo "$RESP" | python3 -c 'import sys,json;print(json.load(sys.stdin)["task_id"])')
echo "task_id=$TASK_ID"
{/* 第 2 步:輪詢狀態 */}
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 + FormData)
import fs from 'node:fs';
import { FormData, File } from 'undici';
const API_KEY = 'sk-your-api-key';
const BASE_URL = 'https://api.apiyi.com/v1';
// 第 1 步:multipart 上傳
const buffer = fs.readFileSync('./lighthouse.png');
const form = new FormData();
form.append('model', 'veo-3.1-fast-generate-preview');
form.append('prompt', '鏡頭從燈塔基座緩慢上升至塔頂,黃昏光線');
form.append('seconds', '8'); // ⚠️ 字串
form.append('size', '1280x720');
form.append('resolution', '720p');
form.append('aspectRatio', '16:9');
form.append('input_reference', new File([buffer], 'lighthouse.png', { type: 'image/png' }));
const submitResp = await fetch(`${BASE_URL}/videos`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${API_KEY}` }, // 不要手動加 Content-Type
body: form
});
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 s = await (await fetch(`${BASE_URL}/videos/${task_id}`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
})).json();
status = s.status;
console.log(`Status: ${status}, progress: ${s.progress ?? 0}%`);
}
if (status === 'failed') throw new Error('Generation failed');
// 第 3 步:下載(帶重試)
await new Promise(r => setTimeout(r, 4000));
let videoBuffer;
for (let i = 0; i < 4; i++) {
try {
const resp = await fetch(`${BASE_URL}/videos/${task_id}/content`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
videoBuffer = Buffer.from(await resp.arrayBuffer());
break;
} catch (e) {
if (i === 3) throw e;
await new Promise(r => setTimeout(r, 4000));
}
}
fs.writeFileSync('output.mp4', videoBuffer);
console.log('Saved: output.mp4');
瀏覽器 JavaScript(FileInput 上傳)
{/* 僅作演示,生產請走後端代理避免 Key 洩露;影片檔案較大也不適合直接在瀏覽器下載 */}
const fileInput = document.querySelector('input[type=file]');
const file = fileInput.files[0];
const form = new FormData();
form.append('model', 'veo-3.1-fast-generate-preview');
form.append('prompt', '讓這張靜態畫面動起來,緩慢推鏡,自然環境音');
form.append('seconds', '4');
form.append('size', '720x1280');
form.append('resolution', '720p');
form.append('aspectRatio', '9:16');
form.append('input_reference', file);
const submitResp = await fetch('https://api.apiyi.com/v1/videos', {
method: 'POST',
headers: { 'Authorization': 'Bearer sk-your-api-key' },
body: form
});
const { task_id } = await submitResp.json();
console.log('Task ID:', task_id);
{/* 輪詢完成後,把 /content 端點交給後端代理下載,再回流給前端展示 */}
已有 task_id?兩條 cURL 直接查狀態 / 下載
如果你已經拿到task_id(提交任務時返回,或在控制台日誌中檢視),只需替換下面命令裡的兩處即可直接使用:
sk-your-api-key→ 你的 API易 Keytask_xxxxxxxxxxxxxxxx→ 你的任務 ID
1. 查詢任務狀態
curl "https://api.apiyi.com/v1/videos/task_xxxxxxxxxxxxxxxx" \
-H "Authorization: Bearer sk-your-api-key"
status 為 completed 即可進行下載;in_progress 則稍等幾秒再查一次。
2. 下載影片(儲存為 output.mp4)
curl -L --retry 3 --retry-delay 4 \
"https://api.apiyi.com/v1/videos/task_xxxxxxxxxxxxxxxx/content" \
-H "Authorization: Bearer sk-your-api-key" \
-o output.mp4
/content 端點必須帶 Authorization 請求頭——直接在瀏覽器位址列開啟會返回 401。--retry 3 用於兜底 status 剛翻 completed 後偶發的 400(CDN 同步延遲)。引數說明速查
| 引數 | 型別 | 必填 | 預設 | 說明 |
|---|---|---|---|---|
input_reference | file | 是 | — | 參考圖檔案,欄位名固定,僅 1 張,接受 image/jpeg / image/png / image/webp,不接受遠端 URL |
model | string | 是 | — | veo-3.1-fast-generate-preview($0.3/次)或 veo-3.1-generate-preview($1.2/次) |
prompt | string | 是 | — | 描述影片動作 / 鏡頭 / 風格的提示詞。不要傳 generateAudio,音訊意圖寫進 prompt |
seconds | string | 否 | "8" | "4" / "6" / "8"。欄位名是 seconds 不是 duration(寫 duration 會被靜默忽略、回落 4 秒)。1080p/4k 必須 "8" |
size | string | 否 | 1280x720 | 輸出畫素 |
resolution | string | 否 | 720p | 720p / 1080p / 4k |
aspectRatio | string | 否 | 16:9 | 16:9(橫)/ 9:16(豎) |
seed | int | 否 | — | 隨機數種子(multipart 表單欄位,傳字串數字也可) |
- JSON 模式下巢狀在
metadata.*下(如metadata.resolution) - multipart 模式下平鋪為表單欄位(直接
resolution/aspectRatio/seed) - 上面的程式碼示例已經按 multipart 約定寫法
- 把
input_reference當作 Base64 字串塞進 JSON body —— 必須走 multipart 檔案欄位 - 欄位名寫成
image/reference/input_image—— 必須正好input_reference - 同時傳 2 張圖 —— 服務端只取第一張,第二張被靜默丟棄
- 傳遠端 URL(如
https://cdn.../img.png)—— 不接受,必須檔案或 Base64
響應格式
響應結構與 文生影片 完全一致:第 1 步返回task_id + status: "queued",第 2 步輪詢返回 status + 粗粒度 progress,第 3 步從 /content 端點下載 MP4 二進位制。
{
"id": "task_xxxxxxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxxxxxx",
"object": "video",
"model": "veo-3.1-fast-generate-preview",
"status": "queued",
"progress": 0,
"created_at": 1775025000
}
task_id與id同值,下游建議統一用task_id- 沒有直接的
video_url欄位,影片從GET /v1/videos/{task_id}/content下載 progress只在 0 / 50 / 100 三檔跳,不是線性進度/content端點在status剛翻completed後偶發 400,等 4 秒重試即可- 圖生影片任務通常比同參數文生影片慢 10-30%(多了一次影像編碼)
completed 時按模型名按次結算(與是否傳 input_reference 無關,fast $0.3 / standard $1.2)。POST 提交、輪詢查詢、影片下載本身不計費,失敗任務也不計費。授權
在 API易控制台获取的 API Key(默认分组 + 任意计费模式都能调通)
主體
模型 ID(按次计费):
veo-3.1-fast-generate-preview—— $0.3/次veo-3.1-generate-preview—— $1.2/次
veo-3.1-fast-generate-preview, veo-3.1-generate-preview 视频生成提示词。重点描述如何让画面动起来:镜头运动、物体动作、光线变化、音频氛围。不要传 generateAudio,音频写进 prompt。
"镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音"
参考图文件。字段名固定 input_reference,仅支持 1 张。
接受格式:image/jpeg / image/png / image/webp。不接受远程 URL,需要文件上传或 Base64。
视频时长,字段名是 seconds(不是 duration),字符串枚举:"4" / "6" / "8"。写成 duration 会被静默忽略、回落默认 4 秒。1080p / 4k 时必须 "8"。
4, 6, 8 输出像素,优先级低于 resolution
1280x720, 720x1280, 1920x1080, 1080x1920, 3840x2160, 2160x3840 分辨率档位(multipart 模式下平铺为表单字段,优先级高于 size)
720p, 1080p, 4k 画面比例:16:9 横屏(默认)或 9:16 竖屏
16:9, 9:16 随机数种子(multipart 表单字段,传字符串数字即可)。固定 seed 可让多次输出风格聚集,但不能字节级复现。
"20260521"
反向提示词,推荐传 "blurry, watermark, distorted, low quality"
"blurry, watermark, distorted, low quality"
回應
任务已提交,返回 task_id 与 queued 状态
任务 ID(与 task_id 同值,下游建议统一用 task_id)
"task_xxxxxxxxxxxxxxxx"
任务 ID,用于后续轮询和下载
"task_xxxxxxxxxxxxxxxx"
对象类型,固定 video
"video"
本次任务使用的模型 ID
"veo-3.1-fast-generate-preview"
任务状态:
queued—— 已提交,排队等待in_progress—— 正在生成completed—— 完成,可下载(/v1/videos/{task_id}/content)failed—— 失败(不计费),可重试
queued, in_progress, completed, failed "queued"
生成进度(粗粒度,只在 0 / 50 / 100 三档跳)
0
任务创建 Unix 时间戳(秒)
1775025000
任务完成 Unix 时间戳(秒),仅 completed 状态返回
1775025090
這個頁面有幫助嗎?