チュートリアル
hiapi /v1/tasks タスクがスタックまたはタイムアウト:診断フローとリトライ戦略
POST https://api.hiapi.ai/v1/tasks にタスクを送信し、taskId を取得したものの、GET /v1/tasks/{taskId} で照会すると data.status が数分経っても queued や handling のまま——「スタック」しているように見える。あるいは、ポーリングループが自分で設定した上限に達しても終端状態にならず、タイムアウトを報告している。まずは慌てて再送信しないこと:hiapi のタスクは非同期であり、「まだ終わっていない」と「すでに失敗した」は別物だ。診断をしっかり行ってから対処すれば、悪化させることはない。
もし
data.statusがすでにfailでerror.codeがTASK_TIMEOUTになっている場合、またはブラウザ/プロキシが文字通りの HTTP 504 を返している場合は、別の種類の問題だ(タスクが本当に実行失敗したか、タイムアウトがあなたと hiapi の間のネットワーク層で発生している)。詳しくは HiAPI タスクタイムアウトと 504 エラーのトラブルシューティング を参照。本記事はタスクがなかなか終端状態に達しない「スタック」シナリオのみを扱う。
問題の症状
「スタック」したタスクを照会すると、おおよそ次のような結果が返る(HTTP 200 だがタスクはまだ非終端状態):
{
"data": {
"taskId": "…",
"status": "queued",
"output": null,
"error": null
}
}
重要な特徴:data.status が queued(キュー待ち)/ handling(処理中)/ archiving(アーカイブ中)のいずれかで、data.error が null、data.output にまだ内容がない。これはタスクが正常であり、単にまだ実行が完了していないことを示す。
hiapi のタスク終端状態は 2 つだけ:data.status が success または fail だ。これら以外であればタスクは未完了であり、「スタック」はほぼすべてこの非終端状態の間に発生する。
混同しやすい 2 つの「偽スタック」:
照会が直接
404を返す:{"code": 404, "data": null, "message": "task not found"}これはスタックではなく、
taskIdの誤記、タスクがそもそも作成されていない、またはタスクレコードが期限切れになっている。送信時に取得したdata.taskIdを確認すること。送信時に同期的に拒否された(そもそも
taskIdが取得できていない)。例えば model の誤記:{"code": 400, "data": null, "error_code": "MODEL_UNAVAILABLE", "message": "model not available via /v1/tasks"}これはリクエスト自体の問題であり、タスクのスタックではない。修正して再送信すればよい。
よくある原因(発生確率順)
1. キューの滞留(最も一般的)
特定のモデル(画像モデル、動画モデル、またはその他の重い計算モデル)が大量に呼び出されている場合、あなたのタスクはそのモデルのキューで worker に拾われるのを待つ。
- シグナル:
data.statusがqueued、data.errorがnull、送信からの経過時間が短い。 - 修正:ポーリングのペースを落とし、5〜10 秒に 1 回で十分。100ms で空回ししないこと。ほとんどのタスクは 1〜2 分以内に拾われる。
2. 重いモデルはそもそも時間がかかる
タスクはすでに拾われている(handling/archiving)が、そのモデルの 1 回の実行はそもそも遅い——長い動画、高解像度、多数の参照画像などはいずれも所要時間を大幅に延ばす。
- シグナル:
data.statusがhandlingまたはarchivingで、数分間続くがエラーは出ない。 - 修正:重いタスクにはポーリング上限をより広く設定する(モデルの能力に応じて余裕を持たせる)。時間がかかる ≠ 失敗。結果が出る直前に自分で打ち切らないこと。
3. ポーリングの仕方が悪い(「スタック」と誤判定されやすい)
多くの「スタック」は実はクライアント側の問題だ:ポーリング間隔が短すぎて自分が混乱する、上限を設けていない、または上限が短すぎて早々に諦める。
- シグナル:サーバー側の
data.statusは正常に進んでいるが、ループが早々にタイムアウトを投げている、またはdata.statusをそもそも読んでいない。 - 修正:固定間隔(5 秒推奨)+ 適切な上限(通常タスクは約 10 分、重いタスクはより長く)を使う。タイムアウトはあなたのループで判定すべきであり、サーバー側の
timeout状態を期待してはいけない——hiapi にそのような状態はない。
4. コールバック先に到達できない
タスク送信時にコールバック(callback)を指定した場合、タスク自体はすでに success になっている可能性があるが、結果があなたのところに届かないため「動きがない」ように見える。
- シグナル:能動的に照会すると
data.statusはすでにsuccess、data.outputに内容があるが、コールバック先には何も届いていない。 - 修正:コールバック URL は公網から到達可能で、
POSTを受信でき、約 10 秒以内に2xxを返す必要がある。そうでなければポーリングに切り替える。詳細は hiapi タスクのコールバックが発火しない理由 を参照。
修正手順
- まず状態を 1 回照会し、感覚で再送信しない:
GET /v1/tasks/{taskId}を実行し、data.statusとdata.errorを読む。 - 状態別に対処を分岐:
queued/handling/archiving→ まだ実行中。5〜10 秒待って再照会(原因 1 / 2)。success→ タスク成功。data.outputから結果を取得。コールバックを待っているのに届かない場合は原因 4。fail→data.error.codeとdata.error.messageを読む。TASK_TIMEOUTの場合は タイムアウトと 504 のガイド を参照。404 task not found→taskIdが間違っているか作成に失敗している。送信レスポンスのdata.taskIdを確認する。
- output には有効期限がある:
data.output内のダウンロード URL にはexpireAt(約 7 日間)が付く。取得後は速やかに保存 / 転送し、ホットリンクを長期間保存しないこと。 - 認証 / リクエストの問題でないことを確認:まず以下の最小検証サンプルを実行し、key と model id の問題を排除する。
- 本当にリトライする場合はバックオフを使う:次の節のリトライ戦略を参照。タイトなループで同じ body を繰り返し再送信しないこと。
最小検証サンプル
最小リクエストで key とタスクインターフェース自体が通ることを確認する。model は裸の id を使う(例:gpt-image-2):
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"input": { "prompt": "a single red apple on a white background, studio lighting" }
}'
送信に成功すると {"data":{"taskId":"…","status":"queued"}} のようなレスポンスが得られる。taskId を使ってポーリングする:
curl -s "https://api.hiapi.ai/v1/tasks/<taskId>" \
-H "Authorization: Bearer $HIAPI_API_KEY"
401が返り、body が{"error":{"code":"permission_denied","type":"hiapi_error","request_id":"…"}}の場合——問題は key にあり、タスクにはない。まず API Key 無効エラーのトラブルシューティング を参照。- 送信が
400+"error_code":"MODEL_UNAVAILABLE"で拒否される場合——model id の問題だ。裸の id を渡し、hiapi「モデル利用不可」エラー と照合する。
悪化させないリトライ戦略
- 指数バックオフ:5s → 15s → 45s を推奨。
- 最大 3 回:3 回目も失敗したらエスカレーション(モデル変更、設定を下げる、またはチケット起票)。無限ループにしないこと。
- 各リトライは新しいタスク:1 回の
POST /v1/tasksは新しいtaskIdであり、新しい課金が発生する可能性がある。hiapi は対外的に「冪等な再送信」を約束していない——同じ body を再送信しても古いタスクが再利用されるとは期待しないこと。 - 429 に遭遇した場合、遅くするのは送信レートであり、ポーリングレートではない:hiapi レート制限(429)エラーの修正方法 を参照。
堅実な Python ポーリング + バックオフの例:
import time, os, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}
def submit_and_wait(body, poll_interval=5, max_wait=600):
r = requests.post(BASE, json=body, headers=HEADERS, timeout=30)
r.raise_for_status()
task_id = r.json()["data"]["taskId"]
deadline = time.time() + max_wait
while time.time() < deadline:
time.sleep(poll_interval)
data = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30).json()
status = (data.get("data") or {}).get("status")
if status == "success":
return data["data"]["output"]
if status == "fail":
raise RuntimeError(data["data"].get("error"))
# queued / handling / archiving → 继续等
raise TimeoutError(f"task {task_id} 在 {max_wait}s 内未到终态")
終端状態の判定は success と fail のみを認識することに注意。それ以外の状態(queued / handling / archiving)は一律で待機を続け、タイムアウトはあなたの max_wait で決まる。
いつエスカレーションすべきか
- バックオフ付きリトライを 3 回行い、毎回同じ
data.error.code→ 一時的な揺らぎではない。入力を変更するかモデルを切り替える。 - タスクが長時間
queuedのままで全く進展がない → hiapi コンソール でプラットフォーム通知がないか確認し、request_idを添えてチケットを起票する。 data.statusがすでにsuccessなのにコールバックが一向に来ない → そのエンドポイントではコールバックに依存せず、ポーリングに変更する。
関連内部リンク
- HiAPI タスクタイムアウトと 504 エラーのトラブルシューティング——タスクが本当に
TASK_TIMEOUTでfailしている場合、または文字通りの 504 が見える場合に読む記事。 - hiapi タスクのコールバックが発火しない理由——コールバックが来ないことで「偽スタック」になる専用記事。
- API Key 無効エラーのトラブルシューティング|モデル利用不可エラー|レート制限 429 エラー
FAQ
Q:どのくらいで「タイムアウト」とみなす?統一されたタイムアウト時間はある?
A:統一された数値はなく、モデルに依存する。重いタスク(長い動画、高解像度)はより長い。また hiapi にはサーバー側の timeout 状態はない——いわゆるタイムアウトは通常、あなたのポーリングループが自分で設定した上限に達したことを意味する。本当にサーバー側でタイムアウト失敗したタスクは data.status:"fail" + error.code:"TASK_TIMEOUT" になり、その場合は タイムアウトと 504 のガイド を参照。
Q:タスクが queued で 30 秒経ったら、キャンセルしてリトライすべき?
A:すべきでない。30 秒はどの非自明なモデルにとっても正常範囲内だ。少なくとも 2 分待ってからリトライを検討すること。
Q:実行中のタスクをキャンセルできる? A:一般的にキャンセルはサポートされていない。仮にキャンセルできても、キュー / 計算スロットは通常すでに占有されている。実行を完了させて結果を照会する方が得策だ。
Q:同じリクエストが昨日は実行できたのに、今日はスタックする? A:ほとんどはモデル層のキュー滞留(原因 1)。同程度の能力を持つ別のモデルに切り替えるか、5〜10 分待ってキューが落ち着いてから再試行する。
Q:すべてのタスクがタイムアウトするが、自分のアカウントの問題? A:まず hiapi コンソール でアカウントレベルの通知がないか確認し、次にレート制限されていないか確認する(429 ガイド参照)。どちらも正常で、特定の 1 つのモデルだけが失敗しているなら、それはそのモデルのキューまたはバックエンドの問題であり、あなたのアカウントではない可能性が高い。
Q:スタック / タイムアウトしたタスクをリトライすると二重課金される?
A:POST /v1/tasks は毎回新しい課金タスクとなる。結果を出さなかった失敗タスクは通常、産出費は課金されないが、キュー / 計算スロットはすでに占有されている可能性がある。コストが気になる場合は後で使用量ページで照合すること。
関連記事
すべての記事を見る →-
チュートリアル
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 チュートリアル
リクエスト優先の実践デモ:プロンプトから動画クリップへの呼び出しを構築し、リクエストを送信し、完了状態をポーリングし、結果をダウンロードする