HiAPI
ブログ

チュートリアル

Ray 3.2 テキスト動画 API の使い方:curl、Python、そしてそのまま実行できるリクエスト

Oct 20, 2026
Ray 3.2 テキスト動画 API の使い方:curl、Python、そしてそのまま実行できるリクエスト

Ray 3.2 は hiapi のモデルカタログにあるテキスト動画モデルで、他のすべての動画モデルと同様に統一された非同期タスク API を通じて呼び出します。モデル id は ray-3.2/text-to-video で、POST /v1/tasks に送信します。プロンプトだけが唯一の調整項目である動画モデルも多い中、Ray 3.2 は異なり、実際に使える 3 つの出力制御項目——duration、resolution、aspect_ratio——を提供し、そのいずれもサーバー側で厳密に検証されます。

本ガイドでは、1 回で成功するリクエストを送れるようにします。正確な入力スキーマ(2026-10-19 に本番 API と照合して検証済み)、コピー&ペーストで実行できる curl 呼び出し、完全な Python の送信/ポーリング/ダウンロードスクリプト、そして本番環境の詳細——コールバック、冪等なリトライ、実際に目にするエラー応答——を扱います。

何を構築し、何を準備するか

目標:テキストプロンプトを送信し、タスクをポーリングし、無音の .mp4 クリップ(5 秒または 10 秒)をダウンロードします。

前提条件:

  • hiapi の API キー——コンソールから取得します。キーは sk-... の形式で、Authorization: Bearer リクエストヘッダーに含めます。タスク API が初めての場合は、まずクイックスタートから始めてください。
  • 任意の HTTP クライアント。curl と Python(requests)を示します。

Ray 3.2 の出力はクリップ単位で課金され、しかも価格は選択によって大きく変動します——現在の料金は料金ページを参照してください。プロンプトを反復する際は 540p / 5 秒から始めましょう。1080p の 10 秒クリップは、予算規模の画像レンダリングより何倍も高くつく可能性があるため、開発ループを最高設定のまま回し続けないようにしてください。

正確な入力スキーマ(必須フィールド 1 つ、厳密な列挙 3 つ)

すべては 1 つの input オブジェクトに収まります。本番 API とフィールドごとに照合して検証済みです:

フィールド 型 必須 許容値 デフォルト
prompt string はい シーン記述、最大 6000 文字 —
duration integer いいえ 5 または 10 5
resolution string いいえ 540p、720p、1080p 540p
aspect_ratio string いいえ 16:9、9:16、1:1、4:3、3:4、21:9 16:9

コードを書く前に、覚えておくべきことが 3 つあります:

  1. duration は整数であり、文字列ではありません。裸の数値を送信します——"duration": 5。これは他の一部のタスク API 動画モデルとは逆です(例えば hailuo-2.3 は "duration": "6" を文字列として要求します)。リクエストボディをあるモデルから別のモデルへ移植する場合は、このフィールドを再確認してください。これは最もよくあるモデル間の誤りです。
  2. 列挙値は検証され、切り捨てられません。範囲外の値は黙って丸められるのではなく、400 で拒否されます。2k はなく、480p もなく、2:1 もありません。
  3. prompt_optimizer、seed、negative_prompt はありません。構図は完全に aspect_ratio とプロンプトで制御します。スキーマが認識しないフィールドを送信すると、400 が返されることを想定してください——/v1/tasks の入力スキーマはモデルごとに異なるため、他の場所で有効だったキーがそのまま使えると仮定しないでください。

検証が実際に何を返すか

以下は本番エンドポイントからの実際の応答です(意図的に無効な値を送信しており、タスクは作成されず、課金もされません):

// POST with "resolution": "2k"
{"code":400,"data":null,"error_code":"INVALID_REQUEST",
 "message":"invalid input: resolution: value must be one of '540p', '720p', '1080p'"}

// POST with "duration": 7
{"code":400,"data":null,"error_code":"INVALID_REQUEST",
 "message":"invalid input: duration: value must be one of 5, 10"}

// POST with "aspect_ratio": "2:1"
{"code":400,"data":null,"error_code":"INVALID_REQUEST",
 "message":"invalid input: aspect_ratio: value must be one of '16:9', '9:16', '1:1', '4:3', '3:4', '21:9'"}

message は正確なフィールドと正確な許容セットを示します——つまり列挙値を忘れても、API が教えてくれます。duration の 5, 10 には引用符がなく(数値)、resolution の '540p' は引用符付きの文字列であることに注意してください。この引用符の違いが、どのフィールドが整数かを思い出させてくれます。

最小の実行可能な例:curl

