HiAPI
ブログ

チュートリアル

hiapi /v1/tasks タスクがスタックまたはタイムアウト:診断フローとリトライ戦略

Oct 13, 2026
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. まず状態を 1 回照会し、感覚で再送信しない:GET /v1/tasks/{taskId} を実行し、data.status と data.error を読む。
  2. 状態別に対処を分岐:
    • 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 を確認する。
  3. output には有効期限がある:data.output 内のダウンロード URL には expireAt(約 7 日間)が付く。取得後は速やかに保存 / 転送し、ホットリンクを長期間保存しないこと。
  4. 認証 / リクエストの問題でないことを確認:まず以下の最小検証サンプルを実行し、key と model id の問題を排除する。
  5. 本当にリトライする場合はバックオフを使う:次の節のリトライ戦略を参照。タイトなループで同じ 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"

悪化させないリトライ戦略

  1. 指数バックオフ:5s → 15s → 45s を推奨。
  2. 最大 3 回:3 回目も失敗したらエスカレーション(モデル変更、設定を下げる、またはチケット起票)。無限ループにしないこと。
  3. 各リトライは新しいタスク:1 回の POST /v1/tasks は新しい taskId であり、新しい課金が発生する可能性がある。hiapi は対外的に「冪等な再送信」を約束していない——同じ body を再送信しても古いタスクが再利用されるとは期待しないこと。
  4. 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 なのにコールバックが一向に来ない → そのエンドポイントではコールバックに依存せず、ポーリングに変更する。

関連内部リンク

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 は毎回新しい課金タスクとなる。結果を出さなかった失敗タスクは通常、産出費は課金されないが、キュー / 計算スロットはすでに占有されている可能性がある。コストが気になる場合は後で使用量ページで照合すること。

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

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

APIドキュメントを読む