ドキュメント
動画生成
GoogleのVeo 3.1ファミリーで、テキストから動画、および画像から動画を生成します。API形式は2種類あります。単一のリクエストで完結し、クリップの準備ができるまで待機する同期エンドポイントと、本番環境のワークロード向けの送信・ポーリング用非同期エンドポイントのペアです。
エンドポイント:POST /v1/video/generations(同期、最初に説明)およびPOST /v1/videos + GET /v1/videos/{id}(非同期、本番環境に推奨)。モデルや長さに応じて生成には30秒から数分かかります。同期エンドポイントでは、クライアントのタイムアウトを十分長く設定してください(600sが安全です)。
テキストから動画
promptを渡してモデルを選択します。aspect_ratioは任意です。
import requests
resp = requests.post(
"https://api.kunavo.com/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "veo-3",
"prompt": "a cinematic dolly-in on a red origami crane unfolding, soft light",
"aspect_ratio": "16:9",
},
timeout=600, # video generation can take minutes
)
print(resp.json()["data"][0]["url"])duration(秒数)は、秒単位課金のモデル(Seedanceの各モデルとWan 2.7)でクリップの長さを指定します。Veoモデルでは無視されます。Veoのクリップはすべて8秒で、動画単位で課金されます。
# The models billed per second take a clip length: here 5 seconds of
# Seedance 2. Leave "duration" out and these models make a 5-second clip.
resp = requests.post(
"https://api.kunavo.com/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "seedance-2",
"prompt": "a paper crane unfolds into a flock of birds over a city at dawn",
"duration": 5,
"aspect_ratio": "16:9",
},
timeout=600,
)
print(resp.json()["data"][0]["url"])画像から動画
image_urlを追加すると、Veoはそれを基にアニメーションを生成します。デフォルトでは静止画が動画の最初のフレームになります。
# Image-to-video: animate a still image. The source image can be an
# https URL, or inline base64 — Kunavo hosts it for the model automatically.
resp = requests.post(
"https://api.kunavo.com/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "veo-3",
"prompt": "the crane gently lifts off the desk",
"image_url": "https://your-cdn.com/source.png",
},
timeout=600,
)
print(resp.json()["data"][0]["url"])image_urlにはhttps://のURL、またはインラインのdata: base64 URIを指定できます。base64はデコードされ、モデル実行前にKunavoのCDNで自動的にホストされます。最初のフレーム、最後のフレーム、参照画像
Veoが画像をどのように使うかはimage_modeで指定します。複数の画像を渡すにはimage_urls(配列)を指定します。
frame(デフォルト)— 画像が1枚なら最初のフレームに、2枚なら最初と最後のフレームになり、Veoがその間の遷移を生成します。reference— 最大3枚の画像をスタイルと被写体の参照として使用します。見た目の方向性を決めますが、フレームには表示されません。
# First + last frame: pass two images and Veo fills in the motion.
resp = requests.post(
"https://api.kunavo.com/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "veo-3",
"prompt": "a smooth transition between the two poses",
"image_urls": [
"https://your-cdn.com/first.png",
"https://your-cdn.com/last.png",
],
"image_mode": "frame",
},
timeout=600,
)ソースフレームをアップロードする
ローカルファイルしかない場合は、POST /v1/files経由で一度アップロードし、返された永続URLを再利用してください。
# No public URL? Upload the still first, then animate it.
with open("frame.png", "rb") as f:
up = requests.post(
"https://api.kunavo.com/v1/files",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": f},
).json()
resp = requests.post(
"https://api.kunavo.com/v1/video/generations",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "veo-3",
"prompt": "slow push-in, volumetric light",
"image_url": up["url"],
},
timeout=600,
)パラメーター
| パラメーター | 種類 | 注記 |
|---|---|---|
model | 文字列(必須) | /v1/ |
prompt | 文字列(必須) | ショットのテキスト説明。 |
image_url | string | 画像から動画を生成する場合の単一ソース画像。URLまたはdata: URI。 |
image_urls | string[] | 複数のソース画像(Veo)。image_ |
image_mode | string | Veo:"frame"(デフォルト — 最初/ |
duration | int | 秒単位課金のモデルでのクリップの長さ(秒)。省略時は5秒です。Seedance 2、Seedance 2 Fast、Seedance 2.0 Miniは4~15秒、Seedance 2.5は4~30秒、Wan 2.7は2~15秒に対応します。モデルの範囲外の長さは400エラーで拒否されます。Veoではこのパラメータは無視されます。Veoのクリップはすべて8秒です。 |
aspect_ratio | string | 例:"16:9"、"9:16"、"1:1"。 |
resolution | string | モデルで段階が提供されている場合の画質など(例:"720p"、"1080p")。 |
input | object | 代替手段 — 下記のRaw inputを参照。 |
生入力の直接指定
秒単位課金のモデルでは、inputはKunavoのアダプターが本来構築する入力の代わりに、記述どおりに上流へ送信されます。Veoモデルでは無視されます。
料金を決めるフィールドは例外です。resolutionは常にモデルの段階のいずれかとして送信され(省略された場合、またはいずれの段階にも該当しない場合は既定の段階)、durationはモデルの範囲内の整数秒である必要があります(それ以外の値は400エラーで拒否され、省略された場合は5が送信されます)。inputが設定されている場合、リクエスト自体のresolutionとdurationは読み取られません。
動画モデル
| スラッグ | プロバイダー | 注記 |
|---|---|---|
veo-3 | Veo 3.1 Fast — Qualityより高速で低価格、ネイティブ音声対応。 | |
veo-3-quality | Veo 3.1 Quality — 最高の忠実度。 | |
veo-3-lite | Veo 3.1 Lite — プレビュー向けの低価格帯。 | |
seedance-2-5 | ByteDance | Seedance 2.5 — 最大30秒のクリップ、マルチモーダル参照、秒単位の課金。 |
seedance-2 | ByteDance | Seedance 2 — マルチショットの一貫性、最大1080p、秒単位の課金。 |
seedance-2-fast | ByteDance | Seedance 2 Fast — 低価格帯、最大720p、秒単位の課金。 |
seedance-2-mini | ByteDance | Seedance 2.0 Mini — 最低価格帯、480p/ |
wan-2-7 | Alibaba | Wan 2.7 — 映画的なテキストから動画への生成、秒単位の課金。 |
最新のモデル一覧とモデルごとの価格は、必ず/modelsで確認してください。
レイテンシとタイムアウト
- Kunavoは、504を返す前に上流タスクを最大540秒間ポーリングします。
- 高速ティア(Veo 3.1 Fast / Lite):多くの場合30~90秒。
- Quality系および長時間の生成:2~5分。
- HTTPクライアントのタイムアウトは600s以上に設定してください。
- ネットワークが不安定な場合やモバイルクライアントでは、代わりに非同期APIを推奨します。送信は数秒で完了し、その後ポーリングして結果を取得できます。
非同期API(送信 + ポーリング)
エンドポイント:POST /v1/videos + GET /v1/videos/{id}。返されるタスクオブジェクトはOpenAIの動画オブジェクトのフィールド名とステータス値を使用し、さらにクリップのURLを含むoutputが追加されています。リクエスト本文は、上記のパラメーターを含むJSONです。
上記の同期エンドポイントは最大9分間HTTP接続を維持します。一度だけ実行するスクリプトには便利ですが、モバイルでは信頼性が低く、サーバー側では非効率です。非同期エンドポイントのペアは、すぐにvid_* IDを返します。statusがcompletedまたはfailedになるまで、GET /v1/videos/{id}をポーリングしてください。モデル、価格、アーカイブURLは同じです。
import requests, time
# 1. Submit — returns immediately with a task id. No long-lived connection.
submit = requests.post(
"https://api.kunavo.com/v1/videos",
headers={
"Authorization": f"Bearer {API_KEY}",
# Optional: retrying with the same key inside ~24h returns the
# original task rather than submitting again.
"Idempotency-Key": "my-task-uuid",
},
json={
"model": "veo-3",
"prompt": "a cinematic dolly-in on a red origami crane",
"aspect_ratio": "16:9",
},
timeout=60,
).json()
task_id = submit["id"] # "vid_abc..."
status = submit["status"] # "queued"
# 2. Poll until terminal. Recommended cadence: 5s, backing off to 30s.
while status not in ("completed", "failed"):
time.sleep(5)
r = requests.get(
f"https://api.kunavo.com/v1/videos/{task_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=30,
).json()
status = r["status"]
if status == "failed":
raise RuntimeError(r["error"]["message"])
print(r["output"]["url"])OpenAI SDKを使う場合は、以下のようにclient.postでそのリクエスト本文を送信し、client.getでポーリングしてください。SDK独自のclient.videos.createはここでは動作しません。このメソッドはSoraのパラメーターしか受け付けず、それらをマルチパートフォームとして送信します(Python SDKではバージョン2.27.0以降)。このエンドポイントは、そのマルチパートリクエストを400で拒否します。
import time
from openai import OpenAI
client = OpenAI(api_key=API_KEY, base_url="https://api.kunavo.com/v1")
# The same JSON body, sent with the client's own post().
task = client.post(
"/videos",
body={
"model": "veo-3",
"prompt": "a cinematic dolly-in on a red origami crane",
"aspect_ratio": "16:9",
},
# object hands back the JSON as parsed. Passing dict instead raises
# after the task has been created.
cast_to=object,
options={"headers": {"Idempotency-Key": "my-task-uuid"}},
)
while task["status"] not in ("completed", "failed"):
time.sleep(5)
task = client.get(f"/videos/{task['id']}", cast_to=object)
if task["status"] == "failed":
raise RuntimeError(task["error"]["message"])
print(task["output"]["url"])レスポンスの形式
| フィールド | 種類 | 注記 |
|---|---|---|
id | string | vid_ |
object | string | "video". |
status | string | queued | in_progress | completed | failed。 |
model | string | 送信したモデルのスラッグ。 |
created_at | int | 送信が受け付けられた時刻(Unix秒)。 |
completed_at | int | null | 終了した時刻(Unix秒)。処理中はnull。 |
expires_at | int | Unix秒。送信から30日後の時刻で、少なくともそれまではタスクをポーリングできます。結果のURLに有効期限はありません。 |
progress | int | 0~100。現在は終端状態になるまで0を返し、その後100になります。 |
output | object | null | 完了時: {url, urls[], duration_ |
error | object | null | 失敗時: {code, message}。 |
ヘッダーと規約
Idempotency-Key(任意、最大128文字)— 同じアカウントで同じキーを使って2回送信すると、重複タスクを作成せず、元のタスクが返されます。再試行ループに便利です。POST /v1/videosは新規送信時に202 Acceptedを返します。冪等性キーが一致し、以前の結果を再送する場合は200 OKを返します。GET /v1/videos/{id}は所有者単位で制限されています。他のアカウントに属するタスクを照会すると404が返されます。他のユーザーのIDが存在することを確認することはありません。- 推奨ポーリング間隔:5秒。指数バックオフで最大30秒まで延長します。モデルや解像度に応じて、通常30秒~5分でタスクが完了します。
どちらを使うか
| 同期 /v1/ | 非同期 /v1/videos | |
|---|---|---|
| 最適な用途 | 単発のスクリプト、ノートブック | 本番環境、モバイル、長時間実行ジョブ |
| ネットワーク | 接続を最大9分間維持 | 数秒で送信し、都合のよいタイミングでポーリング |
| 障害からの復旧 | レスポンスを失う = タスクを失う | 有効期限前であれば、いつでもIDを再照会できます |
| 同時実行数 | 呼び出しごとにサーバーワーカーを1つ使用 | 送信後すぐに接続を解放 |
| レスポンスの形式 | OpenAI /images/ | OpenAI /videos形式 |
レスポンスと保存先
レスポンスはOpenAI標準形式のdata[].urlです。URLは永続的なfiles.kunavo.comリンクです。Kunavoはすべての結果を独自CDNにアーカイブするため、上流から直接返されるURLと異なり、期限切れになりません。すべてのクリップは/app/assetsにも表示されます。