チュートリアル
HiAPI で kling-4.0/image-to-video を呼び出す方法:curl、Python、ポーリング
kling-4.0/image-to-video エンドポイントの役割
kling-4.0/image-to-video は、1 枚の静止画像を短い生成動画に変換します。HiAPI 上ではタスクベースのエンドポイントとして提供されます。画像と、画面をどのように動かしたいかを説明するプロンプト風の記述を送信すると、API は完成した動画ではなく、タスクハンドルを即座に返します。
リクエストのレベルでは、呼び出し側は以下を提供する必要があります:
- モデル識別子(
kling-4.0/image-to-video)、 - ソース画像(通常は公開アクセス可能な画像 URL)、
- 画像をどのように動かすか、またはシーンで何が起こるべきかを指示するテキスト記述、
- このエンドポイントでこのモデル用に記録されている追加の生成オプション。
返されるのは動画そのものではありません。送信レスポンスにはタスク識別子と初期状態が含まれます。実際の動画クリップは生成タスクが完了した後に初めて利用可能になり、その時点で識別子を参照して取得できます。
この分割こそがこのエンドポイントの完全なメンタルモデルです:送信 → タスク id を取得 → 状態をポーリング → 結果をダウンロード。以下の各節はすべてこのループのバリエーションです。
このエンドポイントは非同期であるため、統合コードには 1 つではなく 2 つの責務があります。正しい形式の送信リクエストを送る必要があり、さらにタスクが終了状態になるまで後続の処理を管理する必要があります。この 2 点を適切に処理すれば、残りは通常の接続作業にすぎません。
前提条件と認証
いずれの呼び出しの前にも、2 つのものが必要です。このモデルへのアクセス権を持つ HiAPI アカウントと、コンソールから発行される API キーです。
認証はリクエストごとに行われます。API への各呼び出しは HTTP ヘッダーにキーを含めます。標準的な方式は bearer スタイルの認証ヘッダーです:
Authorization: Bearer <YOUR_HIAPI_API_KEY>
キーをソースコード管理に入れないでください。通常の方法は次のとおりです:
- 環境変数(例:
HIAPI_API_KEY)に保存し、実行時に読み取る。 - クライアントコードに貼り付けたり、後でリポジトリにコミットする curl コマンドに貼り付けたりしない。
- キーが漏洩した場合は、コンソールからローテーションする。
以下の curl と Python の例の両方が読み取れるように、シェルでエクスポートします:
export HIAPI_API_KEY="your-key-here"
また、アクセス可能な画像 URL も必要です。このエンドポイントは画像を参照経由で使用するため、ノート PC 上のローカルファイルパスは使えません。安定した HTTPS URL を持つ場所に画像をホストするか、プラットフォームがリソース機構を提供している場合は画像をアップロードして返された参照を使用します。
キーをエクスポートし、画像がアクセス可能になったら、タスクを送信できます。
curl リクエストを段階的に解析
完全な送信リクエストは次のようになります:
curl -X POST "https://api.hiapi.ai/v1/tasks" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-4.0/image-to-video",
"input": {
"image": "https://example.com/your-image.jpg",
"prompt": "A slow camera push-in as the subject turns toward the light; soft afternoon shadows"
}
}'
各部分の解説:
-X POST— タスク作成は POST であり、GET ではありません。リクエストはジョブを記述する本文を持ちます。- URL — 統一された HiAPI タスクエンドポイントです。タスクベースのモデルではこれが同じルートであり、モデルはパスではなく本文で選択されます。
Authorization— 前節で説明したあなたのキーです。Content-Type: application/json— 本文は JSON です。このヘッダーを省略したり綴りを間違えたりすると、通常はリクエストがモデルに到達する前にサーバーに拒否されます。model— リテラル文字列kling-4.0/image-to-video。正確かつ大文字小文字を区別するものとして扱ってください。綴りを間違えると、役立つヒントではなくモデル未検出エラーが発生します。input.image— ソースの静止画像を URL 形式で指定します。これはモデルが動かすフレームであるため、鮮明で構図が明確な画像を選んでください。input.prompt— 自然言語による指示です。動きやカメラの挙動(プッシュイン、パン、被写体の移動)および全体的な雰囲気を記述します。曖昧なプロンプトは曖昧な動きを生みます。
即時のレスポンスは動画ではなくタスクオブジェクトです。ジョブの識別子と状態フィールドを含み、送信直後は通常キュー待ちや処理待ちに似た状態になります。この識別子を保存してください。後でジョブを確認する際に必要な唯一の情報です。
この時点では動画クリップはまだ存在しません。これは想定された動作であり、次の節でその扱い方を示します。
Python での同じ呼び出し
Python 版はまったく同じことを行います。同じエンドポイント、同じヘッダー、同じ本文であるため、選ぶツールによってプロトコルが変わることはありません。
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
payload = {
"model": "kling-4.0/image-to-video",
"input": {
"image": "https://example.com/your-image.jpg",
"prompt": "A slow camera push-in as the subject turns toward the light; "
"soft afternoon shadows",
},
}
resp = requests.post(
"https://api.hiapi.ai/v1/tasks",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
resp.raise_for_status()
task = resp.json()
task_id = task["id"]
print("submitted:", task_id, task.get("status"))
実践で注意すべき点:
- 文字列を手動でシリアライズするのではなく、
json=payloadを使用してください。コンテンツタイプを設定してくれ、引用符の誤りも避けられます。 - 送信リクエストと後続処理を同じ関数またはクラスに置き、タスク id がステップ間で失われないようにします。
- 明示的なタイムアウトを設定します。送信呼び出しはすぐに返るはずです。ジョブを作成するだけで、動画を待つわけではありません。
raise_for_status()を呼び出した後にタスクが存在すると仮定して続行しないでください。非 2xx レスポンスはタスクが作成されなかったことを意味し、エラー本文がどのフィールドが誤っているかを通常示します。
サービスを構築する場合は、この呼び出しを小さなクライアントにラップし、送信用メソッドと状態確認用メソッドを用意してください。これにより、リトライ、ログ記録、キー処理を各呼び出し箇所に分散させるのではなく、一箇所に集中できます。
非同期タスクを完了までポーリング
画像から動画の生成は、チャット補完よりも明らかに時間がかかります。モデルは多数のフレームを合成し、エンコードし、結果を保存する必要があります。送信レスポンス内で接続を長時間開いたままにせずに動画クリップを返すことはできないため、このエンドポイントは設計上非同期です。
状態を確認する方法
GET リクエストで識別子を指定してタスクをポーリングします:
curl "https://api.hiapi.ai/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $HIAPI_API_KEY"
レスポンスはジョブを記述します。状態、および完了後の出力です。状態は通常、キュー待ち状態から実行状態を経て終了状態(たとえば成功、またはエラーメッセージによる失敗)へと進みます。
Python での簡単なポーリングループ
import time
def wait_for_task(session, base_url, task_id, timeout=900):
deadline = time.time() + timeout
delay = 2.0
while time.time() < deadline:
r = session.get(f"{base_url}/tasks/{task_id}", timeout=30)
r.raise_for_status()
data = r.json()
status = data.get("status")
if status in ("succeeded", "failed"):
return data
time.sleep(delay)
delay = min(delay * 1.5, 15.0) # gentle backoff, capped
raise TimeoutError(f"task {task_id} did not finish in time")
バックオフの指針
- 短い間隔から始めて徐々に増やします。生成は最初の 1 秒で完了するわけではないため、エンドポイントを頻繁に叩くだけではクォータを浪費し、レート制限を誘発します。
- 完了したジョブにすぐ気づけるよう間隔に上限を設けます。定常状態では数秒で十分です。
- 常にハードな締め切りを設定します。境界を設定しない限り、永遠に完了しないタスクと異常に時間がかかるタスクを区別できません。
- Web リクエストをブロックするのではなく、バックグラウンドワーカーや定期ジョブからポーリングします。ユーザーが UI で待機している場合は、フロントエンドにあなた自身の状態エンドポイントをポーリングさせます。
- 状態呼び出しでの一時的なネットワークエラーはリトライしますが、すでに
failedを報告したタスクはリトライしないでください。その場合の正しい操作は新しいタスクを送信することです。
返された動画クリップを取得して保存
ポーリングが終了成功状態を返すと、タスクオブジェクトには生成された動画への出力参照(完成した動画を指すリソース URL または同等の参照)が含まれます。
result = wait_for_task(session, "https://api.hiapi.ai/v1", task_id)
if result["status"] != "succeeded":
raise RuntimeError(result.get("error") or "generation failed")
video_url = result["output"]["video_url"]
with session.get(video_url, stream=True, timeout=120) as r:
r.raise_for_status()
with open(f"{task_id}.mp4", "wb") as f:
for chunk in r.iter_content(chunk_size=1 << 16):
f.write(chunk)
ここでは通常 2 つの設計上の決定が生じます。
速やかにダウンロードする。 出力 URL には通常有効期限があります。動画クリップを保持する予定なら、生の URL をユーザーに渡して有効であり続けることを期待するのではなく、自分のストレージにコピーしてください。
メタデータをファイルと一緒に保存する。 タスク id、プロンプト、ソース画像参照、作成時刻を動画と一緒に永続化してください。後で誰かがなぜ動画クリップがこう見えるのかと尋ねたとき、その記録が答えになります。
サービスを提供する場合の一般的なパターンは、バックエンドで生成し、ファイルをオブジェクトストレージに保存し、クライアントにはあなた自身の安定した URL を返すことです。これにより、生成リソースのライフサイクルに依存するのではなく、アプリでアクセス、有効期限、キャッシュを制御できます。
別の動きで再生成したい場合は、プロンプトを調整した新しいタスクを送信してください。各タスクは独立しており、完了したタスクを変更する必要はありません。
失敗したリクエストのトラブルシューティング
問題が発生したら、リクエスト構造から外側に向かって調査します。ほとんどの失敗は少数の原因に集約されます。
送信呼び出しがエラーを返す
- モデル文字列の誤り。
kling-4.0/image-to-videoは大文字小文字やスラッシュを含め完全に一致する必要があります。ソースファイルを信頼するのではなく、実際に送信している文字列を出力してください。 - 認証の拒否。 ヘッダーが
Authorization: Bearer <key>であることを確認してください。裸のキーでもクエリパラメータでもありません。また、環境変数がリクエストを実行する同じシェルまたはプロセスで設定されていることを確認してください。 - 画像にアクセスできない。 画像はプラットフォームから HTTPS 経由で取得できる必要があります。localhost URL、プライベートバケット、ホットリンク防止のあるホストは失敗します。シークレットブラウザで URL を開き、認証なしで解決できることを確認してください。
- フィールドの欠落または名前の誤り。 本文はモデル入力を
inputの下にネストします。promptやimageをinput内ではなくトップレベルに置くのはよくあるミスです。検証エラーは通常フィールド名を指摘します。 - コンテンツタイプ。
Content-Type: application/jsonなしで JSON 本文を送信すると、モデルに関わる前に拒否されます。
タスクは作成されたが成功しない
- ポーリングが少なすぎるか、まったくしていない。 ループが実際に実行されているか、比較している状態値が API の返す値と一致しているか確認してください。終了状態チェックの綴り誤りは無限ループを引き起こします。
- タスクが
failedになる。 タスクオブジェクト内のエラーメッセージを読んでください。通常は入力(たとえばデコードできない画像)を指摘しています。 - 締め切りに達した。 ジョブがタイムアウト付近でまだ実行中の場合、繰り返し再送信するのではなく上限を引き上げてください。再送信は負荷とコストを増やすだけです。
- 出力リンクの期限切れ。 タスクは成功したがダウンロードが 404 を返す場合、完了から取得までの間に時間が経過しすぎています。成功後すぐにダウンロードしてください。
迅速な診断の習慣:最初の数回の統合では、送信レスポンス本文を逐語的に記録してください。タスク id、初期状態、およびこのエンドポイントが返す正確なフィールド名がわかるため、以降のすべての失敗における推測を排除できます。
関連記事
すべての記事を見る →-
チュートリアル
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 チュートリアル
リクエスト優先の実践デモ:プロンプトから動画クリップへの呼び出しを構築し、リクエストを送信し、完了状態をポーリングし、結果をダウンロードする