Character Swap は、シーンもカメラ移動も元の音もそのまま保ちながら、人物の外見を体格や服装まで丸ごと差し替えたいときに使います。Character Swap はクリップ内の誰を差し替えるかを選べます。最終クリップを解析し、番号付きのプレビューを確認してから、選んだプレビュー番号と差し替え側の画像 1〜3 枚を送ります。元の服装を残す必要がある場合は、代わりに head swap や face swap のワークフローを使います。
SpicyAPI では解析と編集は別々に課金されるタスクです。7 秒のソースは合計で480p なら $0.72、720p なら $1.28です。解析が 1 回、それに 10 秒へ切り上げられた編集の合計です。Playground は両方の手順をブラウザ内で実行し、API も同じ入力を受け取ります。映像と、参照画像に写っている人物の顔について、いずれも許可が必要です。
7 秒のシーンと全身差し替えを準備する
例のシーンは、誰かが閉じた工具箱を持って作業台へ向かう 7 秒のショットで、もう一人の成人がその隣に立っています。箱を持つ側は、ネイビーの仕事ジャケットとチャコールグレーのズボンを着た架空の成人に置き換えられます。下のイラストがそれらの外観です。作業台、工具箱、もう一人の人物、元の演技はそのまま残ります。
編集する 7 秒のソースをそのまま書き出してください。最初のつかみ、運ぶ動作、工具箱が作業台に届いたあとの手放しを残します。入力は5〜30 秒の MP4で、90 MB までです。ファイルをアップロードするのが最も確実で、直接リンクは MP4 ファイルそのものを指している必要があります。プレーヤーを含むページだと失敗します(課金は返金されます)。解析後にトリミングや再エンコードすると、解析をやり直す必要があります。
トラッカーは、十分に大きく見えて追跡できる人物を追うため、必要な区間だけ切り出してください。狙いの人物が完全に隠れた状態が長い区間は避けてください。編集は 5 秒単位で課金されるので、短いカットのほうが安くなります。
差し替え側には、同じ成人の全身の正面ビューと 3/4 ビューを、同じ服装で用意してください。参照画像は 1 枚でも受け付けられ、対象ごとの上限は 3 枚です。顔と肩までのポートレートでは体格と服装を推測することになるため、袖、手、靴を見せてください。また、いちばん鮮明なポートレートを選ぶのではなく、映像と同じ照明に揃えて参照画像を用意します。1 枚目は人物 A の顔、2 枚目は人物 B のズボン、3 枚目はまた別のジャケットのように組み合わせないでください。サービスはこれらを別々の服装レイヤーではなく、1 回の差し替えの参照画像として受け取ります。
画像生成にそのまま使えるブリーフは次のとおりです。
架空の成人女性、30 歳ごろの全身参照ポートレート。素のネイビーの仕事ジャケット、チャコールグレーのズボン、暗いフラットシューズ。正面向きのリラックスした姿勢、手が見える、袖と靴が判読できる、ニュートラルな背景。工具箱なし、他の人物なし、文字なし。
必要なら、確定した同じデザインの 2 つ目のアングルを生成または撮影してください。character swap の編集にはテキストプロンプト欄も衣装セレクターも身体マスクもありません。目的の服装は参照画像に含まれている必要があります。

