動画は POST /v1/videos で生成します。このエンドポイントには、Authorization: Bearer で送る API キーが必要です。認証を参照してください。本文は JSON です。
動画の生成には時間がかかるため、このエンドポイントは結果を待ちません。必ずジョブを伴う 202 を返します。結果は、ジョブをポーリングするか、webhook のイベントを受け取って得ます。同じ Idempotency-Key でリクエストを再び送った場合も同じで、ジョブがすでに終わっていても 202 を返します。
動画を作成する
Section titled “動画を作成する”モデルとプロンプトを送ります。例では、sakuranbo/cherry-1.0-pro を使います。
curl -X POST "https://api.sakuranbo.ai/v1/videos" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SAKURANBO_API_KEY" \ -d '{ "model": "sakuranbo/cherry-1.0-pro", "prompt": "Aerial shot gliding over a misty mountain lake at sunrise, gentle wind and birdsong", "duration": 5, "resolution": "1080p", "aspect_ratio": "16:9"}'const response = await fetch("https://api.sakuranbo.ai/v1/videos", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.SAKURANBO_API_KEY}`, }, body: JSON.stringify({ "model": "sakuranbo/cherry-1.0-pro", "prompt": "Aerial shot gliding over a misty mountain lake at sunrise, gentle wind and birdsong", "duration": 5, "resolution": "1080p", "aspect_ratio": "16:9" }),});const data = await response.json();console.log(data);import os
import requests
response = requests.post( "https://api.sakuranbo.ai/v1/videos", headers={ "Authorization": f"Bearer {os.environ['SAKURANBO_API_KEY']}", }, json={ "model": "sakuranbo/cherry-1.0-pro", "prompt": "Aerial shot gliding over a misty mountain lake at sunrise, gentle wind and birdsong", "duration": 5, "resolution": "1080p", "aspect_ratio": "16:9", },)print(response.json())例のモデルの入力パラメータは次のとおりです。
| 名前 | 型 | 必須 | 既定値 | 制約 | 説明 |
|---|---|---|---|---|---|
prompt | string | はい | 最大 20,000 文字 | 場面、動き、音声の説明。 | |
first_frame | url | いいえ | 最初のフレームに使う画像(image-to-video)。 | ||
last_frame | url | いいえ | 最後のフレームに使う画像。first_frame と組み合わせて使います。 | ||
reference_images | url[] | いいえ | 最大 10 件 | 最大 10 枚の参照画像。キーフレームとは併用できません。 | |
duration | integer | いいえ | 5 | 2〜30 | 動画の長さ(秒)。秒単位で課金されます。 |
resolution | enum | いいえ | 1080p | 次のいずれか: 1080p, 2k, 4k | 出力解像度。1 秒あたりの価格が決まります。 |
aspect_ratio | enum | いいえ | adaptive | 次のいずれか: adaptive, 16:9, 9:16, 1:1, 4:3, 3:4 | 出力動画のアスペクト比。 |
audio | boolean | いいえ | true | 音声トラックを生成します。音声の有無で価格は変わりません。 |
リクエスト本文には、次のフィールドがあります。
| 名前 | 型 | 必須 | 既定値 | 制約 |
|---|---|---|---|---|
model | string | はい | 1〜128 文字 | |
prompt | string | はい | ||
first_frame | string | いいえ | ||
last_frame | string | いいえ | ||
reference_images | string[] | いいえ | ||
duration | number | いいえ | ||
resolution | string | いいえ | ||
aspect_ratio | string | いいえ | ||
audio | boolean | いいえ |
表にないパラメータや、範囲外の値を指定すると、400 と invalid_request を返します。error.param にパラメータの名前が入り、error.details.allowed、error.details.minimum、error.details.maximum に有効な値が入ります。
送るフィールドによって、動画の作り方が決まります。
promptだけを送ると、テキストから動画を生成します。first_frameを送ると、画像から始まる動画を生成します。last_frameも送ると、画像で終わる動画になります。last_frameにはfirst_frameが必要です。reference_imagesを送ると、画像を参照として使う動画を生成します。プロンプトで 1 枚目や 2 枚目の画像を指せるため、順番が意味を持ちます。reference_imagesは、first_frameやlast_frameと組み合わせられません。
画像の指定には、公開された https の URL か、data:image/...;base64, の URI を使います。画像の形式は PNG、JPEG、WebP、GIF です。data URI のサイズ上限は URL より小さいので、大きな画像は公開された URL で送ってください。サーバーは、ジョブを作る前に、各 URL を取得して確認します。リダイレクトには従わず、認証情報、IP アドレス、内部向けのホスト名を含む URL は拒否します。使えない画像を指定すると、400 と invalid_request を返します。error.param にフィールドの名前が入ります。URL では、error.details.reason に問題の内容が入ります。大きすぎる data URI では、error.details.max_bytes に上限が入ります。
202 のレスポンスは、ジョブに 2 つのフィールド polling_url と eta_seconds を加えたものです。object は video です。
| 名前 | 型 |
|---|---|
id | string |
object | string |
model | string |
status | string |
progress | integer | null |
created_at | string |
completed_at | string | null |
expires_at | string | null |
error | object | null |
outputs | object[] |
usage | object | null |
cost | object | null |
polling_url | string |
eta_seconds | integer | null |
progress と eta_seconds は、経過時間から見積もった値です。期限や課金の根拠として使わないでください。Location ヘッダと polling_url は、どちらもその動画を指します。
status が completed、failed、cancelled、expired のいずれかになるまで、数秒おきに GET /v1/videos/{id} をポーリングします。polling_url は、このリクエストの URL です。失敗したジョブも 200 を返し、理由は error に入ります。ステータスについては、ジョブを参照してください。
curl "https://api.sakuranbo.ai/v1/videos/job_0123456789abcdef0123456789abcdef" \ -H "Authorization: Bearer $SAKURANBO_API_KEY"const response = await fetch("https://api.sakuranbo.ai/v1/videos/job_0123456789abcdef0123456789abcdef", { headers: { Authorization: `Bearer ${process.env.SAKURANBO_API_KEY}`, },});const data = await response.json();console.log(data);import os
import requests
response = requests.get( "https://api.sakuranbo.ai/v1/videos/job_0123456789abcdef0123456789abcdef", headers={ "Authorization": f"Bearer {os.environ['SAKURANBO_API_KEY']}", },)print(response.json())ポーリングを避けるには、webhook のエンドポイントを登録して、job.succeeded、job.failed、job.cancelled のイベントを受け取ります。Webhookを参照してください。
制限時間内に終わらなかったジョブは expired になります。課金されません。
モデルの提供元が混み合っていることは、POST /v1/videos の HTTP ステータスには現れません。あとで、ジョブの error フィールドに、コード rate_limited または concurrency_limited として現れます。少し待ってから、動画をもう一度作成してください。
モデルの提供元が、プロンプトや参照画像を、その内容を理由に拒否することもあります。この場合も HTTP ステータスには現れず、ジョブがコード content_policy_violation で失敗します。課金はされません。
ファイルをダウンロードする
Section titled “ファイルをダウンロードする”完了したジョブの outputs には、項目が 1 つ入ります。その url は署名付き URL で、API キーは不要で、expires_at まで使えます。expires_at は、ジョブが完了してから 7 日後です。それまでは、URL を知っていれば誰でもファイルをダウンロードできるため、URL は秘密として扱ってください。expires_at を過ぎるとファイルは削除されるため、必要な動画は保存してください。
API キーを付けて GET /v1/videos/{id}/content を呼び出すこともできます。署名付き URL へのリダイレクトで応答するため、クライアントはリダイレクトに従う必要があります。ジョブにファイルがないときは 404 を返し、error.details.status にジョブのステータスが入ります。これは、ジョブがまだ実行中のとき、失敗、キャンセル、時間切れになったとき、そしてファイルがすでに削除されているときに起こります。
動画を一覧し、キャンセルする
Section titled “動画を一覧し、キャンセルする”動画は GET /v1/videos で新しい順に一覧できます。パラメータ limit、cursor、status は、ジョブの一覧と同じです。待機中または実行中の動画は POST /v1/videos/{id}/cancel でキャンセルします。どちらも、ジョブのエンドポイントの規則に従います。ジョブを参照してください。
安全に再試行する
Section titled “安全に再試行する”自分で決めた値の Idempotency-Key ヘッダを送ります。同じキーと同じ内容のリクエストが再び届くと、同じジョブが返り、課金は 1 回だけです。同じキーで内容の違うリクエストを送ると、409 と idempotency_conflict を返します。キーは一定の期間だけ記憶され、その期間は API リファレンスに載っています。
リクエストが受理されると、Sakuranbo AI は、見積もった価格を残高から確保します。見積は duration と resolution から出します。ジョブが完了すると、依頼した duration の分を、resolution の 1 秒あたりの価格で課金します。これは、確保した金額と同じです。キャンセルされたジョブと時間切れになったジョブは課金されません。失敗したジョブも、通常は課金されず、確保した金額は残高に戻ります。
まれに、リクエストがモデルの提供元に届いたかどうかを、Sakuranbo AI が確認できないことがあります。その場合、ジョブは upstream_error で失敗し、確保した金額は、課金されるかどうかを Sakuranbo AI が確認するまで確保されたままになります。確保されたままのときは、ジョブ ID を添えてサポートにお問い合わせください。
価格は、モデルカタログと料金のページで確認するか、実行する前に POST /v1/estimate で計算してください。見積 APIを参照してください。
| コード | HTTP ステータス | 種別 | 説明 |
|---|---|---|---|
invalid_request | 400 | invalid_request_error | リクエストの形式が不正か、値が範囲外です。有効な値が分かる場合は details.allowed に入ります。 |
unauthorized | 401 | authentication_error | API キーが指定されていない、形式が不正、存在しない、失効済み、または期限切れです。レスポンスからは、どれに当たるかは分かりません。 |
balance_insufficient | 402 | insufficient_balance | 利用可能な残高が、このリクエストのために確保する金額に足りません。error.details.limit_source は balance です。 |
key_limit_exceeded | 402 | insufficient_balance | このリクエストを受理すると、API キーの利用上限を超えます。error.details.limit_source は key で、error.details.resets_at にカウンターが数え直される時刻が入ります。 |
account_suspended | 403 | permission_error | アカウントが停止されているため、画像・動画・チャットのリクエストを受け付けません。サポートにお問い合わせください。残高、入金、API キー、ジョブは引き続き利用できます。 |
model_not_found | 404 | not_found_error | 指定したモデル ID がカタログにありません。チャットのエンドポイントは、テキストモデルでないモデルに対しても、このコードを返します。 |
idempotency_conflict | 409 | conflict_error | 同じ Idempotency-Key が、別の内容のリクエストで使われています。 |
payload_too_large | 413 | invalid_request_error | リクエスト本文が、許容サイズを超えています。error.details.max_bytes に上限が入ります。 |
upstream_unavailable | 503 | overloaded_error | 上流の提供元が一時的に容量不足です。時間をおいて再試行してください。 |
429 または 503 のレスポンスでは、Retry-After ヘッダの秒数だけ待ってから再試行してください。402 のレスポンスには error.details.limit_source が入り、値は balance か key です。残高とキーの利用上限を参照してください。すべてのコードは、エラーを参照してください。
価格はすべて USD 表示です。表示価格には当社のマージンを含みます。