チュートリアル
PixVerse V6 画像から動画への API:すぐに実行できる curl と Python のサンプル
- モデル
- pixverse-v6
hiapi 上で pixverse-v6/image-to-video を使って静止画像をアニメーション化するには、POST /v1/tasks の呼び出し 1 回とポーリング 1 回だけで済みます。これはプラットフォーム上のすべての生成モデルが使う非同期タスクのパターンと完全に同じです。テキストから動画へのエンドポイントとの違いは入力にあります。開始フレーム(image_url)と、それがどのように動くべきかを記述したプロンプトを提供する必要があります。本ガイドでは、そのままコピー&ペーストできる curl と Python のサンプル、このエンドポイントが実際に検証する入力フィールド、そしてテキストから動画へ移行してきた人がつまずく意外な点を紹介します。
必要なもの
- hiapi の API キー。コンソールで作成し、
Authorization: Bearer sk-<your-key>で送信します。ヘッダーの形式は認証ドキュメントを参照してください。 - モデル ID は
pixverse-v6/image-to-videoです(スラッシュはそのまま残してください。これは ID の一部であり、URL パスではありません)。これはpixverse-v6/text-to-videoとは異なるモデル ID です。 - 最初のフレームとして公開アクセス可能な画像 URL。プラットフォームはサーバー側でこの画像を取得するため、
localhostやプライベートバケットのリンクは使用できません。最初のフレームは API が GET でアクセスできる場所にホストしてください。 - curl を使う場合は何もインストールする必要はありません。Python のサンプルでは、標準ライブラリと
requestsだけが必要です。
PixVerse V6 画像から動画へは、提供された静止画像を開始フレームとして、1~15 秒のクリップにアニメーション化します。これは統合された非同期タスク API を通じて動作します。タスクを送信し、結果をポーリングし、出力 URL が期限切れになる前にダウンロードします。
最小限の動作するリクエスト(curl)
タスクを POST /v1/tasks に送信します。image_url と prompt はどちらも必須です:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-<your-key>" \
-H "Content-Type: application/json" \
-d '{
"model": "pixverse-v6/image-to-video",
"input": {
"image_url": "https://cdn.example.com/your-first-frame.jpg",
"prompt": "Slow push-in; the subject turns toward the camera and smiles, soft breeze in the hair",
"duration": 5,
"resolution": "720p"
}
}'
レスポンスはタスク ID を返します:
{ "code": 200, "data": { "taskId": "a1b2c3d4-...." } }
次に GET /v1/tasks/<taskId> を data.status が success になるまでポーリングします:
curl -s https://api.hiapi.ai/v1/tasks/a1b2c3d4-.... \
-H "Authorization: Bearer sk-<your-key>"
成功時、完了した動画の URL は data.output[0].url にあります:
{
"code": 200,
"data": {
"status": "success",
"output": [{ "url": "https://temp.hiapi.ai/....mp4", "expireAt": 1760000000 }]
}
}
この出力 URL は一時的なものです。expireAt タイムスタンプが付いています。すぐに .mp4 をダウンロードして自分のバケットに保存してください。直接ホットリンクしないでください。
Python での同じ流れ
import time, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": "Bearer sk-<your-key>", "Content-Type": "application/json"}
def create_task():
payload = {
"model": "pixverse-v6/image-to-video",
"input": {
"image_url": "https://cdn.example.com/your-first-frame.jpg",
"prompt": "Slow push-in; the subject turns toward the camera and smiles",
"duration": 5,
"resolution": "720p",
},
}
r = requests.post(BASE, json=payload, headers=HEADERS, timeout=60)
r.raise_for_status()
data = r.json()
task_id = (data.get("data") or {}).get("taskId")
if not task_id:
raise RuntimeError(f"create failed: {data}") # 400s echo the exact bad field
return task_id
def wait_for(task_id, timeout_s=600):
deadline = time.time() + timeout_s
while time.time() < deadline:
try:
r = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
task = (r.json().get("data") or {})
except requests.RequestException:
time.sleep(5) # one transient network blip should not abort the whole poll
continue
status = task.get("status")
if status == "success":
return task["output"][0]["url"]
if status == "fail":
raise RuntimeError(f"task failed: {task.get('error')}")
time.sleep(5) # still pending — keep the SAME task_id, re-poll
raise TimeoutError(task_id)
task_id = create_task()
url = wait_for(task_id)
video = requests.get(url, timeout=120).content
open("out.mp4", "wb").write(video)
print("saved out.mp4")
ポーリングループは success と fail を明示的にチェックし、それ以外のステータスでは待機を続けるため、タスクがレンダリング中に報告する中間ステータスのラベルが何であっても堅牢に処理できます。あるポーリングリクエストがエラーになった場合は、再送信せずに、保存した同じ task_id でスリープ後に再ポーリングしてください。再送信すると 2 回目のレンダリング費用が発生します。
pixverse-v6/image-to-video が実際に検証するパラメータ
以下は本番エンドポイントが実際に受け付けるフィールドです。無効な値を送って検証エラーを読み取り、1 つずつ確認したうえで、モデルドキュメントと照合しました:
| フィールド | 型 | 値 / 範囲 | 説明 |
|---|---|---|---|
image_url |
string | 公開画像 URL | 必須。最初のフレーム。単一の URL 文字列で、配列ではありません。 |
prompt |
string | — | 必須。そのフレームに加える動きを記述します。 |
duration |
integer | 1–15、デフォルト 5 |
単位は秒。整数である必要があり、文字列は不可。 |
resolution |
string | 360p、540p、720p、1080p |
出力解像度。 |
negative_prompt |
string | — | 任意。避けたい内容。 |
seed |
integer | — | 任意。再現可能な結果を得るために再利用します。 |
style |
string | anime、3d_animation、clay、comic、cyberpunk |
任意のプリセットスタイル。 |
generate_audio |
boolean | true / false、デフォルト false |
任意。生成される音声トラック / 環境音のオン・オフ。 |
ここには aspect_ratio フィールドはありません。これは、目にしたことがあるかもしれないテキストから動画へのリクエストとの唯一の実質的な違いであり、覚えておく価値があります(下記参照)。
本番運用の注意点
aspect_ratioはありません——出力の形状は入力画像に従います。テキストから動画へのエンドポイントはaspect_ratioの列挙値を受け付けますが、このエンドポイントはそれを拒否します。最初のフレームを提供するため、クリップはそのフレームのサイズを継承します。9:16 の縦向きクリップが必要な場合は、送信前にimage_urlを 9:16 にトリミングまたはパディングしてください。比率を上書きするつまみはありません。- リクエスト構造は閉じています。上表以外のフィールドはすべて拒否され、
invalid input: <root>: additional properties '<field>' not allowedというエラーになります。タイプミスや推測したフィールドは、黙って無視されるのではなく、送信時に明確に失敗します。first_frame、image、input_image、motion_mode、camera_movementなどのフィールドはすべて拒否されます。開始画像はimage_urlに入れ、カメラの動きはpromptテキストに書きます。 durationは整数です。プラットフォーム上の一部の動画モデルは文字列("6")を受け付けますが、それとは異なります。"5"を送るとinvalid input: duration: got string, want integerが返ります。範囲外の値は境界を直接報告します。例えばduration: maximum: got 999, want 15です。- エラーは一度に 1 フィールドずつ返され、フラットなエンベロープ形式をとります:
{"code":400,"error_code":"INVALID_REQUEST","message":"invalid input: image_url: missing required field \"image_url\""}。報告されたフィールドを修正して再送信してください。次の無効なフィールド(あれば)は次の呼び出しで明らかになります。 - タスクの失敗でも HTTP 200 が返ります。失敗の情報はレスポンスボディ内に
data.status: "fail"の形で含まれます。HTTP ステータスコードだけでなく、ステータスフィールドを確認してください。プラットフォームが取得できない画像 URL はよくある原因なので、まず最初のフレームが公開されていることを確認してください。 - 秒単位で課金され、解像度と長さに応じて増加するため、1080p/15 秒のクリップは 540p/3 秒のクリップよりはるかに高価です。大量生成の前に料金ページで現在のレートを確認してください。
検証したこと(および検証していないこと)
pixverse-v6/image-to-video の本番 /v1/tasks エンドポイントに意図的に無効な値を送り、API 自身の検証レスポンスを読むことで入力契約を明らかにしました。これは読み取り専用のスキーマ探索であり、コールバックも設定せず、レンダリング費用も発生させていません。覚えておく価値のある具体的な発見:
image_urlは必須の最初のフレームフィールドで、単一の文字列であり配列ではありません。数値を送るとimage_url: got number, want stringが返ります。省略するとmissing required field "image_url"が返ります。推測されがちな代替フィールド(first_frame、image、input_image)はすべて未知の属性として拒否されます。- このエンドポイントは
aspect_ratioを拒否します(additional properties 'aspect_ratio' not allowed)。ただしpixverse-v6/text-to-videoでは有効です。これが画像から動画へのリクエストがテキストから動画へのリクエストと異なって見える具体的な理由です。出力の形状はパラメータではなく、あなたのフレームによって決まります。 generate_audioは真のブールスイッチです(デフォルトfalse)。文字列を送るとgenerate_audio: got string, want booleanが返ります。音声が必要ならtrueに設定してください。強制的にオンまたはオフにされることはありません。
この探索ではクリップをレンダリングしていないため、本ガイドはモーションの品質や、モデルが入力フレームをどの程度忠実に保持するかについては主張しません。記録しているのは、このエンドポイントが強制する正確なリクエスト契約のみです。
関連コンテンツ
- PixVerse V6 画像から動画へ——モデルページ
- PixVerse V6 画像から動画へ——API ドキュメント
- タスクの作成とタスク詳細の取得リファレンス
- 認証
- 料金
- hiapi 上のその他の画像から動画へのチュートリアル:hailuo-2.3 と Grok Imagine 1.5
よくある質問
画像から動画へに aspect_ratio がないのはなぜですか?クリップは image_url のフレームで始まり、そのサイズを継承するためです。出力比率を制御するには、送信前に入力画像のサイズ変更やトリミングを行ってください。このエンドポイントは aspect_ratio を未知のフィールドとして拒否します。
image_url は複数の画像を受け付けますか?いいえ。このエンドポイントでは単一の URL 文字列であり、配列を渡すと検証エラーになります。最初のフレームのみを設定します。
duration の単位は秒ですか、フレームですか?秒です。1 から 15 までの任意の整数で、デフォルトは 5 です。整数である必要があり、文字列の "5" は拒否されます。
これはテキストから動画へのエンドポイントとどう違いますか?pixverse-v6/image-to-video は提供されたフレームをアニメーション化します(image_url + prompt、aspect_ratio なし)。pixverse-v6/text-to-video は別のモデル ID で、プロンプトのみから生成し、aspect_ratio を確かに受け付けます。動かしたい正確な開始スチル画像がすでにある場合は、画像から動画へを使用してください。
なぜ私のリクエストは「additional properties not allowed」で失敗するのですか?スキーマに存在しないフィールドを送信しています。入力は image_url、prompt、duration、resolution、negative_prompt、seed、style、generate_audio のみを受け付けます。
関連記事
すべての記事を見る →-
チュートリアル
HiAPI API で hailuo-2.3-fast/image-to-video を呼び出す方法:curl と Python の実践
高速・低コストな画像から動画へのティアにおける最初の実行可能なリクエスト — モデル ID から MP4 のダウンロードまで
-
チュートリアル
HiAPI APIでhailuo-2.3/text-to-videoを呼び出す方法:curl、Python、実行可能なリクエスト例
-
チュートリアル
HiAPI で Kandinsky 6.0 Pro のテキストto動画を使用する:curl と Python チュートリアル
リクエスト優先の実践デモ:プロンプトから動画クリップへの呼び出しを構築し、リクエストを送信し、完了状態をポーリングし、結果をダウンロードする