文生视频:根据文本提示词生成视频任务
curl --request POST \
--url https://api.apiyi.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "sora-2",
"prompt": "A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion"
}
'import requests
url = "https://api.apiyi.com/v1/videos"
payload = {
"model": "sora-2",
"prompt": "A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'sora-2',
prompt: 'A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion'
})
};
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 => json_encode([
'model' => 'sora-2',
'prompt' => 'A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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("{\n \"model\": \"sora-2\",\n \"prompt\": \"A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"sora-2\",\n \"prompt\": \"A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion\"\n}")
.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["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"sora-2\",\n \"prompt\": \"A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion\"\n}"
response = http.request(request)
puts response.read_body{
"id": "video_abc123def456",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1712697600,
"completed_at": 1712697900,
"size": "1280x720",
"seconds": "8",
"quality": "standard"
}Sora 2(OpenAI)
文生影片 API 參考
Sora 2 文生影片 API 參考與線上除錯 — JSON 請求體、非同步任務三步流程、4/8/12 秒靈活時長。
POST
/
v1
/
videos
文生视频:根据文本提示词生成视频任务
curl --request POST \
--url https://api.apiyi.com/v1/videos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "sora-2",
"prompt": "A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion"
}
'import requests
url = "https://api.apiyi.com/v1/videos"
payload = {
"model": "sora-2",
"prompt": "A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'sora-2',
prompt: 'A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion'
})
};
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 => json_encode([
'model' => 'sora-2',
'prompt' => 'A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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("{\n \"model\": \"sora-2\",\n \"prompt\": \"A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
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>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"sora-2\",\n \"prompt\": \"A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion\"\n}")
.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["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"sora-2\",\n \"prompt\": \"A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion\"\n}"
response = http.request(request)
puts response.read_body{
"id": "video_abc123def456",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1712697600,
"completed_at": 1712697900,
"size": "1280x720",
"seconds": "8",
"quality": "standard"
}右側的互動式 Playground 支援直接線上除錯。請在 Authorization 中填入你的 API Key(格式:
Bearer sk-xxx),輸入 prompt、選擇 model / size / seconds 後一鍵傳送即可。場景說明:本頁用於「純文本提示詞生成影片」——不傳
input_reference、走 application/json 請求體。如需基於一張參考圖生成影片(圖生影片),請使用 圖生影片介面(同一端點 + input_reference 檔案上傳)。⚠️ 三步非同步流程,本頁只覆蓋第一步(提交)
- 第 1 步(本頁):
POST /v1/videos→ 返回video_id+status: "queued" - 第 2 步:
GET /v1/videos/{video_id}輪詢,直到status: "completed" - 第 3 步:
GET /v1/videos/{video_id}/content下載 MP4 檔案
程式碼示例
Python(OpenAI SDK 直連)
from openai import OpenAI
import time
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api.apiyi.com/v1"
)
# 第 1 步:提交生成任務
video = client.videos.create(
model="sora-2",
prompt="A golden retriever running on the beach at sunset, cinematic, golden hour, slow motion",
seconds="8",
size="1280x720"
)
print(f"Video ID: {video.id}, status: {video.status}")
# 第 2 步:輪詢狀態
while True:
video = client.videos.retrieve(video.id)
print(f"Status: {video.status}, progress: {getattr(video, 'progress', 0)}%")
if video.status == "completed":
break
if video.status == "failed":
raise RuntimeError(f"Generation failed: {video}")
time.sleep(15)
# 第 3 步:下載影片
content = client.videos.download_content(video.id)
content.write_to_file("output.mp4")
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": "sora-2",
"prompt": "A serene Japanese garden with cherry blossoms, koi pond, traditional bridge, golden hour, ultra detailed",
"seconds": "8",
"size": "1280x720"
},
timeout=30 # POST 提交本身只是入隊,30 秒足夠
).json()
video_id = resp["id"]
print(f"Video ID: {video_id}, status: {resp['status']}")
# 第 2 步:輪詢(最長等 15 分鐘)
deadline = time.time() + 900
while time.time() < deadline:
status_resp = requests.get(f"{BASE_URL}/videos/{video_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(15)
# 第 3 步:下載
with requests.get(f"{BASE_URL}/videos/{video_id}/content", headers=HEADERS, stream=True) 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)
print("Saved: output.mp4")
cURL
{/* 第 1 步:提交任務 */}
curl -X POST "https://api.apiyi.com/v1/videos" \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "A futuristic cityscape at night with neon lights and flying vehicles, cyberpunk style, cinematic",
"seconds": "8",
"size": "1280x720"
}'
{/* 第 2 步:輪詢狀態(替換 video_id)*/}
curl -X GET "https://api.apiyi.com/v1/videos/video_abc123" \
-H "Authorization: Bearer sk-your-api-key"
{/* 第 3 步:下載影片檔案 */}
curl -X GET "https://api.apiyi.com/v1/videos/video_abc123/content" \
-H "Authorization: Bearer sk-your-api-key" \
-o 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: 'sora-2',
prompt: 'Aerial drone shot over snowy mountain range at sunrise, cinematic, ultra wide',
seconds: '8',
size: '1280x720'
})
});
const { id: videoId } = await submitResp.json();
console.log(`Video ID: ${videoId}`);
// 第 2 步:輪詢
let status = 'queued';
while (status !== 'completed' && status !== 'failed') {
await new Promise(r => setTimeout(r, 15000));
const statusResp = await fetch(`${BASE_URL}/videos/${videoId}`, {
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 步:下載
const contentResp = await fetch(`${BASE_URL}/videos/${videoId}/content`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
const buffer = Buffer.from(await contentResp.arrayBuffer());
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: 'sora-2',
prompt: 'Watercolor northern lights over snowy mountains, gentle motion',
seconds: '4',
size: '720x1280'
})
});
const { id } = await submitResp.json();
console.log('Video ID:', id);
{/* 輪詢狀態後,把影片 URL 交給後端代理下載,再回流給前端展示 */}
引數說明速查
| 引數 | 型別 | 必填 | 預設 | 說明 |
|---|---|---|---|---|
model | string | 是 | — | sora-2(720p 標準)或 sora-2-pro(720p / 1024p / 1080p 多檔) |
prompt | string | 是 | — | 影片描述提示詞,建議詳細描述場景、鏡頭運動、風格、光線 |
seconds | string | 否 | "4" | 影片時長,字串列舉:"4" / "8" / "12"(不是數字) |
size | string | 否 | 720x1280 | 輸出解析度,需匹配模型支援檔位(見 概覽頁技術規格) |
詳細的引數約束、可選值、示例請檢視右側 Playground 中的欄位說明,所有 enum 欄位均支援下拉選擇。圖生影片相關引數(
input_reference 檔案上傳)見 圖生影片介面。響應格式
第 1 步 - 提交後立即返回
{
"id": "video_abc123def456",
"object": "video",
"model": "sora-2",
"status": "queued",
"progress": 0,
"created_at": 1712697600,
"size": "1280x720",
"seconds": "8",
"quality": "standard"
}
第 2 步 - 輪詢返回(生成中)
{
"id": "video_abc123def456",
"object": "video",
"model": "sora-2",
"status": "in_progress",
"progress": 45,
"created_at": 1712697600,
"size": "1280x720",
"seconds": "8"
}
第 2 步 - 輪詢返回(完成)
{
"id": "video_abc123def456",
"object": "video",
"model": "sora-2",
"status": "completed",
"progress": 100,
"created_at": 1712697600,
"completed_at": 1712697900,
"size": "1280x720",
"seconds": "8"
}
⚠️ 響應欄位陷阱
- 沒有直接的
video_url欄位 —— 影片檔案需要通過GET /v1/videos/{id}/content端點單獨下載(返回video/mp4二進位制流),不要期待響應裡直接出現一個 CDN 連結 progress欄位在不同生成階段會跳變(如 0 → 45 → 80 → 100),不是嚴格線性的status: "failed"時不一定帶詳細error欄位,多見於內容稽核或服務過載,直接重試或調整 prompt 即可- 影片內容在 OpenAI 上只保留 1 天,過期後
/content返回 404
本端點是非同步任務式入口,計費在生成完成時按
seconds 單價結算(見 概覽頁定價表)。POST 提交、輪詢查詢、影片下載本身不計費,失敗任務也不計費。授權
在 API易控制台获取的 API Key(必须配置 Sora2官转 分组 + 按量计费)
主體
application/json
模型 ID。sora-2 仅支持 720p;sora-2-pro 支持 720p / 1024p / 1080p 三档分辨率
可用選項:
sora-2, sora-2-pro 视频生成提示词,建议详细描述场景、镜头运动、风格、光线、人物动作
範例:
"A serene Japanese garden with cherry blossoms, koi pond, traditional bridge, golden hour, ultra detailed"
视频时长,字符串枚举(不是数字):
"4"—— 4 秒(默认),适合短演示、单镜头、快速试错"8"—— 8 秒,标准短视频,最常用"12"—— 12 秒,长镜头、连续动作
传 "10" / "15" 或数字 4 会返回 400
可用選項:
4, 8, 12 输出分辨率,sora-2 与 sora-2-pro 支持档位不同:
sora-2(仅 720p):720x1280(竖屏,默认)/1280x720(横屏)sora-2-pro额外支持:1024x1792/1792x1024(1024p,$0.50/秒)1080x1920/1920x1080(1080p,$0.70/秒)
给 sora-2 传 1024p / 1080p 会返回 400
可用選項:
720x1280, 1280x720, 1024x1792, 1792x1024, 1080x1920, 1920x1080 回應
任务已提交,返回 video_id 与 queued 状态
任务 ID,用于后续轮询和下载
範例:
"video_abc123def456"
对象类型,固定 video
範例:
"video"
本次任务使用的模型 ID
範例:
"sora-2"
任务状态:
queued—— 已提交,排队等待in_progress—— 正在生成completed—— 完成,可下载(/v1/videos/{id}/content)failed—— 失败(不计费),可重试
可用選項:
queued, in_progress, completed, failed 範例:
"queued"
生成进度百分比(0–100),不严格线性
範例:
0
任务创建 Unix 时间戳(秒)
範例:
1712697600
任务完成 Unix 时间戳(秒),仅 completed 状态返回
範例:
1712697900
实际输出分辨率(与请求的 size 一致)
範例:
"1280x720"
实际生成时长(与请求的 seconds 一致)
範例:
"8"
画质档位(standard 对应 sora-2,high 对应 sora-2-pro)
範例:
"standard"
這個頁面有幫助嗎?
⌘I