タスクを作成します:

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ray-3.2/text-to-video",
    "input": {
      "prompt": "雨の夜、ストリートダンサーがネオンの灯りの下で回転し、水たまりにピンクとブルーの光が反射している。彼女のジャケットが回転に合わせて翻り、カメラはローアングルで彼女の周りを回り込む。シネマティック",
      "duration": 5,
      "resolution": "540p",
      "aspect_ratio": "9:16"
    }
  }'

作成レスポンスにはタスク id が含まれます(切り詰め):

{ "data": { "taskId": "task_01k..." } }

終端状態になるまでポーリングします:

curl -s https://api.hiapi.ai/v1/tasks/task_01k... \
  -H "Authorization: Bearer sk-YOUR_KEY"

タスクの実行中、data.status は処理中の状態を報告します。2 つの終端状態は success と fail です。成功時(切り詰め):

{
  "data": {
    "taskId": "task_01k...",
    "status": "success",
    "output": [ { "url": "https://.../clip.mp4" } ]
  }
}

data.output[0].url をすぐにダウンロードしてください。出力 URL は署名付きで期限切れになります——タスク URL を直接ホットリンクするのではなく、バイトを自分のストレージに保存してください。Ray 3.2 は無音の MP4(音声トラックなし)を返すため、決して来ない音声ストリームを待たないようにしてください。

完全な Python スクリプト(送信 → ポーリング → ダウンロード)

import time
import requests

API_BASE = "https://api.hiapi.ai/v1"
API_KEY = "sk-YOUR_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}


