将下方平台地址替换 OpenAI 的 base_url,使用平台颁发的令牌作为 api_key,即可开始调用。
该地址为平台统一接入地址,兼容 OpenAI 协议;以下示例中的地址均自动取自此处。
sk- 开头的密钥api_key 填入客户端或代码中操练场是内置的在线测试工具,无需编写代码即可直接与模型对话,适合快速验证令牌是否可用。
/console/playground)from openai import OpenAI
client = OpenAI(
api_key="sk-xxxxxxxxxxxxxxxx", # 平台颁发的令牌
base_url="…"
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
curl …/messages \
-H "x-api-key: sk-xxxxxxxx" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-3-5-sonnet-20241022", "max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}]}'
curl "…/v1beta/models/gemini-1.5-pro:generateContent?key=sk-xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"contents": [{"parts": [{"text": "Hello"}]}]}'
| 接口 | 方法 | 路径 | 说明 |
|---|---|---|---|
| 聊天补全 | POST | /v1/chat/completions | 对话生成,支持流式输出 |
| 文本补全 | POST | /v1/completions | 传统补全接口 |
| 向量嵌入 | POST | /v1/embeddings | 文本向量化 |
| 图像生成 | POST | /v1/images/generations | 文生图 |
| 图像编辑 | POST | /v1/images/edits | 图像编辑 |
| 语音转文字 | POST | /v1/audio/transcriptions | Whisper 等 |
| 文字转语音 | POST | /v1/audio/speech | TTS |
| 重排序 | POST | /v1/rerank | 文档重排序 |
| Responses API | POST | /v1/responses | OpenAI Responses 格式 |
| 实时对话 | GET | /v1/realtime(WebSocket) | OpenAI Realtime API |
| 模型列表 | GET | /v1/models | 查询可用模型 |
| 视频生成 | POST | /v1/videos | 创建视频任务,见下方「视频生成模型」 |
| 视频任务查询 | GET | /v1/videos/{task_id} | 轮询视频任务状态 |
视频生成接口采用异步任务模型:先调用生成接口创建任务获得 task_id,再循环轮询状态接口直到任务完成(状态为 completed),从响应中取出视频下载地址。
两套地址均可使用:OpenAI 兼容格式与平台原生格式,请求参数完全相同,仅查询响应结构不同。
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /v1/videos | 创建视频生成任务(OpenAI 兼容格式) |
| GET | /v1/videos/{task_id} | 查询任务状态(OpenAI 兼容格式) |
| GET | /v1/videos/{task_id}/content | 直接获取视频内容(代理下载) |
| POST | /v1/video/generations | 创建视频任务(平台原生格式) |
| GET | /v1/video/generations/{task_id} | 查询任务状态(平台原生格式) |
POST /v1/videos 与 POST /v1/video/generations 请求体相同(JSON):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 视频模型名称,如 doubao-seedance-2.0、happyhorse-1.1-t2v |
| prompt | string | 是 | 视频生成提示词 |
| duration | int | 视模型 | 视频时长(秒),如 4-15 |
| resolution | string | 视模型 | 分辨率:480p / 720p / 1080p |
| ratio | string | 否 | 宽高比:16:9 / 9:16 / 1:1 等 |
| image_urls | array[string] | 否 | 参考图片 URL 列表(图生视频首帧、参考图) |
| video_urls | array[string] | 否 | 参考视频 URL 列表(视频编辑输入) |
| watermark | bool | 否 | 是否添加水印,默认 false |
| seed | int | 否 | 随机种子 [0, 2147483647] |
| generate_audio | bool | 否 | 是否生成同步音频(仅部分模型) |
| return_last_frame | bool | 否 | 是否返回尾帧图像(仅部分模型) |
不同模型支持的参数范围不同,请以控制台「视频模型」页面为准。例如 doubao-seedance-2.0 要求 duration 与 resolution 必填;视频编辑类模型不接受 duration 和 ratio。
HappyHorse 系列为阿里云百炼新一代视频模型,输出物理真实、运动流畅的视频,支持文生视频、图生视频(首帧)、参考生视频、视频编辑四种形态。调用方式与上方统一视频接口完全一致,仅模型名称与输入素材不同。
| 模型 | 能力 | 输入要求 |
|---|---|---|
| happyhorse-1.1-t2v / happyhorse-1.0-t2v | 文生视频 | prompt 必填(≤2500 中文字符) |
| happyhorse-1.1-i2v / happyhorse-1.0-i2v | 图生视频(首帧) | image_urls 有且仅有 1 张首帧图;prompt 可选;宽高比自动跟随首帧,不支持 ratio |
| happyhorse-1.1-r2v / happyhorse-1.0-r2v | 参考生视频 | prompt + image_urls 1~9 张参考图;prompt 中用 [Image 1]、[Image 2]… 按顺序指代参考图中的对象 |
| happyhorse-1.0-video-edit | 视频编辑 | prompt(编辑指令)+ video_urls 有且仅有 1 个输入视频(MP4/MOV,3~60 秒)+ image_urls 0~5 张参考图 |
| 字段 | 说明 |
|---|---|
| duration | 3-15 秒整数,默认 5。视频编辑不接受该参数:输出时长跟随输入视频(输入 ≤15 秒时与输入一致,否则自动截取前 15 秒) |
| resolution | 480p / 720p / 1080p,默认 1080p;视频编辑仅支持 720p / 1080p |
| ratio | 仅文生视频 / 参考生视频支持:16:9(默认)/ 9:16 / 1:1 / 4:3 / 3:4 / 4:5 / 5:4 / 9:21 / 21:9 |
| watermark | 默认 false(不添加水印);设为 true 时右下角添加 “Happy Horse” 水印 |
| seed | [0, 2147483647],固定 seed 可提升结果可复现性 |
HappyHorse 按产出视频时长(秒)× 分辨率档位单价计费:创建任务时按请求时长预扣;视频编辑因输出时长未知按 15 秒上限预扣,任务完成后按实际产出时长多退少补。
# 文生视频(16:9、720p、5 秒) curl …/videos \ -H "Authorization: Bearer sk-xxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "model": "happyhorse-1.1-t2v", "prompt": "一座由硬纸板和瓶盖搭建的微型城市,在夜晚焕发出生机", "duration": 5, "resolution": "720p", "ratio": "16:9" }' # 图生视频(首帧驱动,宽高比跟随首帧) curl …/videos \ -H "Authorization: Bearer sk-xxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "model": "happyhorse-1.1-i2v", "prompt": "一只猫在草地上奔跑", "image_urls": ["https://example.com/first-frame.png"], "duration": 5, "resolution": "720p" }' # 参考生视频(prompt 中以 [Image N] 指代参考图) curl …/videos \ -H "Authorization: Bearer sk-xxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "model": "happyhorse-1.1-r2v", "prompt": "[Image 1]中身着红色旗袍的女性,轻抬玉手展开[Image 2]中的折扇", "image_urls": ["https://example.com/girl.jpg", "https://example.com/fan.jpg"], "duration": 5, "resolution": "720p", "ratio": "16:9" }' # 视频编辑(指令 + 输入视频,可选参考图) curl …/videos \ -H "Authorization: Bearer sk-xxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "model": "happyhorse-1.0-video-edit", "prompt": "让视频中的角色穿上图片中的条纹毛衣", "video_urls": ["https://example.com/input.mp4"], "image_urls": ["https://example.com/sweater.webp"], "resolution": "720p" }'
轮询与结果获取方式与其他视频模型完全相同(OpenAI 兼容格式取 metadata.url,平台原生格式取 data.result_url);上游视频链接有效期 24 小时,请及时下载转存。
HTTP 200。两个创建地址(/v1/videos 与 /v1/video/generations)返回相同的 OpenAI Video 对象:
{
"id": "task_xxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxx",
"object": "video",
"model": "doubao-seedance-2.0",
"status": "queued",
"progress": 0,
"created_at": 1783495738,
"metadata": null
}
其中 task_id 用于后续轮询。
GET /v1/videos/{task_id} 返回与创建时相同的 OpenAI Video 对象,关键字段随任务推进变化:
| 字段 | 说明 |
|---|---|
| status | 任务状态,见下方状态码表 |
| progress | 进度百分比 0-100 |
| metadata.url | 视频下载地址(status=completed 时存在) |
| completed_at | 完成时间戳 |
| error | 失败时的错误信息 {message, code} |
生成成功响应示例:
{
"id": "task_xxxxxxxxxxxx",
"task_id": "task_xxxxxxxxxxxx",
"object": "video",
"model": "doubao-seedance-2.0",
"status": "completed",
"progress": 100,
"created_at": 1783495738,
"completed_at": 1783496011,
"metadata": { "url": "https://example.com/video.mp4" }
}
| 状态 | 说明 |
|---|---|
| queued | 已创建,排队中 |
| in_progress | 生成中 |
| completed | 生成成功,可取 metadata.url |
| failed | 生成失败,查看 error |
GET /v1/video/generations/{task_id} 返回 {code, message, data} 结构,视频地址在 data.result_url:
{
"code": "success",
"message": "",
"data": {
"task_id": "task_xxxxxxxxxxxx",
"action": "generate",
"status": "SUCCESS",
"progress": "100%",
"result_url": "https://example.com/video.mp4",
"fail_reason": "",
"submit_time": 1783495738,
"start_time": 1783495740,
"finish_time": 1783496011
}
}
| 字段(data 内) | 说明 |
|---|---|
| task_id | 任务 ID |
| status | 任务状态,见下方状态码表 |
| progress | 进度字符串,如 "10%" / "50%" / "100%" |
| result_url | 视频下载地址(status=SUCCESS 时存在) |
| fail_reason | 失败原因(status=FAILURE 时存在) |
| submit_time / start_time / finish_time | 提交 / 开始 / 完成时间戳 |
| quota | 该任务预扣额度 |
| 状态 | 说明 |
|---|---|
| NOT_START / SUBMITTED / QUEUED | 已创建,排队中 |
| IN_PROGRESS | 生成中 |
| SUCCESS | 生成成功,可取 result_url |
| FAILURE | 生成失败,查看 fail_reason |
| 状态码 | 说明 |
|---|---|
| 200 | 请求成功 |
| 400 | 参数错误或任务不存在(code 如 invalid_duration、invalid_resolution、unsupported_model、task_not_exist) |
| 401 | 令牌无效或过期 |
| 403 | 额度不足(预扣费失败) |
| 429 | 当前分组上游负载饱和,请稍后再试 |
| 500 | 内部错误 |
错误响应体格式:{"code": "错误码", "message": "错误描述", "data": null}。
from openai import OpenAI
import time
client = OpenAI(
api_key="sk-xxxxxxxxxxxxxxxx",
base_url="…"
)
# 1. 创建视频任务
resp = client.post(
"/videos",
body={
"model": "doubao-seedance-2.0",
"prompt": "一只猫在草地上奔跑",
"duration": 5,
"resolution": "720p"
},
cast_to=object
)
task_id = resp["task_id"]
print(f"Task created: {task_id}")
# 2. 轮询状态直到完成
while True:
time.sleep(10)
status_resp = client.get(f"/videos/{task_id}", cast_to=object)
status = status_resp["status"]
print(f"Status: {status}")
if status == "completed":
video_url = status_resp["metadata"]["url"]
print(f"Video URL: {video_url}")
break
elif status == "failed":
print(f"Failed: {status_resp.get('error')}")
break
# 创建任务 curl …/videos \ -H "Authorization: Bearer sk-xxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "model": "doubao-seedance-2.0", "prompt": "一只猫在草地上奔跑", "duration": 5, "resolution": "720p" }' # 轮询状态(将 {task_id} 替换为实际值) curl …/videos/{task_id} \ -H "Authorization: Bearer sk-xxxxxxxx"
import requests, time
BASE = "…"
HEADERS = {"Authorization": "Bearer sk-xxxxxxxx", "Content-Type": "application/json"}
# 1. 创建任务
resp = requests.post(f"{BASE}/video/generations", headers=HEADERS, json={
"model": "doubao-seedance-2.0",
"prompt": "一只猫在草地上奔跑",
"duration": 5,
"resolution": "720p"
}).json()
task_id = resp["task_id"]
print(f"Task created: {task_id}")
# 2. 轮询状态直到 SUCCESS
while True:
time.sleep(10)
data = requests.get(f"{BASE}/video/generations/{task_id}",
headers=HEADERS).json()["data"]
print(f"Status: {data['status']}")
if data["status"] == "SUCCESS":
print(f"Video URL: {data['result_url']}")
break
elif data["status"] == "FAILURE":
print(f"Failed: {data['fail_reason']}")
break