HiAPI
ブログ

チュートリアル

HiAPI API で flux-3-max/keyframes-to-video を呼び出す方法:curl と Python ガイド

開発者向け:認証、キーフレームの送信、タスクのポーリング、結果の取得

Nov 3, 2026
封面图:深松绿背景上被直线切割成平面色块的大型棱镜,鼠尾草绿与雾绿点缀,几何克制。

この統合が実際に行うこと

flux-3-max/keyframes-to-video は、キーフレーム画像から動画を生成するための非同期タスク API です。結果を同一の HTTP レスポンスで返す同期エンドポイントとは異なり、このモデルはキーフレームを受け取り、バックグラウンドタスクを作成し、進捗確認に使えるタスク識別子を返します。

エンドツーエンドのライフサイクルは 4 つのフェーズに分かれます:

  1. 認証 — すべてのリクエストに HiAPI API キーを付与します。
  2. 送信 — キーフレームとパラメータを送信して動画タスクを開始します。
  3. ポーリング — タスクが終端状態に達するまで、繰り返しステータスを問い合わせます。
  4. 取得 — タスク成功時に返された URL から生成済み動画をダウンロードします。

このライフサイクルを念頭に置くことがクライアントの書き方を決めます。送信と結果取得は別々の呼び出しであり、アプリケーションは数十秒から数分かかるタスクに耐えられる必要があります。以下の curl と Python の例は同じ 4 フェーズに従っているため、このフローを任意の言語やジョブランナーに移植できます。

API キーの取得と認証

API キーは HiAPI ダッシュボードから発行されます。パスワードと同様に扱ってください。アカウントを識別し、課金対象の呼び出しを認可するものなので、ソースコード、コミット履歴、ログ出力に絶対に含めてはいけません。

認証は HTTP ヘッダーとして各リクエストで渡します:

Authorization: Bearer $HIAPI_API_KEY

実運用では、キーを環境変数に保存し、実行時に読み取ります。シェルの例では、セッションごとに一度エクスポートします:

export HIAPI_API_KEY="your-key-here"

Python では、文字列をハードコードするのではなく os.environ["HIAPI_API_KEY"] で読み取ります。.env ファイルを .gitignore に追加し、デバッグ目的でリクエストを記録する場合は、ログアグリゲーターに届く前に Authorization ヘッダーをマスクしてください。キーが漏洩した場合は、直ちにダッシュボードからローテーションしてください。

curl でリクエストを組み立てる

動画タスクの送信とは、モデルを指定しキーフレームを運ぶ JSON ボディを送ることを意味します。キーフレーム入力と生成パラメータの正確なフィールド名はモデルページに記載されているので、それを正としてください。以下の構造はリクエストの形を示しています。

curl -X POST "https://api.hiapi.ai/v1/tasks" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-3-max/keyframes-to-video",
    "input": {
      "keyframes": [
        "https://example.com/frame-01.png",
        "https://example.com/frame-02.png"
      ]
    }
  }'

各部分の役割:

  • model — flux-3-max/keyframes-to-video を選択します。これにより、トランスポートコードを変更せずに、同じエンドポイントを将来他のモデルへルーティングできます。
  • input.keyframes — 順序付きの画像 URL リストです。順序は重要です。最初のフレームがクリップの開始を固定し、後続のフレームがその後の時点を導きます。
  • Authorization — 前述の bearer ヘッダーです。
  • Content-Type — JSON ボディに必須です。

レスポンスは識別子を含むタスクオブジェクトです。その ID を保存してください。以降のすべてのポーリングで使うハンドルになります。

Python での同じリクエスト

Python 版は curl 呼び出しをそのまま反映しています。requests を使うと簡潔に保てますが、依存をゼロにしたい場合は標準ライブラリでも同様に可能です。

import os
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = "https://api.hiapi.ai/v1"


def submit_video_task(keyframe_urls: list[str]) -> str:
    response = requests.post(
        f"{BASE_URL}/tasks",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        json={
            "model": "flux-3-max/keyframes-to-video",
            "input": {"keyframes": keyframe_urls},
        },
        timeout=30,
    )
    response.raise_for_status()
    return response.json()["id"]