def create_task(prompt: str, duration: int = 5,
                resolution: str = "540p", aspect_ratio: str = "9:16") -> str:
    resp = requests.post(
        f"{API_BASE}/tasks",
        headers=HEADERS,
        json={
            "model": "ray-3.2/text-to-video",
            "input": {
                "prompt": prompt,
                "duration": duration,          # 5 or 10 — an INTEGER, not a string
                "resolution": resolution,      # "540p" | "720p" | "1080p"
                "aspect_ratio": aspect_ratio,  # "16:9" | "9:16" | "1:1" | "4:3" | "3:4" | "21:9"
            },
        },
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()["data"]["taskId"]


def wait_task(task_id: str, timeout_s: int = 900, poll_interval: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        resp = requests.get(f"{API_BASE}/tasks/{task_id}", headers=HEADERS, timeout=30)
        resp.raise_for_status()
        task = resp.json()["data"]
        if task["status"] == "success":
            return task
        if task["status"] == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')}: {err.get('message')}")
        time.sleep(poll_interval)  # any non-terminal status = still running
    raise TimeoutError(f"task {task_id} not finished after {timeout_s}s")


task_id = create_task(
    "紙のボートが雨水で満ちた側溝を流れ下り、水滴が水面に波紋を広げ、"
    "秋の葉が渦を巻いて漂い、水面に近いローアングルで撮影、柔らかな曇天の光"
)
print("task created:", task_id)

task = wait_task(task_id)
video_url = task["output"][0]["url"]

# Output URLs expire — download right away and store the bytes yourself.
video = requests.get(video_url, timeout=120).content
with open("ray32-clip.mp4", "wb") as f:
    f.write(video)
print(f"saved ray32-clip.mp4 ({len(video) / 1e6:.1f} MB)")

依存関係を pip install requests でインストールし、キーを自分のものに差し替えれば、タスク完了時に .mp4 がディスク上にできます。動画タスクは数秒ではなく数分かかります——ポーリングループには早く返ることを仮定するのではなく、余裕のある期限(上記では 15 分)を設定してください。

本番環境の注意点:コールバック、冪等性、エラー

ポーリングよりコールバックを優先する

スクリプト以外のあらゆる用途では、ポーリングではなくタスク作成時に webhook を登録してください:

{
  "model": "ray-3.2/text-to-video",
  "input": { "prompt": "...", "duration": 10, "resolution": "720p" },
  "callback": { "url": "https://your-app.example.com/hooks/hiapi", "when": "final" }
}

"when": "final" を使用すると、hiapi はタスクが終端状態になったときにエンドポイントを 1 回呼び出します——ポーリングのトラフィックはなく、2 回の間隔の間に完了通知を見逃すこともありません。ハンドラーは続いて GET /v1/tasks/<id> を実行する(または配信されたレスポンスボディを読む)ことで output[0].url を取得します。HTTPS エンドポイントを公開できない CLI やノートブックでは、ポーリングでも問題ありません。

リトライを冪等にする

作成呼び出しが返った瞬間に taskId を永続化してください。プロセスが生成の途中でクラッシュした場合は、保存済みの id をポーリングして復帰します——タスクを再作成しないでください。さもないと 2 回目のレンダリングに課金されます。タスク id を返す前に元の作成リクエスト自体が失敗した場合にのみ、再作成してください。Ray 3.2 はクリップ単位で課金され、高解像度のクリップは安くないため、重複作成は時間の無駄だけでなく、実質的なコスト上の誤りです。

実際に目にするエラー

以下の各行は検証済みの本番応答形状です:

症状 応答 修正方法
キーが欠落/無効 401、ネストされた {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}} Authorization: Bearer sk-... ヘッダーと、キーにアクセス権があるかを確認してください。サポートに連絡する際は request_id を添えてください。
列挙値の誤り 400 INVALID_REQUEST、フラットな {"code":400,"error_code":"INVALID_REQUEST","message":"invalid input: <field>: value must be one of ..."} message で指定されたフィールドを読んでください。正確な許容セットが列挙されています。
duration を文字列で送信 400 INVALID_REQUEST 裸の整数 5 または 10 を送信し、"5" は送らないでください。
不明なモデル id 400、error_code: "MODEL_UNAVAILABLE"、"model not available via /v1/tasks" 厳密に ray-3.2/text-to-video を使用してください——正規の id はモデルページで確認できます。
ポーリング時のタスク id の誤り 404、フラットな {"code":404,"data":null,"message":"task not found"}(注意:404 には error_code がありません) id が間違っているか、別アカウントのキーで照会しています。
ポーリング時の status: "fail" タスクの終端状態、詳細は data.error にあります data.error.code / data.error.message を読んでください。失敗したタスクは返金されます。コンテンツポリシーによるフラグや上流の容量問題はここに現れます——コンテンツフラグの場合は、言い換えたプロンプトで再試行してください。

関連リソース

  • Ray 3.2 テキスト動画モデルページ——オンラインで試用、リアルタイムのステータス、完全な料金表
  • Ray 3.2 画像動画 API——同じモデル系列ですが、テキストからではなく参照フレームをアニメーション化します(入力スキーマが異なります——本リクエストボディを再利用する前にプローブしてください)
  • Hailuo 2.3 テキスト動画 API の使い方——同種のレシピで、その duration は文字列であり、Ray の整数との有用な対比になります
  • hiapi の料金——解像度と長さごとに示されたクリップ単位の動画料金

よくある質問

モデル id は何で、どのエンドポイントを呼ぶべきですか? ray-3.2/text-to-video をトップレベルの model として POST https://api.hiapi.ai/v1/tasks に送信し、パラメータは input の下に置きます。非同期です——taskId を受け取り、その後 GET /v1/tasks/<id> をポーリングします(またはコールバックを登録します)。

duration は秒単位ですか、なぜ "5" は失敗するのですか? クリップは 5 秒または 10 秒で、このフィールドは整数です:5 または 10 を送信してください。引用符付きの文字列や、7 のような他の数値は失敗し、400 INVALID_REQUEST: duration: value must be one of 5, 10 が返されます。

解像度とアスペクト比を設定できますか? はい——まさにこれが Ray 3.2 とプロンプトのみの動画モデルとの違いです。resolution は 540p、720p、1080p のいずれか、aspect_ratio は 16:9、9:16、1:1、4:3、3:4、21:9 のいずれかです。どちらもオプション(デフォルトは 540p と 16:9)で、範囲外の値は 400 で拒否されます。

1 クリップいくらですか? Ray 3.2 はクリップ単位で課金され、解像度が最大のレバーです——同じ長さなら、1080p クリップのコストは 540p の数倍で、10 秒クリップのコストは 5 秒クリップの約 3 倍です。料金は変動するため、数値をハードコードするのではなく料金ページを確認し、540p/5 秒でプロトタイプを作成してください。

クリップに音声はありますか? いいえ——Ray 3.2 テキスト動画は無音の MP4 を返します。音声が必要な場合は、ポストプロダクションで追加するか、別の音声モデルを使用してください。

Ray 3.2 は画像動画をサポートしていますか? はい、同じタスク API 上の別のモデル id として:ray-3.2/image-to-video。入力スキーマが異なる(参照画像を受け取る)ため、本リクエストボディを再利用する前にプローブしてください——画像動画モデルページを参照してください。

生成が遅い、または止まっているように見えます。何が正常ですか? 動画タスクは数分かかります。ポーリングループでは非終端の data.status を保持して待機してください——10〜15 分の期限を設けるか、"when": "final" 付きの callback を使い、自分で間隔を推測するのではなく hiapi が終端状態を通知するようにしてください。

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

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

APIドキュメントを読む