ドキュメント

ドキュメント

動画生成

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/modelsから取得した動画モデルのslug。
prompt文字列(必須)ショットのテキスト説明。
image_urlstring画像から動画を生成する場合の単一ソース画像。URLまたはdata: URI。
image_urlsstring[]複数のソース画像(Veo)。image_urlより優先されます。
image_modestringVeo:"frame"(デフォルト — 最初/最後のフレーム)または"reference"(スタイル参照)。
durationint秒単位課金のモデルでのクリップの長さ(秒)。省略時は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_ratiostring例:"16:9"、"9:16"、"1:1"。
resolutionstringモデルで段階が提供されている場合の画質など(例:"720p"、"1080p")。
inputobject代替手段 — 下記のRaw inputを参照。

生入力の直接指定

秒単位課金のモデルでは、inputはKunavoのアダプターが本来構築する入力の代わりに、記述どおりに上流へ送信されます。Veoモデルでは無視されます。

料金を決めるフィールドは例外です。resolutionは常にモデルの段階のいずれかとして送信され(省略された場合、またはいずれの段階にも該当しない場合は既定の段階)、durationはモデルの範囲内の整数秒である必要があります(それ以外の値は400エラーで拒否され、省略された場合は5が送信されます)。inputが設定されている場合、リクエスト自体のresolutionとdurationは読み取られません。

動画モデル

スラッグプロバイダー注記
veo-3GoogleVeo 3.1 Fast — Qualityより高速で低価格、ネイティブ音声対応。
veo-3-qualityGoogleVeo 3.1 Quality — 最高の忠実度。
veo-3-liteGoogleVeo 3.1 Lite — プレビュー向けの低価格帯。
seedance-2-5ByteDanceSeedance 2.5 — 最大30秒のクリップ、マルチモーダル参照、秒単位の課金。
seedance-2ByteDanceSeedance 2 — マルチショットの一貫性、最大1080p、秒単位の課金。
seedance-2-fastByteDanceSeedance 2 Fast — 低価格帯、最大720p、秒単位の課金。
seedance-2-miniByteDanceSeedance 2.0 Mini — 最低価格帯、480p/720pのみ。下書きや大量生成向け。
wan-2-7AlibabaWan 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"])

レスポンスの形式

フィールド種類注記
idstringvid_で始まるタスクID。上流の変更後も安定しています。
objectstring"video".
statusstringqueued | in_progress | completed | failed。
modelstring送信したモデルのスラッグ。
created_atint送信が受け付けられた時刻(Unix秒)。
completed_atint | null終了した時刻(Unix秒)。処理中はnull。
expires_atintUnix秒。送信から30日後の時刻で、少なくともそれまではタスクをポーリングできます。結果のURLに有効期限はありません。
progressint0~100。現在は終端状態になるまで0を返し、その後100になります。
outputobject | null完了時: {url, urls[], duration_seconds, resolution}。duration_secondsはモデルにリクエストしたクリップの長さで、Veoではnullです。resolutionはクリップの解像度の段階で、段階が記録されていない場合はnullです。
errorobject | 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/video/generations非同期 /v1/videos
最適な用途単発のスクリプト、ノートブック本番環境、モバイル、長時間実行ジョブ
ネットワーク接続を最大9分間維持数秒で送信し、都合のよいタイミングでポーリング
障害からの復旧レスポンスを失う = タスクを失う有効期限前であれば、いつでもIDを再照会できます
同時実行数呼び出しごとにサーバーワーカーを1つ使用送信後すぐに接続を解放
レスポンスの形式OpenAI /images/generations形式OpenAI /videos形式

レスポンスと保存先

レスポンスはOpenAI標準形式のdata[].urlです。URLは永続的なfiles.kunavo.comリンクです。Kunavoはすべての結果を独自CDNにアーカイブするため、上流から直接返されるURLと異なり、期限切れになりません。すべてのクリップは/app/assetsにも表示されます。

次に確認する項目