task_id = submit_video_task([
    "https://example.com/frame-01.png",
    "https://example.com/frame-02.png",
])
print(task_id)

残しておく価値のある詳細が 2 つあります。明示的な timeout(ハングした接続がワーカープロセスを永遠にブロックしないように)と、raise_for_status()(4xx や 5xx が静かなエラーペイロードではなく例外として浮上するように)です。関数は小さく純粋に保ってください。送信して ID を返す、それだけであるべきです。ポーリングは別の話です。

タスクステータスのポーリングと結果の取得

動画生成には実際の計算時間がかかるため、API はファイルができるまでブロックしません。代わりに、タスクが完了するまで問い合わせます。ステータスが succeeded のときは出力 URL を伴い、failed のときはエラーを伴います。それ以外の値は待ち続けることを意味します。

import time
import requests


def wait_for_video(task_id: str, poll_interval: int = 5, max_wait: int = 600) -> str:
    deadline = time.monotonic() + max_wait
    while time.monotonic() < deadline:
        response = requests.get(
            f"{BASE_URL}/tasks/{task_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
            timeout=30,
        )
        response.raise_for_status()
        task = response.json()

        if task["status"] == "succeeded":
            return task["output"]["video_url"]
        if task["status"] == "failed":
            raise RuntimeError(task.get("error", "task failed"))

        time.sleep(poll_interval)

    raise TimeoutError(f"task {task_id} did not finish in time")

本番環境向けの設計上の注意:

  • ポーリング間隔 — 数秒で十分です。エンドポイントを叩き続けても負荷が増えるだけで、タスクが早く完了するわけではありません。
  • 期限 — 総待機時間には必ず上限を設け、失敗時は無限ループせずに大きな声でエラーを報告してください。
  • ダウンロード — 返される URL は一時的なものです。タスク成功後すぐにファイルを取得し、自社のストレージへ移動してください。
  • 分離 — Web アプリでは、このループをバックグラウンドワーカーで実行し、HTTP リクエストを開いたままにせず、webhook やキューでクライアントへ通知してください。

エラーとエッジケースの処理

統合の失敗のほとんどは 4 つのカテゴリに分かれます。

認証エラー (401/403)。 キーが欠落しているか、形式が不正か、もはや有効ではありません。環境変数が実際に呼び出しを行うプロセスでエクスポートされているか確認してください。よくある落とし穴は、ローカルシェルでは動作するのに、コンテナや cron ジョブではその変数が欠けていることです。

入力エラー (4xx)。 到達できないキーフレーム URL、サポートされていない画像形式、許容範囲外のパラメータは送信を拒否します。送信前に各キーフレーム URL が公開で取得可能か検証してください。遅い、または制限されたホストは、本来正しいリクエストが失敗する最も一般的な原因です。

タスクの失敗。 タスクは受け付けられた後、生成中に失敗する可能性があります。完了したポーリングを成功とみなさず、必ずエラーフィールドを確認してください。サポート依頼と関連付けられるよう、エラーとともにタスク ID を記録してください。

タイムアウトとリトライ。 送信時のネットワークエラーは、通常バックオフ付きで安全にリトライできます。ただし、送信が成功した後のリトライは安全ではありません。重複タスクを作成し、二重課金が発生する可能性があります。リトライ前にレスポンスを読み取り、ポーリングループでもジッター付き指数バックオフを使用してください。

最後に衛生面の注意:Authorization ヘッダーは絶対に記録せず、キーフレーム URL に署名付きクエリ文字列が含まれる場合はそれを除去してください。このモデルのフィールド名や制限について不明な点がある場合は、flux-3-max/keyframes-to-video のドキュメントを参照し、その値をクライアントにそのまま反映してください。

永続的なAIアーティファクトで開発を始める

APIキーを取得して、タスクベースの1つのAPIで画像・動画・音声モデルを呼び出せます。

APIドキュメントを読む