🎨 ChatGPT 最新生图 gpt-image-2-all 已上线 | Now Live:$0.03/张图,对话式端点提示词遵循最佳!详情 Details
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": "A coastal lighthouse at dusk, slow push-in, waves lapping the rocks, distant seabirds, cinematic lighting, steady camera"
}
'{
"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 text-to-video API reference and interactive Playground — JSON request body, three-step async flow, flexible 4 / 6 / 8 second durations, per-request billing.
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": "A coastal lighthouse at dusk, slow push-in, waves lapping the rocks, distant seabirds, cinematic lighting, steady camera"
}
'{
"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.
Bearer sk-xxx), enter prompt, pick model / duration / metadata.resolution, then send. Default group works — no dedicated group switch needed.input_reference, application/json body. To generate from a reference image, use the Image-to-Video endpoint (same endpoint + input_reference upload).duration must be a string "4" / "6" / "8" — passing a number fails with parse_request_failed: cannot unmarshal number into Go struct field ... duration of type stringgenerateAudio — upstream returns INVALID_ARGUMENT. Encode audio intent (ambient, dialogue, BGM) in the prompt insteadduration must be "8" — "4" / "6" will be rejected upstreamPOST /v1/videos → returns task_id + status: "queued"GET /v1/videos/{task_id} poll until status: "completed"GET /v1/videos/{task_id}/content to download MP4{/* OpenAI SDK has no videos.create method; /v1/videos is a custom path, use low-level client.post() */}
from openai import OpenAI
import time
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api.apiyi.com/v1"
)
# Step 1: submit
resp = client.post(
"/videos",
body={
"model": "veo-3.1-fast-generate-preview",
"prompt": "A coastal lighthouse at dusk, slow push-in, waves lapping the rocks, distant seabirds, cinematic lighting, steady camera",
"duration": "8", # string, not number
"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']}")
# Step 2: poll (up to 3 minutes for 720p/1080p)
deadline = time.time() + 180
while time.time() < deadline:
s = client.get(f"/videos/{task_id}", cast_to=dict)
print(f"Status: {s['status']}, progress: {s.get('progress', 0)}%")
if s["status"] == "completed":
break
if s["status"] == "failed":
raise RuntimeError(f"Generation failed: {s}")
time.sleep(8)
# Step 3: download (retry to handle CDN sync delay right after completed)
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:
if i == 4:
raise
time.sleep(4)
print("Saved: output.mp4")
import requests
import time
API_KEY = "sk-your-api-key"
BASE_URL = "https://api.apiyi.com/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Step 1: submit (JSON body)
resp = requests.post(
f"{BASE_URL}/videos",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"model": "veo-3.1-fast-generate-preview",
"prompt": "A coastal lighthouse at dusk, slow push-in, steady camera, ocean ambience and distant seabirds",
"duration": "8", # must be a string
"size": "1280x720",
"metadata": {
"resolution": "720p",
"aspectRatio": "16:9"
}
},
timeout=30 # POST is just an enqueue; 30 sec is enough
).json()
task_id = resp["task_id"]
print(f"Task ID: {task_id}, status: {resp['status']}")
# Step 2: poll (3 min for 720p/1080p, 10 min for 4K)
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(f"Generation failed: {s}")
time.sleep(8)
# Step 3: download with retry
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")
{/* Step 1: submit (note duration is the string "8", not number 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": "A coastal lighthouse at dusk, slow push-in, ocean ambience, cinematic lighting",
"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"
{/* Step 2: poll every 8 sec */}
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
{/* Step 3: download (--retry covers occasional 400 right after status=completed) */}
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
import fs from 'node:fs';
const API_KEY = 'sk-your-api-key';
const BASE_URL = 'https://api.apiyi.com/v1';
// Step 1: submit
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: 'A golden retriever running on a sandy beach, slow motion, golden hour, cinematic quality',
duration: '8', // must be string
size: '1280x720',
metadata: { resolution: '720p', aspectRatio: '16:9' }
})
});
const { task_id } = await submitResp.json();
console.log(`Task ID: ${task_id}`);
// Step 2: poll
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');
// Step 3: download (retry up to 3 times, 4-second gaps)
await new Promise(r => setTimeout(r, 4000));
let buffer;
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}`);
buffer = Buffer.from(await resp.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');
{/* Demo only; route through a backend proxy in production to avoid Key leakage; large video downloads are also unsuitable for direct browser handling */}
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: 'Watercolor northern lights over snowy mountains, gentle motion',
duration: '4',
size: '720x1280',
metadata: { resolution: '720p', aspectRatio: '9:16' }
})
});
const { task_id } = await submitResp.json();
console.log('Task ID:', task_id);
{/* After polling completes, route the /content endpoint through your backend proxy for download */}
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
model | string | Yes | — | veo-3.1-fast-generate-preview ($0.3/req) or veo-3.1-generate-preview ($1.2/req) |
prompt | string | Yes | — | Video description; describe scene, action, camera, lighting, audio intent (do not pass generateAudio) |
duration | string | No | "8" | Video length, string enum: "4" / "6" / "8". 1080p/4k must be "8" |
size | string | No | 1280x720 | Output pixels, e.g. 1280x720 / 1920x1080 / 3840x2160; lower precedence than metadata.resolution |
metadata.resolution | string | No | 720p | 720p / 1080p / 4k; higher precedence than size |
metadata.aspectRatio | string | No | 16:9 | 16:9 (landscape) or 9:16 (portrait) |
metadata.seed | int | No | — | Random seed. Fixed seed clusters outputs in style (but cannot byte-reproduce) |
metadata.negativePrompt | string | No | — | Negative prompt; recommended "blurry, watermark, distorted, low quality" |
generateAudio field! Veo 3.1 is natively audio-enabled; passing this parameter returns INVALID_ARGUMENT. To control audio, write the intent into your prompt: "waves, distant seabirds, low wind sounds".metadata.durationSeconds > duration > seconds > 8metadata.resolution > size > 720pmetadata.aspectRatio > inferred from size > 16:9{
"id": "task_xxxxxxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxxxxxx",
"object": "video",
"model": "veo-3.1-fast-generate-preview",
"status": "queued",
"progress": 0,
"created_at": 1775025000
}
{
"id": "task_xxxxxxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxxxxxx",
"object": "video",
"model": "veo-3.1-fast-generate-preview",
"status": "in_progress",
"progress": 50,
"created_at": 1775025000
}
{
"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
}
id and task_id are both returned with the same value; downstream should standardize on task_id (compatible with the existing Reverse channel)video_url / data.url in the response; the video can only be retrieved as an MP4 binary stream via GET /v1/videos/{task_id}/content (requires auth header). Frontends cannot hit this endpoint directly — download server-side and re-host on your own OSS / CDNprogress is coarse-grained — jumps only between 0 / 50 / 100, do not use for percentage barsstatus: "failed" may not include a detailed error field; usually content review or parameter errors. Just retry or adjust the prompt/content returns 400 occasionally right after status flips to completed; retry after 4 seconds (all code samples above have this baked in)completed, charged per request by model name (fast $0.3 / standard $1.2, see Pricing). POST submission, polling, and download themselves are not billed; failed tasks are also not billed.API Key from APIYI console (Default group + Pay-per-request or Pay-as-you-go Priority Token; pure Pay-as-you-go not supported)
Model ID (per-request billing, duration / resolution do not affect price):
veo-3.1-fast-generate-preview — $0.3/request, top pick for iteration / batch generationveo-3.1-generate-preview — $1.2/request, for final delivery / 4K scenariosveo-3.1-fast-generate-preview, veo-3.1-generate-preview Video generation prompt; describe in detail: scene + subject + action + camera + lighting + style.
Audio intent also goes in the prompt (e.g. "waves, distant seabirds, low wind sounds"). Do not pass generateAudio — upstream rejects with INVALID_ARGUMENT.
"A coastal lighthouse at dusk, slow push-in, waves lapping the rocks, distant seabirds, cinematic lighting, steady camera"
Video length, string enum (not number):
"4" — 4 sec, 720p only"6" — 6 sec, 720p only"8" — 8 sec (default), required at 1080p / 4kPassing a number (8) returns parse_request_failed: cannot unmarshal number into Go struct field ... duration of type string.
4, 6, 8 Output pixel dimensions; lower precedence than metadata.resolution:
1280x720 / 720x1280 — 720p (default)1920x1080 / 1080x1920 — 1080p (duration must be "8")3840x2160 / 2160x3840 — 4k (duration must be "8", 4–6× slower render)1280x720, 720x1280, 1920x1080, 1080x1920, 3840x2160, 2160x3840 Wrapper for fine-grained generation parameters. Higher precedence than the top-level size etc.:
metadata.durationSeconds > duration > seconds > 8metadata.resolution > size > 720pShow child attributes
Task submitted; returns task_id and queued status
Task ID (matches task_id; downstream should standardize on task_id)
"task_xxxxxxxxxxxxxxxx"
Task ID for subsequent polling and download
"task_xxxxxxxxxxxxxxxx"
Object type, fixed to video
"video"
Model ID used for this task
"veo-3.1-fast-generate-preview"
Task status:
queued — submitted, awaiting processingin_progress — generatingcompleted — done, downloadable (/v1/videos/{task_id}/content)failed — failed (not billed), retry possiblequeued, in_progress, completed, failed "queued"
Generation progress (coarse-grained, jumps only between 0 / 50 / 100, do not use for percentage bars)
0
Task creation Unix timestamp (seconds)
1775025000
Task completion Unix timestamp (seconds); only present for completed status
1775025090
Was this page helpful?