チュートリアル
Kling 2.5 Turbo テキストtoビデオ API の呼び出し方:curl と Python ガイド
kling-2.5-turbo/text-to-video エンドポイントでできること
kling-2.5-turbo/text-to-video は HiAPI 上で提供されるテキストtoビデオモデルです。テキストプロンプトを渡すと、生成された動画が返されます。名前に含まれる「turbo」は最適化の方向性を示しています。標準品質のティアよりも高速なターンアラウンドを実現する代わりに、細部がいくらか失われます。ドラフトレンダリング、ストーリーボードのプレビュー、ソーシャルメディア向けのカット、クリエイティブな反復作業においては、このトレードオフは通常正しい選択です。
最初のコードを書く前に最も内面化すべき点は、これが非同期エンドポイントであることです。動画生成には数秒から数分かかり、あらゆる妥当な HTTP タイムアウトをはるかに超えます。そのため API は 2 つの操作に分かれています:
- 送信 —— プロンプトとパラメータを POST すると、すぐにジョブ識別子が返ります。
- ポーリング —— その識別子でジョブを繰り返し GET し、終端状態になるまで待ち、完了したレスポンスペイロードから動画結果を読み取ります。
これを単一のブロッキング呼び出しとしてモデル化しようとすると、タイムアウト、リトライ時の重複生成、高負荷時の接続リセットに直面します。送信してからポーリングするパターンは回避すべき面倒ではなく、正しいメンタルモデルです。以下のすべてのコード例はこれを中心に構築されており、一度これを内面化すれば統合の残りの部分はごく素直です。
もう一つ期待値を設定しておきましょう。エンドポイントはステートフルですが、状態はサーバー側にあり、あなたの側にはありません。ジョブはあなたの HTTP 接続とは独立して存在します。スクリプトがポーリングの途中でクラッシュして再起動しても、その ID をどこかに永続化しておきさえすれば、ID を使って同じジョブに再接続できます。最初からこの前提で設計してください。
リクエスト構造:プロンプト、fast/turbo プリセット、柔軟な長さ
制御できるフィールドはごく少数ですが、それぞれがジョブに実質的な影響を与えます。本当に重要なのは以下です。
プロンプト
プロンプトは主要なクリエイティブ入力です。検索クエリではなくショットの説明として扱ってください。このモデルで良いプロンプトには通常以下が含まれます:
- 被写体 —— 画面に映るのは誰、あるいは何か。
- 動作 —— 被写体がクリップの中で何をするか。
- カメラ —— 構図と動き。例えば
slow dolly in、static wide shot、handheld followなど。 - 環境と光 —— シーン、時間帯、雰囲気。
- スタイル —— ルックを導きたい場合は
cinematic、anime、product photographyなどと書けます。
具体的に保ち、被写体を先頭に置いてください。曖昧なプロンプトは曖昧な動きを生み、turbo ティアは解釈の余地が少ないためそれを増幅します。
fast/turbo プリセット
このモデルファミリーは、一部の精細さと引き換えにレイテンシを短縮する高速プリセットをサポートしています。有効にすると、バックエンドに速度優先を指示することになります。動きは依然として一貫していますが、細かいテクスチャ、小さな顔、複雑な背景は品質パスよりも早く劣化します。プロンプトのバリエーションを試す反復ループではこれを使い、最終的にヒーローショットをレンダリングする際は、品質パスが最後の一手としてより適切か検討してください。このプリセットはリクエストのフィールドであるため、アカウント全体のグローバル設定ではなく、ジョブごとの判断です。
柔軟な長さ
長さはモデルがサポートする範囲で柔軟であり、単一の固定長ではありません。より長い長さはより多くのフレームを生成することを意味し、完了時間が長くなり、コストも高くなります。課金は出力秒数に基づきます。ショットを満たす最短の長さを選んでください。ソーシャルメディア投稿用の 5 秒ループは、物語のビートと同じ長さである必要はありません。
フィールドの規律
必要なフィールドだけを設定してください。未知の、あるいはスペルミスのあるキーは、サイレントな設定ミスのよくある原因です。JSON リクエストボディは小さく明確に保ち、パイプライン設定の他の部分と一緒にバージョン管理してください。
curl でリクエストを送る
すべての HiAPI 呼び出しは同じ認証パターンを使用します。Authorization ヘッダーに bearer token を載せます。キーは環境変数に置き、シェル履歴やコミットされたスクリプトに現れないようにしてください。
export HIAPI_API_KEY="your_api_key_here"
次にジョブを送信します。正確なフィールド名とエンドポイントパスはモデルリファレンスから取得すべきですが、以下の形式が標準的な形式です:
curl -X POST "https://api.hiapi.ai/v1/video/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-2.5-turbo/text-to-video",
"prompt": "A slow dolly-in on a ceramic coffee cup on a wooden table, morning light raking across the surface, steam rising, shallow depth of field, cinematic",
"duration": 5,
"fast": true
}'
返ってくるのは動画ではないと想定してください。代わりに、ジョブ識別子とその初期状態を含む確認応答です。通常は queued または processing 状態に加えて id フィールドが含まれます。その ID を保存してください。それが以降のすべての操作のハンドルになります。
最小限のレスポンスはおおよそ次のとおりです:
{
"id": "job_abc123",
"status": "queued",
"model": "kling-2.5-turbo/text-to-video"
}
送信呼び出しはすぐに返るはずです。通常の条件下では 1 秒をはるかに下回ります。もしハングするなら、問題は接続性か認証にあり、モデルにはありません。401 が返る場合はヘッダー形式を確認してください(Bearer プレフィックスが重要です)。422 が返る場合は、JSON リクエストボディの形式が誤っているか、必須フィールドが欠けています。
この呼び出しに -L、リトライ、長いタイムアウトを追加しないでください。送信ステップは素早く成功するか、素早く失敗するかのどちらかです。すべての待機はポーリングループの中で発生し、それが次に説明する内容です。
Python での同じリクエスト
Python 版は同じ HTTP 契約の薄いラッパーです。requests を共有の Session とともに使い、送信と各ポーリングの間で接続プールが効くようにしてください。関数で包み、残りのコードが生の HTTP に直接触れないようにします。
import os
import time
import requests
BASE = "https://api.hiapi.ai/v1"
HEADERS = {
"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
"Content-Type": "application/json",
}
session = requests.Session()
def submit_video(prompt: str, duration: int = 5, fast: bool = True) -> str:
body = {
"model": "kling-2.5-turbo/text-to-video",
"prompt": prompt,
"duration": duration,
"fast": fast,
}
resp = session.post(f"{BASE}/video/generations", json=body, headers=HEADERS, timeout=15)
resp.raise_for_status()
return resp.json()["id"]
def poll_video(job_id: str, timeout_s: int = 600, interval_s: float = 3.0) -> dict:
deadline = time.monotonic() + timeout_s
delay = interval_s
while time.monotonic() < deadline:
resp = session.get(f"{BASE}/video/generations/{job_id}", headers=HEADERS, timeout=15)
resp.raise_for_status()
data = resp.json()
status = data.get("status")
if status in ("succeeded", "failed", "cancelled"):
return data
time.sleep(delay)
delay = min(delay * 1.5, 15.0)
raise TimeoutError(f"job {job_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
job = submit_video("A slow dolly-in on a ceramic coffee cup, morning light, steam rising, cinematic")
result = poll_video(job)
print(result)
いくつかの細部は削らずに残す価値があります。各リクエストの timeout により、詰まったソケットがワーカーをハングさせません。妥当な上限を設けた指数バックオフ、そして呼び出し元が「まだ実行中」と「壊れた」を区別できるように別個の TimeoutError を用意します。
httpx を好むなら、変換はごく素直です。メソッド、URL、JSON ボディは同じです。トランスポート層は面白い部分ではありません。契約こそが重要です。ポーリングを開始する前に job_id を永続的な場所に保存し、再起動によって進行中の生成が孤立しないようにしてください。
ジョブをポーリングし、レスポンスを読み取る
ポーリングループは、ほとんどの統合バグが潜む場所です。3 つのルールがそれを信頼できるものに保ちます。
ルール 1:終端状態だけがループを終わらせる
queued、processing といった過渡状態と、succeeded、failed、cancelled といった終端状態が表示されます。ループを抜けるのは終端状態だけです。未知の状態文字列を成功として扱ったり、processing で中断したりしないでください。各イテレーションで状態をログに記録してください。深夜 2 時に問題が起きたとき、そのログが唯一の証拠になります。
ルール 2:バックオフし、空回りしない
1 分かかるジョブに対して 1 秒固定のポーリングは無駄です。また、バッチジョブを実行しているときにアグレッシブなポーリングはレート制限に達する可能性があります。約 2〜3 秒から始め、各ラウンドで約 1.5 倍し、上限を 10〜15 秒にしてください。1 分のジョブの総リクエスト数は 60 から 15 未満に減り、最悪の場合の検出遅延は依然として上限値にすぎません。
ルール 3:アセットとメタデータを分ける
完了したレスポンスペイロードには両方が含まれます。動画自体は URL として提供され(通常は有効期限付き)、それ以外のすべて、つまりジョブ ID、モデル、長さ、ステータス、所要時間は、どのように得たかについてのメタデータです。URL を読み取り、速やかにダウンロードし、自分で保存してください。生成されたアセット URL は永続的な CDN ではありません。引き継ぎとして扱い、住処とはしないでください。ジョブ ID を自分のコピーと一緒に永続化し、あらゆるクリップをそれを生み出した正確なリクエストまで辿れるようにしてください。
failed についての注意
failed 状態はジョブレベルの結果であり、トランスポートエラーではありません。HTTP 呼び出しは成功しましたが、生成は成功しませんでした。エラーペイロードを読んでください。コンテンツポリシーによる拒否、サポートされないパラメータの組み合わせ、内部障害を示している可能性があります。ポリシー拒否をそのまま再試行しても再び失敗するだけなので、再試行を検討する前に原因で分岐してください。
エラー、タイムアウト、リトライの処理
2 つのエラーの世界を区別し、それぞれ別に扱ってください。
トランスポートレベルのエラーは HTTP の失敗です。接続リセット、5xx レスポンス、レート制限 429、クライアントのタイムアウトなどです。これらはジョブが実行されたかどうかを示しません。指数バックオフとジッターでリトライし、試行回数を制限してください。
ジョブレベルのエラーは、成功した HTTP レスポンスの中の終端状態です。ジョブは実行され、明確な結果を生み出しました。ポーリングをリトライしても役に立ちません。リトライするならそれは新しい送信であり、しかも失敗の原因が一時的なものである場合に限ります。
正しいものをリトライする
ここが微妙な部分です。送信呼び出しがタイムアウトした場合、サーバーがジョブを受け入れたかどうかはわかりません。盲目的に再送信すると、2 回の生成と 2 回の課金が発生する可能性があります。より安全なパターンは、クライアント生成のリクエストキーで送信を冪等にすることです。これをヘッダーまたはリクエストボディのフィールドとして送信すれば、重複した送信は新しいジョブを開始するのではなく元のジョブを返します。使用する API サーフェスがこれを提供していない場合、送信がタイムアウトしたときはプロンプトのハッシュと長さを記録し、再送信する前に最近のジョブを確認してください。
すべての層にタイムアウトを
3 つの異なるタイムアウトを設定し、混同しないでください:
- リクエストごとのタイムアウト —— 短く、例えば 10〜15 秒。これは単一の HTTP 呼び出しを制限するもので、ジョブではありません。
- ジョブ全体の締め切り —— 生成全体のウォールクロック予算。超過した場合はジョブを孤立としてマークし、アラートを出して先に進みます。
- クライアント向けのタイムアウト —— ユーザーが待っている場合、進捗をストリーミングするか、フロントエンドにジョブハンドルを返すかを決めます。
実用的なリトライ戦略
429 と 5xx をバックオフでリトライし、上限を小さく設定してください。400、401、403、422 は決してリトライしないでください。それらはあなたのリクエストのバグであり、繰り返すとクォータを焼くだけです。各失敗のレスポンスボディをログに記録してください。HiAPI のエラーペイロードは通常、問題のあるフィールドを指し示します。
バッチの安全性
多数のジョブをファンアウトするときは、並行性の制限とジッター付きの起動遅延を追加してください。100 件の同時送信はレート制限事故を自ら招くものです。5〜10 ワーカーのプールで、それぞれが独立してポーリングする方がはるかに安定し、観察も容易です。
本番稼働前のチェックリスト
これがノート PC を離れる前に、これらの決定を固めてください。
- タイムアウトと締め切り。 各呼び出しにリクエストごとのタイムアウト、ジョブ全体の締め切り、そしてジョブが孤立したときに何が起こるかの明確なポリシーを設けてください。マジックナンバーではなく定数として書いてください。
- ID の永続化。 ポーリング開始前に
job_idとプロンプトのハッシュを保存してください。これが再起動と監査を可能にする鍵です。 - アセットの保存。 成功時に完成した動画を自分のストレージバケットにダウンロードしてください。自分が制御しない URL を永久参照としてフロントエンドやデータベースに渡さないでください。
- ログ記録。 ジョブ ID、モデル、長さ、プリセット、所要時間を含めて、すべての状態遷移を記録してください。コストや品質の問題が発生したとき、それがそれらに答えるデータセットになります。
- コスト意識。 課金は出力秒数に基づくため、長さが主要なコストレバーです。turbo プリセットはレイテンシ(ひいてはワーカーの占有)を低く保ちます。機能ごとに生成された秒数を追跡し、コストの議論を推測ではなく実際の数字に基づかせてください。
- 冪等性。 送信時にクライアントリクエストキーを使用し、何が安全な再送信を構成するかのルールを定めてください。
- 失敗時の UX。 ジョブレベルの失敗時にユーザーが何を見るかを今決めてください。リトライボタン、フォールバックプロンプト、またはプレーンテキストのメッセージです。サイレントな空回りが最悪の選択です。
- プロンプトのバージョン管理。 プロンプトはハンドラーにインラインで書くのではなく設定に置き、再デプロイなしで異なるバリエーションの出力を比較できるようにしてください。
エンドポイント自体は小さいものです。1 回の送信、1 回のポーリング。エンジニアリングの努力のほとんどはその周囲のライフサイクルにあり、そこが本番品質を決める場所です。HiAPI 上の kling-2.5-turbo/text-to-video のモデルリファレンスから始め、その周囲にここで説明した足場を構築してください。
関連記事
すべての記事を見る →-
チュートリアル
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 チュートリアル
リクエスト優先の実践デモ:プロンプトから動画クリップへの呼び出しを構築し、リクエストを送信し、完了状態をポーリングし、結果をダウンロードする