API 密钥只能放在服务端环境变量或密钥管理服务中,不得写进浏览器包、Git、日志或截图。

官方 SDK 快速上手

官方 SDK 封装一步式契约(提交 → 轮询 → 下载),自动幂等键与类型化错误;Node 零依赖,Python 仅依赖 httpx。当前为 GitHub 仓库形态,npm/PyPI 正式发布另行公告。

Node

npm install github:openaiav/sdk-node   # npm 正式发布另行公告

import { OpenAiav } from '@openaiav/sdk'
const client = new OpenAiav({ apiKey: process.env.OPENAIAV_API_KEY })
const task = await client.generations.createAndWait({
  model: 'seedance-2.5-oa', prompt: 'She walks into the sunlight.',
  resolution: '480p', aspectRatio: 'adaptive', durationSeconds: 4,
  generateAudio: false
})
await client.generations.downloadToFile(task.id, './out.mp4')

Python

pip install git+https://github.com/openaiav/sdk-python   # PyPI 正式发布另行公告

from openaiav import OpenAiav
client = OpenAiav(os.environ["OPENAIAV_API_KEY"])
task = client.generations.create_and_wait({
    "model": "seedance-2.5-oa", "prompt": "She walks into the sunlight.",
    "resolution": "480p", "aspectRatio": "adaptive", "durationSeconds": 4,
    "generateAudio": False,
})
client.generations.download_to_file(task["id"], "./out.mp4")

四步接入

  1. 使用服务端环境变量 OPENAIAV_API_KEY 调用 https://api.openaiav.com/v1/models,读取当前模型键、计价与 reference_modes。
  2. 向 POST /v1/generations 提交 prompt、referenceMode 与 referenceImages;参考图是公网 HTTPS URL,不需要预注册。创建成功为 HTTP 201。
  3. 保存响应 id,按 poll_after_ms 对同一个 GET /v1/generations/{id} 轮询。processing、result_pending、submission_unknown 都继续等待,不要重新创建。
  4. 状态变为 succeeded 后调用 GET /v1/generations/{id}/content 下载;完整响应为 HTTP 200,单区间 Range 为 206。

认证与幂等

export OPENAIAV_API_KEY='oav_...'
export OPENAIAV_IDEMPOTENCY_KEY='openaiav-quickstart-4s-480p-001'

每个请求都带 Authorization: Bearer oav_...。密钥只放在服务端。创建任务需要 generation:create,查询和下载需要 generation:read。网络结果不确定时复用原 Idempotency-Key;同一个键不得配不同请求体。

请求头

参数类型必填说明
Authorizationstring必填所有 /v1 请求均使用 Bearer oav_...;密钥只保存在服务端。
Idempotency-Keystring仅创建任务必填网络重试必须复用同一个值;同值同请求体不会重复生成或重复扣费。
Content-Typestring仅 POST 必填创建任务使用 application/json

端点一览

方法路径成功Scope说明
GET/v1/models200valid API key读取当前可售模型、价格、分辨率、时长与 reference_modes。提交前必须按目录校验能力。
POST/v1/generations201generation:create创建异步任务;参考图与 referenceMode 在同一个 JSON 请求中提交。
GET/v1/generations/{id}200generation:read按响应中的 poll_after_ms 查询同一任务,直到终态。
GET/v1/generations/{id}/content200 / 206generation:read任务成功后下载输出;单区间 Range 请求返回 206。

第一步:读取模型能力

不要写死模型能力。只有 reference_modes 列出的模式可以提交;界面也应在提交前隐藏或拦截不兼容组合。最小示例固定演示 seedance-2.5 的 4 秒、480p、无音频请求。

curl --fail-with-body 'https://api.openaiav.com/v1/models' \
  --header "Authorization: Bearer $OPENAIAV_API_KEY"

最小公网视频示例

完整链路在同一个示例里:创建 → 轮询同一任务 → 下载。 first_frame 使用一张参考图和 adaptivegenerateAudio=false 避免请求音频。创建、轮询、下载的成功状态分别是 201、200、200/206;失败响应先读取 HTTP,再读取 error.code

