はじめに
画像生成 API は、テキスト生成よりも「まあ試しに 1 回」が重く感じます。私も新しい model ID を見つけるとすぐ curl したくなるのですが、画像や動画は endpoint、価格単位、権限、availability status が混ざると、失敗したときに何を見ればいいのか分からなくなりがちです。
今回は Flatkey AI の public catalog を例に、画像生成 API を叩く前に model ID、status、pricing memo、route、tiny smoke test を 1 枚の表にしておく作業をメモします。
先に書いておくと、このランタイムには FLATKEY_API_KEY がなかったので、有料の画像生成はしていません。dummy token で route の認証エラーまで見ただけです。なので「画像生成が成功した記事」ではなく、「試す前に確認する表を作った記事」です。
今回の前提
確認日は 2026-07-04 09:33 JST です。
| 項目 | 値 |
|---|---|
| public catalog | https://router.flatkey.ai/api/pricing |
| base URL signal | https://router.flatkey.ai/v1 |
| image route | POST /v1/images/generations |
| Gemini route | POST /v1beta/models/{model}:generateContent |
| API key | この実行環境にはなし |
public catalog は HTTP 200 で取れました。pricing_version は a42d372ccf0b5dd13ecf71203521f9d2、data は 45 rows でした。過去のメモではもっと多い rows の日もあったので、記事や README に固定値として書くより、確認日と一緒に残す方がよさそうです。
先に見る表
私が最初に作るなら、このくらいの表にします。
| model ID | route | status | pricing memo | smoke test |
|---|---|---|---|---|
gpt-image-2 |
/v1/images/generations |
official_unsupported |
model_ratio=3.325, image_ratio=1.6
|
dummy token で HTTP 401 |
nano-banana-pro-preview |
/v1/images/generations |
unknown_failure |
model_ratio=1, completion_ratio=6
|
未実行 |
gemini-2.5-flash-image |
/v1beta/models/{model}:generateContent or /v1/chat/completions
|
available |
model_ratio=0.15, completion_ratio=100
|
未実行 |
gemini-3-pro-image |
/v1beta/models/{model}:generateContent or /v1/chat/completions
|
available |
model_ratio=1, completion_ratio=6
|
未実行 |
gemini-3-pro-image-preview |
/v1beta/models/{model}:generateContent or /v1/chat/completions
|
available |
model_ratio=1, completion_ratio=60
|
未実行 |
この表のポイントは、status と smoke test を分けることです。catalog 上で available でも、自分の key、group、route で成功したとは限りません。逆に今回の gpt-image-2 は catalog に行として存在しますが、status は official_unsupported でした。ここを見落として「モデル名はあるから使える」と書くと危ないと思います。
public pricing catalog を取る
まずは public catalog を取ります。
curl -sS https://router.flatkey.ai/api/pricing \
| jq '{success, pricing_version, data_count: (.data | length), supported_endpoint}'
今回見た supported_endpoint はこうでした。
{
"gemini": {
"path": "/v1beta/models/{model}:generateContent",
"method": "POST"
},
"image-generation": {
"path": "/v1/images/generations",
"method": "POST"
},
"openai": {
"path": "/v1/chat/completions",
"method": "POST"
},
"openai-video": {
"path": "/v1/video/generations",
"method": "POST"
},
"video": {
"path": "/v1/videos",
"method": "POST"
}
}
画像っぽい model ID だけ見たいときは、最初は雑に絞ってもよいと思います。
curl -sS https://router.flatkey.ai/api/pricing \
| jq -r '
.data[]
| select(
(.model_name | test("image|imagen|banana|gpt-image"; "i"))
or ((.supported_endpoint_types // []) | any(test("image"; "i")))
)
| [
.model_name,
((.supported_endpoint_types // []) | join(",")),
(.availability_status // ""),
((.enable_groups // []) | join(",")),
(.model_ratio | tostring),
(.completion_ratio | tostring),
(.image_ratio | tostring)
]
| @tsv'
この時点では、まだ API を叩いていません。あくまで「候補を確認した」段階です。
endpoint type を path に戻す
catalog の supported_endpoint_types は便利ですが、そのままだと実際に叩く path が曖昧です。私はここを毎回 path に戻してからメモします。
| endpoint type | path | メモ |
|---|---|---|
image-generation |
/v1/images/generations |
OpenAI 互換の画像生成として扱う候補 |
gemini |
/v1beta/models/{model}:generateContent |
Gemini 形式で叩く候補 |
openai |
/v1/chat/completions |
chat completions として叩く候補 |
openai-video |
/v1/video/generations |
video generation 系の候補 |
たとえば gemini-2.5-flash-image は gemini,openai の両方が付いていました。だからといって、何も考えずに /v1/images/generations に投げるのではなく、どの API 形状で使うつもりなのかを先に決めます。
status を成功扱いしない
今回いちばん記事に残したかったのはここです。
gpt-image-2 は Flatkey の public catalog に行としてありました。ただし status は official_unsupported で、reason には上流が現在その model をサポートしていない可能性がある、という趣旨の説明が入っていました。
一方、nano-banana-pro-preview は unknown_failure でした。これは「公式に下がったと断定はしないが、検出は失敗している」くらいに読むのがよさそうです。
私なら README や検証 issue にはこう書きます。
| model | catalog status | action |
|---|---|---|
| gpt-image-2 | official_unsupported | 今回は成功候補にしない |
| nano-banana-pro-preview | unknown_failure | account/key つきで別途確認 |
| gemini-2.5-flash-image | available | route を決めて tiny test |
この書き方にしておくと、あとで誰かが「なぜ gpt-image-2 を試さなかったのか」を追いやすいです。私はこの説明がないまま model ID だけ残すと、数日後に自分で忘れます。
tiny smoke test は route 確認まで
このランタイムには FLATKEY_API_KEY がなかったので、今回は本物の画像生成はしていません。代わりに dummy token で route に到達するところだけ見ました。
curl -sS -X POST https://router.flatkey.ai/v1/images/generations \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-fk-redacted-smoke-test' \
--data '{
"model": "gpt-image-2",
"prompt": "tiny smoke test: one blue dot",
"size": "256x256",
"n": 1
}'
結果は HTTP 401 でした。
{
"error": {
"code": "",
"message": "Invalid token (request id: redacted)",
"type": "new_api_error"
}
}
これは成功ではありません。ただ、DNS や path が完全に違う状態ではなく、route まで届いて認証で落ちた、という確認にはなります。記事や issue には smoke test: HTTP 401 invalid token と書き、generation succeeded とは絶対に書かないようにします。
repo に残すメモ
実際の repo には、こういう形で残すのが扱いやすいと思いました。
verified_at: 2026-07-04T09:33:04+09:00
base_url: https://router.flatkey.ai/v1
source_catalog: https://router.flatkey.ai/api/pricing
image_generation_candidates:
- model: gpt-image-2
route: POST /v1/images/generations
catalog_status: official_unsupported
smoke: HTTP 401 with dummy token, no generation attempted
decision: do not use as success sample
- model: nano-banana-pro-preview
route: POST /v1/images/generations
catalog_status: unknown_failure
smoke: not run
decision: needs real key and reviewer-approved test
- model: gemini-2.5-flash-image
route: POST /v1beta/models/{model}:generateContent or POST /v1/chat/completions
catalog_status: available
smoke: not run
decision: candidate only
価格も同じです。homepage のおすすめカードには GPT Image 2 が $4 / 1M、Seedance 2.0 が $0.063 / sec と出ていました。一方で public pricing API の行には model_ratio や completion_ratio、一部 image_ratio が出ます。ここを勝手に USD の請求額へ変換せず、まずは「どの source のどの field を見たか」までを残すのが安全だと思います。
特に画像系は、テキストの token 単価だけを見ていると読み違えやすいです。価格カードの単位、catalog の ratio、実際の usage の出方を同じ列に押し込むと、あとで計算根拠が曖昧になります。私は display_price、catalog_ratio、runtime_usage のように列を分けて、まだ runtime usage がないものは空欄のままにします。空欄が残っている方が、未確認なのに確認済みに見えるよりましだと思います。
まとめ
画像生成 API を試す前に、私は次の 5 つを分けてメモすることにしました。
-
model ID: catalog 上の文字列 -
route: 実際に叩く path -
status:available、official_unsupported、unknown_failureなど -
pricing memo: price 表示か ratio field か、source を明記する -
smoke test: 成功、失敗、未実行を混ぜない
今回の確認では、gpt-image-2 は行としては存在するものの official_unsupported でした。nano-banana-pro-preview は unknown_failure、Gemini image 系のいくつかは available でした。ただし、私は実 key で画像生成を通していないので、この記事では「動いた model」とは呼びません。
このくらい地味な表を先に作っておくと、画像 API の検証で失敗したときに、model が悪いのか、route が違うのか、key がないのか、status を見落としたのかを切り分けやすいと思います。
おわりに
画像生成や動画生成は、1 回の試行前に少し身構えます。だからこそ、成功ログだけではなく、official_unsupported や HTTP 401 も含めて、日付つきで残しておくのが大事だと思いました。
間違いあったらコメントください。よろしくお願いします。