Night city street after rain, seen from a slow forward dolly shot at low height: wet asphalt reflecting colorful lights, light trails from passing cars, soft steam rising from a street grate, light drizzle. Generic modern architecture. No people, no readable text, signs, logos, license plates, flags or recognizable landmarks. Cinematic, realistic.
見積もり、タスク作成、状態確認の順に進み、完成した動画をダウンロードします。作成リクエストを再試行する際は、同じ冪等性キーを使ってください。受け付けられたタスクはまだ処理中です。完了してからダウンロードしてください。最小限のサンプルです。本番環境では、再起動後に再開できるように Idempotency-Key とタスク ID を永続化してください。
AIエージェントへの指示を表示
ユーザーのアプリに BetterToken 動画 API を組み込んでください。
BETTERTOKEN_API_KEY は環境変数からのみ読み取り、コードへの埋め込み、ログ記録、分析への送信はしないでください。
ベース URL: https://bettertoken.ai/v1
モデル: kling-3.0.
プロンプト: A rainy city street at night, slow forward camera move
下記のリクエストJSONをそのまま使い、選択したモデルの対応フィールドと制限に従ってください。
同じリクエストで POST /videos/quote を呼ぶと、残高を予約せずに見積もりを取得できます。認証が必要であり、公開料金エンドポイントではありません。
POST /videos の前に、新しい Idempotency-Key と正確なリクエスト本文をプロセス外へ永続保存してください。再起動後は保存状態を読み込むか、受理済みタスクの保存 ID で再開します。応答が不明な場合も同じキーと本文を再利用し、タイムアウトだけを理由に別の有料タスクを作らないでください。
/videos の 202 受理後(互換ルートは 200)、id を保存し、5 秒ごとに GET /videos/{id} を確認します。queued、in_progress、completed、failed、canceled を処理してください。送信結果が不明なタスクは stage=reconciliation の in_progress のままです。代替タスクを作らないでください。429 では Retry-After に従います。5 秒間隔で最大 360 回確認しますが、通信遅延やレート制限の待機で全体の時間が延びる場合があります。確認を停止するときも ID を保存してください。確認の停止はタスクのキャンセルや再作成ではありません。
completed 後、所有者の許可された API キーで GET /videos/{id}/content を呼びます。期限切れのファイルは 410 video_artifact_expired を返します。動画は非公開です。ダウンロードの失敗や期限切れは生成失敗と分けて処理してください。
最終請求は課金明細で確認してください。生成の失敗またはキャンセルが確認された場合、財務処理により元の支払い元へ予約額が解放または返金されます。タスク状態だけで返金完了とは判断できません。送信結果の不明状態と生成後の配信障害も別々に扱ってください。
relay のエラーは error にあります。402 video_insufficient_balance、409 video_idempotency_conflict/video_acceptance_pending、422 はパラメータ不正、503 は受理不明または利用不可です。応答が不明な場合は元のキーと本文を保持してください。Web 会員プランやページ内生成 UI は追加しないでください。
{
"model": "kling-3.0",
"operation": "text_to_video",
"prompt": "A rainy city street at night, slow forward camera move",
"duration": {
"mode": "fixed",
"seconds": 5
},
"output": {
"format": "mp4",
"aspect_ratio": "16:9"
},
"provider_options": {
"kling": {
"mode": "std"
}
},
"audio": {
"mode": "off"
}
}
# Minimal example: persist the Idempotency-Key and task ID in production.
# Requires curl, jq and BETTERTOKEN_API_KEY in your environment.
BASE=https://bettertoken.ai/v1
IDEM="$(uuidgen)"
cat > request.json <<'JSON'
{
"model": "kling-3.0",
"operation": "text_to_video",
"prompt": "A rainy city street at night, slow forward camera move",
"duration": {
"mode": "fixed",
"seconds": 5
},
"output": {
"format": "mp4",
"aspect_ratio": "16:9"
},
"provider_options": {
"kling": {
"mode": "std"
}
},
"audio": {
"mode": "off"
}
}
JSON
curl --fail-with-body "$BASE/videos/quote" \
-H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
-H 'Content-Type: application/json' --data-binary @request.json || exit 1
TASK=$(curl --fail-with-body "$BASE/videos" \
-H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
-H "Idempotency-Key: $IDEM" \
-H 'Content-Type: application/json' --data-binary @request.json) || exit 1
ID=$(printf '%s' "$TASK" | jq -er '.id') || exit 1
# Poll up to 360 times, waiting 5 seconds between requests.
# Network delays can extend the total time.
for attempt in $(seq 1 360); do
TASK=$(curl --fail-with-body "$BASE/videos/$ID" \
-H "Authorization: Bearer $BETTERTOKEN_API_KEY") || exit 1
STATUS=$(printf '%s' "$TASK" | jq -r '.status')
case "$STATUS" in
completed) break ;;
failed|canceled) printf '%s\n' "$TASK"; exit 1 ;;
esac
sleep 5
done
[ "$STATUS" = completed ] || { echo "Resume polling task: $ID"; exit 1; }
curl --fail-with-body "$BASE/videos/$ID/content" \
-H "Authorization: Bearer $BETTERTOKEN_API_KEY" -o video.mp4