Comfy Router はまだ一般提供されていません。 以下のルート
POST /v2/models/{provider}/{model} と、そのカタログおよびスキーマの関連ルートは、
まだリクエストを処理していません。現在、認証付きの呼び出しは 404 を返します。このページは、
これらのルートが将来提供する契約を文書化したものであり、ロールアウトに先立って公開されているため、
統合をその契約に合わせて作成する準備ができます。これは、現在実際に試すことができる動作の説明ではありません。https://api.comfy.org。ルートは POST /v2/models/{provider}/{model} です。リクエストボディはモデル独自のネイティブ JSON 入力であり、200 応答にはモデル独自のネイティブ JSON 出力が含まれます。Router は入力と出力のどちらもラップしないため、パートナーの API に対して既に作成した呼び出しは、ホストを変更するだけで Router の呼び出しになります。
このページで bfl/flux-2-pro を使用する理由
bfl/flux-2-pro は p50 で約 3.1 秒で応答を返します。これは Router 上で測定された中で最速の経路であり、5 分での最初の結果を現実的にするものです。より遅いモデルでは、その予算は読むことではなく待つことに費やされることになるでしょう。
これは便宜上のものであり、必須ではありません。Router 上の他のすべてのモデルもまったく同じ方法で呼び出されます。同じルート、同じ認証情報ヘッダー、同じエラーバケット、同じ X-Comfy-Request-Id です。変更されるのは、モデル ID、リクエスト本文内のフィールド、そして読み取る結果の形状だけです。たとえば Gemini は、p95 の 72.8 秒を余裕を持ってクリアします。Router は、ポーリング用のジョブハンドルを返すのではなく、生成全体にわたって接続を保持します。長時間の呼び出しを途中で打ち切るエッジ側の上限はありませんが、Router は呼び出し自体に制限を設けています。Router 自身のサーバーデッドライン(デフォルトで 10 分)が接続を保持する最長の時間であり、それを過ぎると 504 / deadline_exceeded を返し、課金は行われません。ID を差し替えて、そのモデルのフィールドを(後述の)モデル自身のスキーマから読み取ってください。
APIキーを取得する
RouterはComfy APIキーで認証します。platform.comfy.org/profile/api-keys で作成し、環境変数に設定してください。以下の2つのサンプルはどちらもCOMFY_API_KEY を読み取り、キーをリテラルとして受け取らないため、コピー&ペーストしたスニペットが認証情報をコミットに持ち込むことはありません。
comfyui- キーは X-API-Key ヘッダーと Authorization: Bearer のどちらでも受け付けられます。サービスが API キーだと判断する手がかりはヘッダーではなく comfyui- プレフィックスなので、どちらの形式でも同じように参照されます。以下の例では X-API-Key を使用していますが、Authorization: Bearer $COMFY_API_KEY でも同等です。両方のヘッダーが送信された場合は、X-API-Key のキーが優先されます。comfyui- プレフィックスのない値を Authorization: Bearer で送ると、Cloud/Firebase の JWT として扱われます(生成済みの APIリファレンス が「bearer token」という言葉で意味しているのはこれです)。401 と X-Comfy-Error-Type: unauthorized を返します。ワークスペースがモデルを実行できないリクエストは、403 / forbidden を返します。
cURL
スクリプト、スモークテスト、ターミナルへのコピー&貼り付けに最適な、最短の呼び出し方法です:X-Comfy-Error-Type ヘッダーがエラーの分類を示します。後で問い合わせる必要があるレスポンスからは、X-Comfy-Request-Id ヘッダーを保存しておいてください。macOS と Linux にはどちらも uuidgen が同梱されています。Windows では、New-Guid または任意の UUID ソースを使用して Idempotency-Key を生成してください。
Python
Python 3.9+ とhttpx が必要です:
quickstart.py として保存し、python quickstart.py で実行します:
TypeScript
Node 18+(組み込みのfetch、AbortSignal.timeout、crypto.randomUUID を使用)と、TypeScript を直接実行するための tsx が必要です:
quickstart.mts として保存します。.mts 拡張子は重要です。このファイルはトップレベルの await を使用するため ES モジュールが必要だからです。npx tsx quickstart.mts で実行します:
422 の読み方
422 は、最初の実呼び出しの前に理解しておく価値がある唯一のエラーです。なぜなら、それは自分自身が引き起こすエラーだからです。これは、Router がボディをモデル自身の入力スキーマに対して検証し、拒否したことを意味します。つまり、必須フィールドが不足している、値が範囲外、画像が小さすぎる、といったケースです。このチェックはプロバイダー呼び出しの前に実行されるため、422 はコストがかかりません。パートナーの支出もなく、後で請求に関する質問に答える必要もありません。これは 400 とは異なります。400 はリクエストレベルの失敗(不正なカーソル、読み取れないエンベロープ)であり、フィールド単位の失敗ではありません。
そのボディは FastAPI の detail[] 形状です。問題のあるフィールドごとに1つのエントリを持つ配列で、各エントリは独自の loc(フィールドへのパス)、msg、type(プロバイダーレベルの具体的な理由: missing、value_error、image_too_small)、および理由に境界が含まれる場合は ctx を保持します。このフィールド単位の粒度こそが、上記のサンプルが配列を例外メッセージにフラット化せずにデータとして保持する理由です。
入力スキーマがまだ作成されていないモデルは、任意の JSON オブジェクトを受け入れる文書化された
寛容なフォールバックとして解決されるため、
422 を返す代わりにボディを転送します。
上記のサンプルは、スキーマが存在する場合に処理する形状を示しています。422 ブロックは、
その特定のボディに対する保証された応答ではなく、エラーパスとして扱ってください。error_type フィールドがないため、422 では X-Comfy-Error-Type ヘッダーが唯一の機械可読なバケットになります。両方のサンプルはまさにその理由から、ヘッダーからバケットを最初に読み取ります。これにより、Router が返すすべての失敗を1つのエラークラスでカバーできます。
X-Comfy-Request-Id は、成功、4xx、5xx を問わずすべてのレスポンスに含まれており、サポートリクエストで引用する ID です。両方のサンプルは、ヘッダーロギングを有効にして再実行する代わりに、例外に ID を添付します。
自分のキーで安全に再試行する
上の 2 つのサンプルはどちらもIdempotency-Key を送信しています。これは独立したセクションを設ける価値があります。このヘッダーはキーを正しく扱った場合にのみ役割を果たし、決定的な違いを生む手順は、リクエストが送信される前に行われるからです。
キーは自分で用意する。 Router がキーを発行してくれることはありません。論理的な呼び出しごとに新しいキーを生成し(想定されている形式は UUID です)、その呼び出しの再試行では毎回同じキーを再利用してください。試行ごとに新しいキーを使っても何も得られません。まったく異なる 2 つの呼び出しでキーを再利用すると 409 になります。同じキーで異なるリクエスト(ボディが異なる場合だけでなく、モデルパス、クエリ文字列、メソッドが異なる場合も含む)を送ることは、静かな上書きではなく競合として扱われるからです。
送信する前に永続化する。 キーは、レスポンスが返ってきた後ではなく、POST が送出される前に、リクエストより長く生き残る場所(生成対象の行、ジョブレコード、キューメッセージなど)に書き込んでください。クラッシュしたプロセスのメモリ上にしか存在しなかったキーは再送できず、Router の記録から回答されるはずだった再試行は、別途課金される新しい実行になってしまいます。これは飛ばしやすく、飛ばすと高くつく唯一の手順です。
そのキーで再試行する。 再試行時、Router はそのキーの状態をまだ保持している限り、再実行ではなく回答を返します。
上の Python サンプルの続きです。ここでのファイルは、すでに手元にある任意の永続ストアの代わりです。
重要なのは仕組みではなく順序です。キーだけでなく、リクエスト全体をキーと並べて
永続化してください。再試行では同じモデルと引数を再送する必要があり、再起動後に
メモリから組み直したリクエストは、空白 1 つ分でも違えば
409 になります。一方、
新しいキーで送れば、2 回目の課金対象の生成になります。
キーが保証するのは課金であり、配信ではありません。 キーが課金されるのは最大 1 回です。
キーが最大 1 回しかディスパッチされないという約束ではなく、失った呼び出しを回収可能にする
ものでもありません。呼び出し途中で接続が切れ、何もコミットされなかった場合、キーは解放され、
そのキーでの再試行は、取り逃した結果を渡すのではなく新しい実行を開始します。
「再試行は新しい実行を生む」ことを前提に計画し、再生は保証ではなく、うまくいった場合の
ケースとして扱ってください。永続的で再開可能な「再接続して回収する」は、Router がまだ
持っていないキュー投入パスの機能です。
制限事項 を参照してください。
モデルを探す
bfl/flux-2-pro は 1 つの ID にすぎず、残りはカタログにあります。GET /v2/models は Router が実行できるすべてのモデルを 1 ページずつ一覧表示し、各エントリには呼び出しに必要な情報がそのまま含まれています。パスに入れる id、個別に保持される provider と model のセグメント、そして何かを消費する前に分岐判断に使える billing ブロックです。
next_cursor を ?cursor= としてそのまま送り返し、ページが短く返ってきたときではなく、has_more が false になったときに停止します。カーソルは不透明な値で、往復させるだけのものです。Router が受け付けないカーソルは 400 / invalid_input になり、黙って 1 ページ目からやり直されることはありません。カーソルはカタログのソート順における位置なので、モデルを追加または削除するデプロイをまたいでも有効です。すでに通過した位置に追加されたモデルは、その走査では単に訪問されないだけです。一覧に対する 503 / service_unavailable は、Router がまだ応答できない(Pod がリリース状態をまだ読み込み中である)ことを意味します。再試行してください。空のカタログと解釈してはいけません。レスポンスの limit は実際に提供されたページサイズです。上限を超えるリクエストは拒否されるのではなく上限に丸められるため、返ってきた数値でページングしてください。デプロイ済みでも未リリースのモデルは、どのページにも単に現れません。
モデルのフィールドの由来
prompt は bfl/flux-2-pro が必須とする唯一のフィールドです。次に必要になるのは width、height、seed、output_format です。時間とともにずれる可能性のあるフィールド一覧を再掲する代わりに、モデルのスキーマをライブで確認してください:
id を選び、その呼び出しパスに /openapi.json を追加すれば、返ってきた内容に基づいて生成できます。
次のステップ
- Comfy Router API リファレンス: すべてのエンドポイント、すべてのパラメータ、そして 15 種類すべてのエラー分類を網羅しています。
- Comfy Router の制限事項: 現在 Router が対応していない機能と、その代わりに使用すべきものを説明しています。