video_urlstring必須続きを作りたい動画です。MP4、MOV、WebM で、60 秒までです。最後のフレームが新しいセグメントの開始フレームになるので、きれいで鮮明なフレームで切ってください。元の動画は課金されません。
- デフォルト値
- 指定なし
- 制約
- minLength:1format:"uri"contentMediaType:["video/mp4","video/webm","video/quicktime"]
bytedance/seedance-2.0-mini/video-extendSeedance 2.0 Mini で動画の続きを作ります。動画の最後のフレームから 4 秒から 15 秒の新しいセグメントが始まり、音も付き、元の動画と続きをつないだ 1 つのファイルが 480p か 720p で返ります。
例は、選択中のエンドポイントの公開パラメーター定義から作っています。API キーとサンプル素材を差し替えて、ご自身のサーバーから送信してください。
SDK・連携https://api.spicyapi.ai/api/v1/jobs/createTaskAPI キーはサーバーの環境変数 SPICY_API_KEY に保存します。Bearer 認証を使用し、JSON リクエストには Content-Type: application/json を指定してください。
Authorization: Bearer $SPICY_API_KEY# Generate the idempotency key once; reuse it when retrying after a lost response.
export SPICY_IDEMPOTENCY_KEY="${SPICY_IDEMPOTENCY_KEY:-$(uuidgen)}"
curl -X POST https://api.spicyapi.ai/api/v1/jobs/createTask \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
-d '{
"model": "bytedance/seedance-2.0-mini/video-extend",
"input": {
"bitrate_mode": "standard",
"duration_seconds": 5,
"enable_web_search": false,
"generate_audio": true,
"resolution": "720p",
"video_url": "https://example.com/reference.mp4"
}
}'
# Copy data.taskId from the response into TASK_ID, then poll the status.
TASK_ID="TASK_ID_FROM_RESPONSE"
curl "https://api.spicyapi.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
-H "Authorization: Bearer $SPICY_API_KEY"このモデルの入力スキーマから生成した例です。API はどのリクエストも、同じスキーマで検証します。
これらのフィールドは、リクエスト本文の input オブジェクトに指定します。名前と型は API と一致します。デフォルト値の指定がない項目に、デフォルト値があると想定しないでください。
video_urlstring必須続きを作りたい動画です。MP4、MOV、WebM で、60 秒までです。最後のフレームが新しいセグメントの開始フレームになるので、きれいで鮮明なフレームで切ってください。元の動画は課金されません。
watermarkboolean任意新しいセグメントに、モデル自身の「AI generated」の透かしを表示します。既定はオフです。公開先が AI 生成の映像へのラベル付けを求めるときにオンにしてください。価格には影響しません。
bitrate_modestring任意モデルが納品する新しいセグメントのエンコードビットレートで、`standard`(既定)か `high` です。high は細かい質感と速い動きをより鮮明に保ち、セグメントのファイルがかなり大きくなります。つないだファイルはプラットフォームが再エンコードします。価格には影響しません。
"standard""high"seedinteger任意0 から 2147483647 の整数です。省略すると実行ごとに別の値になります。変えた項目の影響を 1 つずつ比べるときに固定してください。比較のための道具であり、フレーム単位で同じ結果になる保証ではありません。
enable_web_searchboolean任意料金に影響既定はオフです。オンにすると、モデルは新しいセグメントを描く前に、プロンプトに関連する情報をウェブで検索することがあります。オンのリクエストは標準より高いウェブ検索料金で課金され、送信前に表示される見積もりにはすでに含まれています。
generate_audioboolean任意既定はオンで、新しいセグメントに生成された音が付きます。この料金帯ではオフにしても価格は下がりません。元の動画の音はどちらの設定でも残り、片側が無音のときはつないだファイルを無音で補います。
duration_secondsinteger任意料金に影響新しいセグメントの長さで、整数秒の 4 から 15、またはモデルに任せる -1 です。-1 のときは先に 15 秒分を確保し、実際に納品された長さで精算します。既定は 5 です。元の動画は手前に加わり、課金されません。
-1456789101112131415resolutionstring任意料金に影響新しいセグメントのサイズで、480p または 720p、既定は 720p です。元の動画に合わせてください。この設定は新しい部分の画質だけを決めるので、低くすると新しい部分が元よりやわらかく見えます。つないだファイルは元のクリップの画角を保ち、黒帯は入りません。つなぎ目を合わせるため、映像の端が数パーセントほど切り取られたり、微調整されたりすることがあります。モデルが返した映像の縦横比が大きく異なる場合は、新しいセグメントを画面いっぱいに拡大して中央に合わせ、はみ出した部分を切り取ります。価格を決める項目です。
"480p""720p"last_image_urlstring任意任意の目標終了フレームです。新しいセグメントは、モデルが決めた場所ではなく、この画像で終わります。トランジションや、見覚えのあるフレームへの回帰に便利です。動画の最後のフレームと同じ比率にしてください。違うと合わせて切り取られます。各辺は 300 から 6000 ピクセルで、これより小さい画像は課金前の入力チェックで拒否されます。
promptstring任意任意です。このあと起きること、つまり続く動き、カメラの動き、音を書きます。省略すると、モデルが最後のフレームから動きを決めます。被写体と場面は開始フレームですでに決まっているので、言葉は動きに使ってください。
{
"additionalProperties": false,
"properties": {
"bitrate_mode": {
"default": "standard",
"description": "Encoding bitrate of the new segment: standard, or high for crisper detail and a larger file.",
"enum": [
"standard",
"high"
],
"type": "string",
"x-ui": {
"advanced": true,
"affects_price": false,
"order": 24,
"widget": "radio"
}
},
"duration_seconds": {
"default": 5,
"description": "Length of the new segment in seconds. The source clip is added on top and is not billed.",
"enum": [
-1,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15
],
"type": "integer",
"x-ui": {
"advanced": false,
"affects_price": true,
"enum_labels": {
"-1": "Smart"
},
"order": 50,
"unit": "s",
"widget": "slider"
}
},
"enable_web_search": {
"default": false,
"description": "Let the model search the web for information related to the prompt before rendering. Requests with it on are billed at the web-search rate.",
"type": "boolean",
"x-ui": {
"advanced": true,
"affects_price": true,
"order": 35,
"widget": "switch"
}
},
"generate_audio": {
"default": true,
"description": "Generate sound for the new segment. The source keeps its own sound either way.",
"type": "boolean",
"x-ui": {
"advanced": false,
"affects_price": true,
"order": 40,
"widget": "switch"
}
},
"last_image_url": {
"contentMediaType": [
"image/jpeg",
"image/png",
"image/webp",
"image/gif"
],
"description": "Optional target end frame: the new segment lands on this picture.",
"type": "string",
"x-ui": {
"advanced": true,
"order": 80,
"widget": "upload"
}
},
"prompt": {
"description": "Describe what happens next: the action that follows, the camera move and the sound.",
"minLength": 1,
"type": "string",
"x-ui": {
"order": 100,
"primary": false,
"widget": "textarea"
}
},
"resolution": {
"default": "720p",
"description": "Resolution of the new segment; match your source clip.",
"enum": [
"480p",
"720p"
],
"type": "string",
"x-ui": {
"advanced": false,
"affects_price": true,
"order": 60,
"widget": "radio"
}
},
"seed": {
"description": "Random seed. Omit to let the model pick one.",
"maximum": 2147483647,
"minimum": 0,
"type": "integer",
"x-ui": {
"affects_price": false,
"order": 30,
"widget": "number"
}
},
"video_url": {
"contentMediaType": [
"video/mp4",
"video/webm",
"video/quicktime"
],
"description": "The clip to continue: MP4, MOV or WebM, up to 60 seconds. Its final frame becomes the opening frame of the new segment, and the result is your clip with the new segment joined on.",
"format": "uri",
"minLength": 1,
"type": "string",
"x-ui": {
"max_duration_seconds": 60,
"order": 90,
"primary": true,
"widget": "upload"
}
},
"watermark": {
"default": false,
"description": "Add the model’s visible \"AI generated\" watermark to the new segment.",
"type": "boolean",
"x-ui": {
"advanced": true,
"affects_price": false,
"order": 22,
"widget": "switch"
}
}
},
"required": [
"video_url"
],
"type": "object",
"x-pricing": {
"billingMode": "duration_capped",
"variantFields": [
"resolution",
"generate_audio",
"enable_web_search"
],
"variantKeyOmitDefaults": [
"enable_web_search"
]
}
}HTTP 202 はタスクを受け付けたという意味で、生成が終わったという意味ではありません。返ってきた taskId を保存し、そのタスクの状態を問い合わせてください。結果を待っている間に、同じ内容でタスクを作り直さないでください。
HTTP/1.1 202 Accepted
Location: /api/v1/jobs/recordInfo?taskId=job_01k3m8x9q2z4v7n5p6r8s0t1w3
{
"code": 200,
"msg": "success",
"request_id": "req_example_create",
"data": {
"taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
"state": "queued",
"estimatedCost": "0.750000"
}
}受理レスポンスには今回の概算料金が含まれるため、アプリのタスク履歴と請求画面に同じ金額を表示できます。
curl --get "https://api.spicyapi.ai/api/v1/jobs/recordInfo" \
--data-urlencode "taskId=$TASK_ID" \
-H "Authorization: Bearer $SPICY_API_KEY"ポーリングは約 2 秒間隔から始め、徐々に間隔を延ばします。終了状態になったら止めてください。通信が切れたときも、元の taskId で状態を確認します。作成をやり直すときは、同じ冪等キーと同じ本文をそのまま使い回してください。
import { verifyWebhook } from "@spicyapi/sdk";
// express.raw keeps the bytes we signed; express.json never matches.
app.post("/hooks/spicy", express.raw({ type: "application/json" }), (req, res) => {
const { payload } = verifyWebhook({
rawBody: req.body,
timestamp: req.header("X-Webhook-Timestamp"),
signature: req.header("X-Webhook-Signature"),
payloadVersion: Number(req.header("X-Webhook-Payload-Version")),
secret: process.env.SPICY_WEBHOOK_SECRET,
});
res.status(200).end();
void handleFinishedTask(payload);
});タスク作成時に callBackUrl を渡せば、完了したレコードが POST で届きます——ポーリングは一切不要です。配信には毎回 X-Webhook-Timestamp、X-Webhook-Signature、X-Webhook-Payload-Version が付きます。署名は taskId.timestamp.sha256(body) に対する HMAC-SHA256(base64)なので、生のバイト列で検証してください。JSON を解析して再度文字列化するとバイト列が変わり、検証は必ず失敗します。失敗した配信は再送されるため同じ taskId が二度届くことがあります。ハンドラーは冪等に。まず 2xx を返し、処理はその後で——応答が遅いと配信失敗として扱われます。
output を読むのは、state が succeeded のときだけにしてください。失敗したときは errorCode、errorMessage、request_id を手がかりに調べます。例に出ている料金や状態は、実際の請求ではありません。
{
"code": 200,
"msg": "success",
"request_id": "req_example_record",
"data": {
"taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
"model": "bytedance/seedance-2.0-mini/video-extend",
"state": "succeeded",
"output": {
"assets": [
{
"key": "tasks/2026/08/28/job_01k3m8x9q2z4v7n5p6r8s0t1w3/3f7a1c9e5b2d48f0a6c1e3d5b7f9a1c3.mp4",
"mime": "video/mp4",
"url": "https://example.r2.cloudflarestorage.com/results/job_01k3m8x9q2z4v7n5p6r8s0t1w3/result.mp4?X-Amz-Signature=SIGNATURE_FROM_RESPONSE",
"expiresAt": "2026-08-28T12:20:08.000Z"
}
]
},
"cost": "0.750000",
"settled": true,
"createdAt": "2026-08-28T12:00:00Z",
"completedAt": "2026-08-28T12:00:30Z"
}
}利用可能なファイルは assets[].url からそのまま開くか、ダウンロードできます。API の Authorization ヘッダーは不要です。署名付き URL は expiresAt で失効しますが、保存期間内であればタスクを再取得することで更新できます。処理中または利用できないファイルに URL はありません。署名付き URL は非公開情報として扱ってください。
アプリ、ターミナル、AI アシスタント、ビジュアルワークフローで SpicyAPI を活用。接続ガイドを選んでください。
上のコードを書く必要はありません。MCP サーバーを 1 回接続すれば、MCP に対応するエージェント(Claude Code、Codex、Cursor、Windsurf、VS Code、Gemini CLI、Cline、LibreChat)がこのモデルを名前で実行できます。シェルから 1 つのコマンドで実行することもできます。
Use bytedance/seedance-2.0-mini/video-extend to make a five-second shot of a neon-lit rooftop at dusk, slow push-in, and save it to ./out/.
エージェントは公開カタログからモデルを引き、ローカルファイルを代わりにアップロードし、正確な見積もりと上限額を示して確認を待ちます。承認するまで課金は発生しません。
claude mcp add spicyapi -e SPICY_API_KEY=$SPICY_API_KEY \
-- npx --yes --package=@spicyapi/mcp spicyapi-mcp
npx skills add spicyapi-ai/spicy-skill1 行目でツールを、2 行目で Skill を渡します。Skill は使い方の取り決めです——課金の前に見積もりを取り、ローカルファイルはバイト列を貼らずにアップロードし、完成した成果物の URL を推測せずに読む。ほかのクライアントも同じサーバーをそれぞれの設定ファイルから使います。開発者向けページをご覧ください。
npx @spicyapi/cli tasks create --model bytedance/seedance-2.0-mini/video-extend \
--input-json '{"bitrate_mode":"standard","duration_seconds":5,"enable_web_search":false,"generate_audio":true,"resolution":"720p","video_url":"https://example.com/reference.mp4"}' \
--wait入力は上の例と同じ、このエンドポイント固有のスキーマに従います。--wait はタスクの完了までポーリングして結果を表示します。CI では --yes を追加すると確認を省略できます。先に SPICY_API_KEY を設定してください。API、CLI、MCP サーバーで同じキーを使えます。
npx @spicyapi/cli files upload ./poster.png
# -> spicy://uploads/01k3m8x9q2z4v7n5p6r8s0t1w3
npx @spicyapi/cli tasks create --model bytedance/seedance-2.0-mini/video-extend \
--input-json '{"video_url":"spicy://uploads/01k3m8x9q2z4v7n5p6r8s0t1w3"}' \
--waitリクエストが受け取るのは URL であってバイト列ではありません。先にアップロードし、出力される spicy:// URI を渡してください。上のフィールド名はこのエンドポイントのスキーマから取ったものです。MCP 経由のエージェントはこの手順を代わりに済ませます——前述の一文が ./poster.png をそのまま指せるのはそのためです。公開 HTTPS で参照できるメディアならアップロードは不要です。
npx @spicyapi/cli tasks create --model bytedance/seedance-2.0-mini/video-extend \
--input-json '{…}' --retention 1h --wait
npx @spicyapi/cli tasks get $TASK_ID # read back the retention that applied--retention は保持期間を短くするだけです——30m、1h、7d、あるいは 0 なら終了と同時に削除。実際に効くのはリクエスト・アカウント設定・プラットフォーム上限のうち最も短い値なので、指定した数値が通った前提で進めず、タスクレコードから読み戻してください。アカウントの許容より長い値を渡しても何も起きません。
ComfyUI Manager か下のコマンドで SpicyAPI ノードをインストールしたら、キャンバスで Seedance 2.0 Mini · Video Extend を検索してください。このノードにはこのページと同じオプションがあり、実行前に価格が表示されます。
cd ComfyUI/custom_nodes
git clone https://github.com/spicyapi-ai/comfyui-spicyapi埋め込みパネルはこのページと同じスキーマを参照するため、API 仕様とのずれを防げます。ドキュメント内の検索対象にする場合は、/api/embed/models/ の JSON を取得して描画してください。
<iframe src="https://spicyapi.ai/embed/ja/models/seedance-2-0-mini/api?model=bytedance%2Fseedance-2.0-mini%2Fvideo-extend" width="100%" height="560" loading="lazy" title="リクエスト例" style="border:1px solid rgba(0,0,0,.12)"></iframe>