画像生成APIの使い方:/v1/images/generations を叩く
画像生成はチャットとは別のエンドポイントです。 /v1/chat/completions ではなく /v1/images/generations に、messages ではなく prompt を送ります。OpenAIのImages APIと同じ形式なので、既存のコードは接続先を変えるだけで動きます。
この記事では実際に動くコードと、課金がトークンではなく1枚あたりの定額であるという、実務でいちばん効いてくる違いを解説します。
最小のリクエスト
curl https://api.fastmetal.ai/v1/images/generations \
-H "Authorization: Bearer $FASTMETAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "z-image-turbo",
"prompt": "a red maple leaf on a white background, minimal",
"size": "1024x1024",
"n": 1
}'
| パラメータ | 内容 |
|---|---|
model | 画像生成モデルのID。モデルカタログで確認できます |
prompt | 生成したい画像の説明 |
size | 1024x1024 など。省略するとモデル側の既定値になります |
n | 生成枚数。枚数ぶん課金されます |
レスポンスの受け取り方
返ってくるのは data 配列です。実際のレスポンス構造がこれです(2026年8月29日実測)。
{
"created": 1756...,
"size": "1024x1024",
"output_format": "png",
"data": [
{
"b64_json": "iVBORw0KGgoAAAANSUhEUgAA...",
"url": null,
"revised_prompt": null
}
],
"usage": {
"total_tokens": 0,
"input_tokens": 0,
"output_tokens": 0
}
}
画像は b64_json に入っています。url はnullです。 URLが返ることを前提にしたコードは動かないので、base64をデコードしてファイルに書き出してください。
import base64
from openai import OpenAI
client = OpenAI(
api_key="<FASTMETAL_API_KEY>",
base_url="https://api.fastmetal.ai/v1",
)
resp = client.images.generate(
model="z-image-turbo",
prompt="a red maple leaf on a white background, minimal",
size="1024x1024",
n=1,
)
with open("out.png", "wb") as f:
f.write(base64.b64decode(resp.data[0].b64_json))
print("saved: out.png")
usageが0なのは壊れているからではありません
上のレスポンスで usage がすべて0になっている点に気づいたはずです。これは正常です。
画像生成はトークン課金ではなく、1枚あたりの定額課金だからです。プロンプトを長く書いても短く書いても、size を変えても、1枚の価格は変わりません。だから usage を見てもコストは分かりません。
実務上の意味は3つあります。
- コストは「枚数 × 単価」で完全に予測できます。 テキスト生成のように出力の長さで上下しません
nが課金の全てです。n: 4は4枚ぶん課金されます。試行錯誤の段階ではn: 1に固定してくださいusageを集計しているコードは、画像生成のコストを見落とします。 枚数を自分で数える必要があります
モデルごとの1枚あたりの価格は料金ページで確認してください。プロンプトを何度も書き直す使い方では、1回あたりが安いモデルで試して、仕上げだけ高品質なモデルに切り替えるのが合理的です。
モデルの選び方
FastMetalでは複数の画像生成モデルを提供しています。用途で分けるとこうなります。
- 速さと単価を優先する試行錯誤 — 低価格帯のモデルで構図やプロンプトを詰める
- 仕上げ・指示への忠実さ — 高品質帯のモデルで最終出力を作る
モデルごとの得意不得意は画像生成モデルの比較記事で扱っています。カタログと現在の価格はモデルカタログを参照してください。
日本語の文字は入れない
実用上いちばん重要な注意点です。現在の画像生成モデルは、画像の中の日本語をきれいに描けません。 崩れた文字や、それらしいだけの記号列になります。
対策は単純で、文字を入れない構図で生成し、文字は後からデザインツールで載せることです。プロンプト側に「文字は入れない」「上部に余白を空ける」と指示しておくと、後からテキストを重ねやすい画像が得られます。
チャット経由との違い
一部の画像モデルは /v1/chat/completions からも呼べますが、課金の仕組みが変わります。 画像パスは1枚あたりの定額、チャットパスはトークン課金です。同じモデルでも請求の出方が違うので、どちらのエンドポイントを使っているかを意識してください。
用途がはっきり「画像を1枚作る」なら、/v1/images/generations を使うのが素直です。
つまずきやすい点
url を読もうとする
b64_json に入っています。url はnullです。
usage からコストを計算しようとする
0です。枚数で計算してください。
n を大きくして試す
枚数ぶん課金されます。プロンプトの検証は n: 1 で。
size を省略する
モデル側の既定値になります。狙ったアスペクト比があるなら明示してください。ただし対応する size はモデルごとに異なります。
プロンプトを日本語で書く モデルによっては英語のほうが指示が通ります。うまくいかないときは英語で書き直してみてください。
次のステップ
生成ではなく画像を読ませたい場合は、画像入力(Vision)の使い方を参照してください。エンドポイントもパラメータも別物です。
動画を生成したい場合は動画生成APIの使い方があります。こちらは非同期のジョブ形式で、作りがかなり異なります。
エージェントから画像を生成したい場合は、MCPサーバーの generate_image ツールが同じ処理を担当します。
よくある質問
Q. レスポンスの usage が全部0なのですが、バグですか?
いいえ、正常です。画像生成はトークン課金ではなく1枚あたりの定額課金なので、トークン数は記録されません。コストは生成枚数から計算してください。
Q. 画像はURLで返ってきますか?
いいえ。data[0].b64_json にbase64で入っています。デコードしてファイルに保存してください。
Q. size を大きくすると高くなりますか?
1枚あたりの定額なので、解像度によって価格は変わりません。ただし対応する size はモデルごとに異なります。
Q. 画像の中に日本語を入れられますか? 現状きれいには描けません。文字なしで生成して、後からデザインツールで載せることをおすすめします。
まとめ
画像生成は /v1/images/generations に prompt を送り、data[0].b64_json をデコードして保存する——それだけです。テキスト生成と決定的に違うのは課金で、トークンではなく1枚あたりの定額なので、usage は0のまま、コストは枚数で決まります。