# Keep both values in environment variables; do not paste secrets into shell history.
# Generate OPENAIAV_IDEMPOTENCY_KEY once for this create intent and keep it unchanged on every retry.
# Set it before the first create, then reuse the exact value after a lost response.
# 1. Create — success: HTTP 201. On failure, the response body contains error.code.
curl --fail-with-body --request POST 'https://api.openaiav.com/v1/generations' \
  --header "Authorization: Bearer $OPENAIAV_API_KEY" \
  --header "Idempotency-Key: $OPENAIAV_IDEMPOTENCY_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "seedance-2.5",
  "prompt": "女孩写完一封信,从乡间石屋走入清晨阳光",
  "resolution": "480p",
  "aspectRatio": "adaptive",
  "durationSeconds": 4,
  "referenceMode": "first_frame",
  "referenceImages": [
    "https://developers.openaiav.com/samples/seedance-letter-reference.webp"
  ],
  "generateAudio": false,
  "outputFormat": "mp4"
}'

# 2. Save the returned id as TASK_ID. Poll the same id — success: HTTP 200.
curl --fail-with-body 'https://api.openaiav.com/v1/generations/TASK_ID' \
  --header "Authorization: Bearer $OPENAIAV_API_KEY"

# Repeat step 2 after poll_after_ms until status is succeeded or failed.
# Never recreate a task whose status is submission_unknown.

# 3. After succeeded, download — success: HTTP 200 (or 206 with Range).
curl --fail-with-body --location 'https://api.openaiav.com/v1/generations/TASK_ID/content' \
  --header "Authorization: Bearer $OPENAIAV_API_KEY" \
  --output 'result.mp4'

请求参数

