官方 SDK 快速上手
The official SDKs wrap the one-step contract (create → poll → download) with automatic idempotency keys and typed errors; the Node SDK has zero dependencies and Python depends only on httpx. Distributed as GitHub repositories for now — npm/PyPI releases will be announced separately.
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")四步接入
- 使用服務端環境變數 OPENAIAV_API_KEY 呼叫 https://api.openaiav.com/v1/models,讀取當前模型鍵、計價與 reference_modes。
- 向 POST /v1/generations 提交 prompt、referenceMode 與 referenceImages;參考圖是公網 HTTPS URL,不需要預註冊。建立成功為 HTTP 201。
- 儲存響應 id,按 poll_after_ms 對同一個 GET /v1/generations/{id} 輪詢。processing、result_pending、submission_unknown 都繼續等待,不要重新建立。
- 狀態變為 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;同一個鍵不得配不同請求體。
Request headers
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| Authorization | string | 必填 | 所有 /v1 請求均使用 Bearer oav_...;金鑰只儲存在服務端。 |
| Idempotency-Key | string | 僅建立任務必填 | 網路重試必須複用同一個值;同值同請求體不會重複生成或重複扣費。 |
| Content-Type | string | 僅 POST 必填 | 建立任務使用 application/json。 |
端點一覽
| Method | Path | Success | Scope | 說明 |
|---|---|---|---|---|
| GET | /v1/models | 200 | valid API key | 讀取當前可售模型、價格、解析度、時長與 reference_modes。提交前必須按目錄校驗能力。 |
| POST | /v1/generations | 201 | generation:create | 建立非同步任務;參考圖與 referenceMode 在同一個 JSON 請求中提交。 |
| GET | /v1/generations/{id} | 200 | generation:read | 按響應中的 poll_after_ms 查詢同一任務,直到終態。 |
| GET | /v1/generations/{id}/content | 200 / 206 | generation: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 使用一張參考圖和 adaptive;generateAudio=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'請求引數
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
| model | string | 必填 | 取自 GET /v1/models 的 model;最小影片示例使用 seedance-2.5。 |
| prompt | string | 必填 | 1–4000 字元。全能參考可按陣列順序用 @Image1、@Image2 指代圖片。 |
| resolution | string | 可選 | 必須屬於所選模型的 resolutions;最小影片示例使用 480p。 |
| aspectRatio | string | 可選 | 必須屬於所選模型的 aspect_ratios。圖片模型同樣生效;當所選模型的首幀能力要求自適應畫幅時使用 adaptive。 |
| durationSeconds | integer | 可選 | 影片省略時使用模型最小時長;顯式值必須在目錄的 duration_seconds 區間內。最小示例使用 4 秒。 |
| referenceMode | first_frame | omni_reference | 使用影片參考圖時必填 | 只在目錄 reference_modes 明確列出的 Seedance 影片模型上使用。一次請求只能選擇一個模式。 |
| referenceImages | string[] | 與 referenceMode 同時填寫 | 公網 HTTPS 圖片 URL。first_frame 必須且只能 1 張;omni_reference 上限讀取 reference_images_max。 |
| inputImages | string[] | 可選 | 僅圖片模型的圖生圖輸入,可用 HTTPS 或 data:image/*;上限讀取 input_images_max,不得與影片參考模式混用。 |
| generateAudio | boolean | 可選 | 支援音訊的影片模型省略時預設 true。最經濟示例顯式傳 false;當前目錄沒有單列音訊附加價,計費始終以 GET /v1/models 為準。 |
| outputFormat | mp4 | mov | 可選 | 只能選擇目錄 output_formats 中的值;最小示例使用 mp4。 |
參考素材模式
first_frame
first_frame:參考圖成為起始畫面並決定構圖。必須且只能提交 1 張 referenceImages;aspectRatio 取自所選模型的 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 外,支援的模型還可傳 referenceVideos 與 referenceAudios;各類上限見下表,目錄未宣告的型別提交即 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"
}Live compatibility
接入方式對所有影片模型是同一套:同一個端點、同一組欄位,換模型只改 model。差異全部由目錄宣告——下表就是目錄本身,逐個模型列出它支援哪些參考模式、各類素材收幾個。目錄沒宣告的能力,提交時會被明確拒絕,不會靜默忽略。
First-frame details & last-frame relay
首幀細則:first_frame 與 omni_reference 互斥,同一請求只能選其一;omni 下可用提示詞間接引導某張參考圖作起始畫面,但需要嚴格首幀一致時,請使用 first_frame 模式提交那張圖。Seedance 2.5 的首幀任務畫幅固定 adaptive(輸出跟隨首幀)。尾幀接力:建立時傳 returnLastFrame: true,成功後任務額外返回 last_frame_url(與影片同寬高的無水印 PNG,保留 24 小時)——把這個 URL 直接作為下一單 first_frame 的 referenceImages,即可串聯多鏡頭連續敘事,無需任何預註冊步驟。
輪詢與下載
succeeded 與 failed 才是終態。submission_unknown 是待對賬狀態:保留原任務 ID,繼續輪詢,絕不能重放建立請求。成功後優先使用鑑權下載路徑 /content,不要依賴任何非 Open AIav 地址。產物保留 24 小時(詳情返回 output_expires_at 倒計時;過期後下載返回 410 OUTPUT_EXPIRED,請及時轉存)。
| Status | Terminal | Action |
|---|---|---|
| processing | No | 已受理;按 poll_after_ms 繼續查詢。 |
| result_pending | No | 輸出正在完成結算;繼續查詢同一任務。 |
| submission_unknown | No | 結果待對賬;不要重放建立請求,繼續保留並查詢原任務 ID。 |
| succeeded | Yes | 成功;使用 /content 下載輸出。 |
| failed | Yes | 確定失敗且預留金額已退回;讀取 error_code。 |
舊端點遷移
/v1/assets、/v1/assets/content、/v1/assets/{id}、/v1/asset-groups 與 /v1/asset-groups/{id} 已退役;使用有效金鑰及相應舊 scope 時返回 HTTP 410 / ENDPOINT_RETIRED。新接入不得呼叫這些路徑;把 referenceMode 與 referenceImages 放進同一次生成請求。錯誤碼對照
Full reference: HTTP status, code, meaning, suggested handling, and the SDK error class. This table shares its data source with the SDK error map; unknown new codes fall back by HTTP status in the SDK.
| HTTP | Code | 含義 | Suggested handling | SDK |
|---|---|---|---|---|
| 401 | UNAUTHENTICATED | Missing or unrecognized API key. | Send Authorization: Bearer oav_…; keep the key server-side. | AuthenticationError |
| 401 | INVALID_API_KEY | The API key is invalid or revoked. | Check the key in the console; rotate to mint a new one if needed. | AuthenticationError |
| 403 | INSUFFICIENT_SCOPE | The key lacks the scope this operation needs. | Creation needs generation:create; polling and download need generation:read. | PermissionError |
| 429 | RATE_LIMITED | Requests exceeded the key rate limit. | Back off per Retry-After / retryAfterSeconds; the SDK handles this automatically. | RateLimitError |
| 400 | IDEMPOTENCY_KEY_REQUIRED | Creation requires an Idempotency-Key header. | Generate a unique key per new request and reuse it on retries. The SDK auto-generates one. | InvalidRequestError |
| 409 | IDEMPOTENCY_KEY_CONFLICT | The same idempotency key was used with a different body. | Use a fresh key for different parameters; keep key and body identical on retries. | InvalidRequestError |
| 400 | MODEL_NOT_FOUND | Unknown model id. | Use ids from GET /v1/models (e.g. seedance-2.5-oa). | InvalidRequestError |
| 400 | INVALID_PROMPT | The prompt is empty or too long. | Prompts must be 1–4000 characters. | InvalidRequestError |
| 400 | INVALID_DURATION | durationSeconds is outside the model range. | Use an integer within the catalog range, or -1 when auto duration is supported. | InvalidRequestError |
| 400 | INVALID_RESOLUTION | The resolution is not supported by the model. | Pick a value from the catalog resolutions. | InvalidRequestError |
| 400 | INVALID_ASPECT_RATIO | The aspect ratio is not supported by the model. | Pick from catalog aspect_ratios; first_frame often locks adaptive. | InvalidRequestError |
| 400 | INVALID_REFERENCE_IMAGES | referenceImages must be an array of public HTTPS URLs. | Provide https:// image URLs readable for the task lifetime. | InvalidRequestError |
| 400 | INVALID_REFERENCE_IMAGE | A reference image entry is not a valid URL. | The message carries the index (referenceImages[i]); fix that entry. | InvalidRequestError |
| 400 | REFERENCE_IMAGE_URL_NOT_HTTPS | A reference image URL is not public HTTPS. | http, private-network and data URLs are rejected; host the image publicly over HTTPS. | InvalidRequestError |
| 400 | REFERENCE_MODE_REQUIRES_IMAGES | referenceMode was set without reference images. | Provide referenceMode and referenceImages together. | InvalidRequestError |
| 400 | REFERENCE_MODE_NOT_SUPPORTED | The model does not support the requested reference mode. | Choose first_frame / omni_reference per the catalog reference_modes. | InvalidRequestError |
| 400 | FIRST_FRAME_REQUIRES_ONE_IMAGE | first_frame takes exactly one reference image. | Submit exactly one image; use omni_reference for multiple. | InvalidRequestError |
| 400 | TOO_MANY_REFERENCES | Reference image count exceeds the catalog limit. | See reference_images_max in the catalog. | InvalidRequestError |
| 400 | INVALID_INPUT_IMAGES | inputImages must be an array. | Each item is an HTTPS URL or data:image/* base64. | InvalidRequestError |
| 400 | INVALID_INPUT_IMAGE | An input image entry is malformed. | Each entry must be an HTTPS URL or data:image/* base64; the message carries the index. | InvalidRequestError |
| 400 | INPUT_IMAGE_TOO_LARGE | An embedded image exceeds 10 MB. | Compress it or switch to a public HTTPS URL. | InvalidRequestError |
| 400 | IMAGE_INPUT_NOT_SUPPORTED | The model does not accept image input. | Only image models with input_images_max>0 accept inputImages. | InvalidRequestError |
| 400 | TOO_MANY_INPUT_IMAGES | Too many input images. | See input_images_max in the catalog. | InvalidRequestError |
| 400 | INSUFFICIENT_BALANCE | Balance is insufficient to reserve this task. | Redeem a top-up card on the Billing page, then retry. | InvalidRequestError |
| 400 | LEGACY_ASSET_REFERENCE_RETIRED | Asset-id references are retired. | Submit referenceMode + referenceImages (public HTTPS) in the same request. | InvalidRequestError |
| 404 | NOT_FOUND | The task does not exist or belongs to another account. | Confirm the task id and the key belong to the same account. | InvalidRequestError |
| 409 | OUTPUT_NOT_READY | The output is not ready yet. | Keep polling the task per poll_after_ms until terminal. | InvalidRequestError |
| 410 | OUTPUT_EXPIRED | The download window (24h after success) has closed. | Save outputs promptly; regenerate after expiry. Use output_expires_at for countdowns. | OutputExpiredError |
Console-session-only codes
| HTTP | Code | 含義 | Suggested handling |
|---|---|---|---|
| 400 | REFERENCE_UPLOAD_NOT_FOUND | The upload reference is missing, expired, or owned by another account. | Re-upload in the Playground and run again (uploads are short-lived). |
| 429 | UPLOAD_QUOTA_EXCEEDED | Too many unused uploads. | Run a task to consume uploads, or wait for them to expire. |
| 429 | WEBHOOK_ENDPOINT_LIMIT | Webhook endpoint limit reached. | Delete or disable an unused endpoint. |
| 400 | INVALID_WEBHOOK_URL | The callback URL is not publicly reachable HTTPS. | Use a public HTTPS address; private/loopback hosts are rejected. |