正面と 3/4 の全身リファレンスセットのイラスト。
まず Playground で試す
- Video Character Swap のモデルページを開き、Playground タブの Form ビューを開いたままにします。実行するには、残高のあるアカウントでサインインします。
- Step 1, Find the people in your clip で、7 秒の MP4 を Input video に追加し(アップロードはリンクより確実です)、完成後のクリップに必要な Resolution、
480pか720pを選びます。編集でも同じ値を使う必要があります。 - Find people in this clip を押します($0.08)。検出された全員が Step 2, Choose who to replace に表示され、1 人につき 1 枚の切り出しプレビューになります。
- 工具箱を持っている人のプレビューを選び、差し替え側の参照画像を 1〜3 枚追加して、編集を実行します。Seed は任意です。
位置 0 が最初の返却プレビューです。順序は画面上の位置ではなくトラッキングから来るため、必ずしも最も左や最大の人物とは限りません。箱を持つ側が 2 番目のプレビューなら、インデックスは 1 です。プレビューを保存するときは返却された順序を保ってください。アルファベット順のファイル名や並び替えられたギャラリーは、インデックスを無断で変えてしまいます。
狙いの人物にプレビューがない場合、隣の番号を当てて編集に課金しないでください。参照画像で引き戻すことはできません。代わりに、その人物がはっきり見えるテイクを使ってください。誰も検出されない解析は失敗として終わり、確保されていた金額は解放されます。解析が成功していれば、差し替えないことを決めても課金は発生します。
続いてコードから呼び出す
Python SDK(pip install spicyapi)をインストールし、SPICY_API_KEY を設定して、次を実行します。クリップと参照画像 2 枚をアップロードし、解析を実行し、プレビューのリンクを表示し、どのインデックスを差し替えるか尋ねてから、編集を送信します。両方のタスクが課金対象です。
import uuid
from spicyapi import SpicyClient, output_assets
client = SpicyClient() # reads SPICY_API_KEY from the environment
RESOLUTION = "720p" # must be identical in both calls
clip = client.upload_file("./workshop-seven-seconds.mp4")
front = client.upload_file("./replacement-front.png")
angled = client.upload_file("./replacement-three-quarter.png")
analysis_task = client.create_task(
model="spicyapi/character-swap-v1/video-analyze",
input_data={"video_url": clip["uri"], "resolution": RESOLUTION},
idempotency_key=str(uuid.uuid4()), # new key per new request; reuse only to retry the same one
)
print("Resume analysis:", analysis_task["taskId"], flush=True)
analysis = client.wait_for_terminal(analysis_task["taskId"])
if analysis["state"] != "succeeded":
raise RuntimeError(f"Analysis {analysis_task['taskId']} ended as {analysis['state']}")
previews = output_assets(analysis)
if not previews or any(p.get("pending") or p.get("unavailable") or not p.get("url") for p in previews):
raise RuntimeError(f"Analysis {analysis_task['taskId']} has no ready previews; retrieve it before editing")
for index, preview in enumerate(previews): # keep the returned order
print(index, preview["url"])
chosen = int(input("Index of the person to replace: "))
if not 0 <= chosen < len(previews):
raise ValueError("Choose one of the returned preview indices before creating an edit")
edit_task = client.create_task(
model="spicyapi/character-swap-v1/video-edit",
input_data={
"analysis_task_id": analysis["taskId"], # video_url is inherited from the analysis
"resolution": RESOLUTION,
"swap_targets": [{"object_index": chosen,
"image_urls": [front["uri"], angled["uri"]]}],
"seed": 42,
},
idempotency_key=str(uuid.uuid4()), # new key per new request; reuse only to retry the same one
)
print("Resume edit:", edit_task["taskId"], flush=True)
edit = client.wait_for_terminal(edit_task["taskId"])
if edit["state"] != "succeeded":
raise RuntimeError(f"Edit {edit_task['taskId']} ended as {edit['state']}")
assets = output_assets(edit)
if not assets or any(a.get("pending") or a.get("unavailable") or not a.get("url") for a in assets):
raise RuntimeError(f"Task {edit_task['taskId']} has no ready output; check this task before a new run")
print(assets[0]["url"]) # copy it to your own storage nowアップロード、待機、エラー、再試行についてはsubject swap ガイド、タスクドキュメント、Python SDK リファレンスを参照してください。両方のステップで同じ API キーを使い、編集は解析から 24 時間以内に実行してください(アップロードしたクリップも 1 日で失効します)。1 回の解析で、個別課金の編集を複数回実行できます。リストに上げなかった人物は変更されず、インデックスはこの解析に属すので、別のショットでキャラクター ID として再利用しないでください。
全身差し替えは、シーン、カメラ移動、振付、元の音を保持することを目的としています。この範囲は、背景のピクセルが不変であること、新しい声が得られることを保証するものではありません。
Agent に実行させる
アシスタントに swap を実行させるなら、CLI か MCP サーバーを渡します。どちらも価格を表示し、有料の呼び出し前に確認を求めます。Skill はその上に指示を追加します。
- CLI.
spicyapiはターミナルから 1 つのタスクを実行します(npx @spicyapi/cliはインストールなしで動作します):
``bash spicyapi files upload ./workshop-seven-seconds.mp4 # prints a spicy:// URI spicyapi tasks create --model spicyapi/character-swap-v1/video-analyze \ --input-file analysis.json --idempotency-key workshop-analysis-v1 --wait ``
analysis.json には {"video_url": "spicy://...", "resolution": "720p"} を入れます。プレビューを確認したら、video-edit、独自のキー workshop-edit-v1、analysis_task_id、resolution、swap_targets を含む input.json を指定してコマンドを実行します。キーを再利用できるのは、内容を変えないリクエストだけです。新しいソース、対象、参照画像セットには新しいキーが必要です。
- MCP サーバー. MCP サーバー(設定スニペットはそのページにあります)をアシスタントに追加して、次のように依頼します: "Character Swap で ./workshop-seven-seconds.mp4 を 720p で解析し、プレビューを見せて"。人物を選んだら、"インデックス 1 を ./replacement-front.png と ./replacement-three-quarter.png で差し替えて" と伝えます。
spicyapi_upload_fileを呼び、その後spicyapi_task_create(価格確認のため停止します)、続いてspicyapi_task_waitを呼びます。 - Skill.
npx skills add spicyapi-ai/spicy-skillは Agent Skill をインストールします。現在のスキーマを読み、冪等キーを使い回せるようにします。この Skill 自体はタスクを実行できないので、CLI か MCP と一緒に使ってください。どのプレビューを差し替えるかは、人の判断のままです。
バリアントを作る前に課金内容を理解する
価格は公開カタログ(2026 年 10 月)時点のものです。
| 段階 | 価格 | 7 秒の場合の例 |
|---|---|---|
| 解析 | リクエストあたり $0.08 | $0.08 |
| 編集、480p | 課金対象秒あたり $0.064 | 課金対象 10 秒: $0.64 |
| 編集、720p | 課金対象秒あたり $0.12 | 課金対象 10 秒: $1.20 |
編集の長さは 5 秒単位のブロックに切り上げられ、最低 5 秒、最大 30 秒です。5 秒のソースは 1 ブロック、5.1 秒なら 2 ブロックを使います。送信前、編集の見積もりが最大 30 秒分を予約します。480p なら $1.92、720p なら $3.60 で、確定時に差額が戻ります。そのため予算の確認では、想定される最終額だけでなく予約分も確保する必要があります。作成時に拒否されたリクエスト(解像度不一致、解析 ID 違い、インデックス重複)は、何も作らず、何も課金しません。
同じ 1 回の解析を使い回した 7 秒ソースの 720p 編集 2 回分は、合計 $2.48 です。$0.08 と $1.20 の 2 倍です。参照画像や seed を変更すると、新しい有料の編集になり、無料の修正にはなりません。
正しい問題を直す
| 症状 | 対処 |
|---|---|
| 編集で横に立っていた人物が変わる | 元の順序どおりのプレビューを開き直し、object_index を修正します。新しい参照画像では選択の誤りは直りません |
| リクエストが「解析が見つからない」または「別のモデルのもの」と返す | 同じ API キーで作成した自分の video-analyze タスクのタスク ID を使います |
| リクエストがソースまたは解像度を拒否する | 編集では video_url を省略し、解析した解像度を使うか、新しいソースを解析し直します |
| 解析が古すぎる | 解析をもう一度実行し、新しいプレビューから対象を選びます |
| 顔は合っているのに服装が変わる | 同じジャケット、同じズボン、同じ靴を示す一貫した全身リファレンスを使います |
| 差し替えが貼り付けたように見える | リファレンスのライティングが撮影素材と違います。同じ光の方向とトーンで作り直してください |
| 手が工具箱を通り抜ける | より明確なつかみ、または釣り合いのより合った差し替え側を使います。鮮明なポートレートだけでは接触を表現できません |
| 交差の後に同一性が変わる | 遮蔽が長く続く場面の少ないソースを試します。もう一人の人物の後ろから戻る瞬間を確認してください |
| タスクは成功したがメディアが保留中 | 既存のタスクの回収を続けてください。ダウンロードのために別の有料編集を作成しないでください |

印刷されたフレームを確認する イラスト。
箱を持つ側、工具箱、選択されていない成人の 3 つを、通常速度で一緒に見ます。次に、つかみ、作業台との接触、手放しを確認します。中央の動作が失敗していても、新しい顔はそれなりに良く見えることがあります。最後の 0.5 秒だけに不具合があるなら、トリミングで足りる場合があります。つかみが最後まで崩れているなら、より明確なソースを選ぶか、元の体と服装を残せる場合は範囲の狭い head 差し替えを使ってください。
受け入れたクリップは有効期限が切れる前に自分のストレージへコピーしてください。結果は約 14 日間保持されます(メディアの保持と配信を参照)。