参数类型必填说明
modelstring必填取自 GET /v1/modelsmodel;最小视频示例使用 seedance-2.5
promptstring必填1–4000 字符。全能参考可按数组顺序用 @Image1@Image2 指代图片。
resolutionstring可选必须属于所选模型的 resolutions;最小视频示例使用 480p
aspectRatiostring可选必须属于所选模型的 aspect_ratios。图片模型同样生效;当所选模型的首帧能力要求自适应画幅时使用 adaptive
durationSecondsinteger可选视频省略时使用模型最小时长;显式值必须在目录的 duration_seconds 区间内。最小示例使用 4 秒。
referenceModefirst_frame | omni_reference使用视频参考图时必填只在目录 reference_modes 明确列出的 Seedance 视频模型上使用。一次请求只能选择一个模式。
referenceImagesstring[]与 referenceMode 同时填写公网 HTTPS 图片 URL。first_frame 必须且只能 1 张;omni_reference 上限读取 reference_images_max
inputImagesstring[]可选仅图片模型的图生图输入,可用 HTTPS 或 data:image/*;上限读取 input_images_max,不得与视频参考模式混用。
generateAudioboolean可选支持音频的视频模型省略时默认 true。最经济示例显式传 false;当前目录没有单列音频附加价,计费始终以 GET /v1/models 为准。
outputFormatmp4 | mov可选只能选择目录 output_formats 中的值;最小示例使用 mp4

参考素材模式

first_frame

first_frame:参考图成为起始画面并决定构图。必须且只能提交 1 张 referenceImagesaspectRatio 取自所选模型的 aspect_ratios,目录含 adaptive 时锁定为 adaptive(输出跟随参考图画幅)。 first_last_frame:提交恰好 2 张 referenceImages按数组顺序分别是首帧与尾帧,中间画面由模型补全。两张图不要求同尺寸。帧模式与 omni_reference 互斥。

{
  "model": "seedance-2.5",
  "prompt": "女孩写完一封信,从乡间石屋走入清晨阳光",
  "resolution": "480p",
  "aspectRatio": "adaptive",
  "durationSeconds": 4,
  "referenceMode": "first_frame",
  "referenceImages": [
    "https://developers.openaiav.com/samples/seedance-letter-reference.webp"
  ],
  "generateAudio": false,
  "outputFormat": "mp4"
}

omni_reference

omni_reference:参考素材用于锁定主体、风格与场景的一致性,不要求成为首帧。除 referenceImages 外,支持的模型还可传 referenceVideosreferenceAudios;各类上限见下表,目录未声明的类型提交即 400。提示词按同类型内的数组顺序引用 @Image1@Video1@Audio1

{
  "model": "seedance-2.5",
  "prompt": "@Image1 保持人物身份与服装一致,女孩从乡间石屋走入清晨阳光",
  "resolution": "480p",
  "aspectRatio": "16:9",
  "durationSeconds": 4,
  "referenceMode": "omni_reference",
  "referenceImages": [
    "https://developers.openaiav.com/samples/seedance-letter-reference.webp"
  ],
  "generateAudio": false,
  "outputFormat": "mp4"
}

真实兼容范围

接入方式对所有视频模型是同一套:同一个端点、同一组字段,换模型只改 model。差异全部由目录声明——下表就是目录本身,逐个模型列出它支持哪些参考模式、各类素材收几个。目录没声明的能力,提交时会被明确拒绝,不会静默忽略。

目录尚未加载。先调用 GET /v1/models;没有 reference_modes 的模型不得提交参考模式。

首帧细则与尾帧接力

首帧细则:first_frameomni_reference 互斥,同一请求只能选其一;omni 下可用提示词间接引导某张参考图作起始画面,但需要严格首帧一致时,请使用 first_frame 模式提交那张图。Seedance 2.5 的首帧任务画幅固定 adaptive(输出跟随首帧)。尾帧接力:创建时传 returnLastFrame: true,成功后任务额外返回 last_frame_url(与视频同宽高的无水印 PNG,保留 24 小时)——把这个 URL 直接作为下一单 first_framereferenceImages,即可串联多镜头连续叙事,无需任何预注册步骤。

轮询与下载

succeededfailed 才是终态。submission_unknown 是待对账状态:保留原任务 ID,继续轮询,绝不能重放创建请求。成功后优先使用鉴权下载路径 /content,不要依赖任何非 Open AIav 地址。产物保留 24 小时(详情返回 output_expires_at 倒计时;过期后下载返回 410 OUTPUT_EXPIRED,请及时转存)。

状态终态处理方式
processing已受理;按 poll_after_ms 继续查询。
result_pending输出正在完成结算;继续查询同一任务。
submission_unknown结果待对账;不要重放创建请求,继续保留并查询原任务 ID。
succeeded成功;使用 /content 下载输出。
failed确定失败且预留金额已退回;读取 error_code

旧端点迁移

/v1/assets/v1/assets/content/v1/assets/{id}/v1/asset-groups/v1/asset-groups/{id} 已退役;使用有效密钥及相应旧 scope 时返回 HTTP 410 / ENDPOINT_RETIRED。新接入不得调用这些路径;把 referenceModereferenceImages 放进同一次生成请求。

错误码对照

完整对照:HTTP 状态、错误码、含义、建议处置与 SDK 错误类。本表与 SDK 的错误映射同一数据源,未知新码由 SDK 按 HTTP 状态段兜底。

HTTP错误码含义建议处置SDK
401UNAUTHENTICATED缺少或无法识别 API 密钥。带上 Authorization: Bearer oav_… 请求头;密钥只放服务端。AuthenticationError
401INVALID_API_KEY密钥无效或已吊销。在控制台确认密钥状态;必要时轮换生成新密钥。AuthenticationError
403INSUFFICIENT_SCOPE密钥缺少本操作所需 scope。创建任务需 generation:create,查询与下载需 generation:read。PermissionError
429RATE_LIMITED请求超出密钥限频。按 Retry-After / retryAfterSeconds 退避重试;SDK 自动处理。RateLimitError
400IDEMPOTENCY_KEY_REQUIRED创建任务必须携带 Idempotency-Key。为每次新请求生成唯一键;网络重试复用同一键。SDK 自动生成。InvalidRequestError
409IDEMPOTENCY_KEY_CONFLICT同一幂等键配了不同请求体。不同参数请换新键;同参重试保持键与请求体逐字一致。InvalidRequestError
400MODEL_NOT_FOUND未知模型 ID。以 GET /v1/models 返回的 model 为准(如 seedance-2.5-oa)。InvalidRequestError
400INVALID_PROMPT提示词为空或超长。提示词 1–4000 字符。InvalidRequestError
400INVALID_DURATION时长不在模型允许区间。取目录 duration_seconds 区间内整数,或支持时传 -1 智能时长。InvalidRequestError
400INVALID_RESOLUTION分辨率不被该模型支持。取目录 resolutions 中的取值。InvalidRequestError
400INVALID_ASPECT_RATIO画幅不被该模型支持。取目录 aspect_ratios 中的取值;first_frame 场景常锁 adaptive。InvalidRequestError
400INVALID_REFERENCE_IMAGESreferenceImages 需为公网 HTTPS URL 数组。逐项提供任务期间可读取的 https:// 图片链接。InvalidRequestError
400INVALID_REFERENCE_IMAGE某一项参考图不是合法 URL。错误信息带下标(referenceImages[i]);逐项检查该链接。InvalidRequestError
400REFERENCE_IMAGE_URL_NOT_HTTPS参考图链接不是公网 HTTPS。不支持 http/内网/data URL;请上传到可公网访问的存储。InvalidRequestError
400REFERENCE_MODE_REQUIRES_IMAGES声明了 referenceMode 却没有参考图。referenceMode 与 referenceImages 必须同时出现。InvalidRequestError
400REFERENCE_MODE_NOT_SUPPORTED该模型不支持所选参考模式。以目录 reference_modes 为准选择 first_frame / omni_reference。InvalidRequestError
400FIRST_FRAME_REQUIRES_ONE_IMAGEfirst_frame 必须且只能一张参考图。只提交 1 张;多图请改用 omni_reference。InvalidRequestError
400TOO_MANY_REFERENCES参考图数量超过目录上限。上限见目录 reference_images_max。InvalidRequestError
400INVALID_INPUT_IMAGESinputImages 需为数组。逐项为 HTTPS URL 或 data:image/* base64。InvalidRequestError
400INVALID_INPUT_IMAGE某一项输入图片格式不合法。逐项需为 HTTPS URL 或 data:image/* base64;错误信息带下标。InvalidRequestError
400INPUT_IMAGE_TOO_LARGE内嵌图片超过 10MB。压缩后重试,或改用公网 HTTPS URL。InvalidRequestError
400IMAGE_INPUT_NOT_SUPPORTED该模型不支持图片输入。仅目录声明 input_images_max>0 的图片模型可用 inputImages。InvalidRequestError
400TOO_MANY_INPUT_IMAGES输入图片数量超上限。上限见目录 input_images_max。InvalidRequestError
400INSUFFICIENT_BALANCE余额不足以预留本次任务。在控制台账单页兑换充值卡后重试。InvalidRequestError
400LEGACY_ASSET_REFERENCE_RETIRED素材 ID 引用已退役。在同一次请求中使用 referenceMode + referenceImages(公网 HTTPS)。InvalidRequestError
404NOT_FOUND任务不存在或不属于当前密钥。确认任务 ID 与密钥归属同一账号。InvalidRequestError
409OUTPUT_NOT_READY产物尚未就绪。继续按 poll_after_ms 轮询任务至终态。InvalidRequestError
410OUTPUT_EXPIRED产物下载窗口(成功后 24 小时)已过。产物请及时转存;过期后需重新生成。detail 的 output_expires_at 可做倒计时。OutputExpiredError

控制台会话面专属码

HTTP错误码含义建议处置
400REFERENCE_UPLOAD_NOT_FOUND本地上传引用不存在、过期或不属于当前账号。在 Playground 重新上传后再运行(上传短时有效)。
429UPLOAD_QUOTA_EXCEEDED未使用的上传数量达到上限。先运行任务消费上传,或等待过期后重试。
429WEBHOOK_ENDPOINT_LIMITWebhook 端点数量达到上限。删除或停用不再使用的端点。
400INVALID_WEBHOOK_URL回调 URL 不是可公网访问的 HTTPS。使用公网 HTTPS 地址;内网/回环地址会被拒绝。