Image Generation APIs: GPT Image 2 & Gemini
Generate images with GPT Image 2 through the OpenAI-compatible Images API or with Nano Banana Pro and Nano Banana 2 through the native Gemini API.
This page keeps two separate image-generation API contracts in one place. They share your Modelflare API key and Credits, but their request and response formats are not interchangeable.
- gpt-image-2 uses the OpenAI-compatible /v1/images/generations and /v1/images/edits contracts.
- gemini-3-pro-image and gemini-3.1-flash-image use the native Gemini generateContent contract.
Choose the model family before copying an example. Do not send Gemini fields to the GPT endpoint or GPT Images fields to a Gemini endpoint.
1. GPT Image 2 — OpenAI-compatible Images API
Generate PNG images or edit reference images supplied by public URL or local upload with gpt-image-2 through the OpenAI-compatible Images API. Each request returns one image and supports medium or high quality, signed URL or base64 output, and optional SSE.
Choose an endpoint and mode
- Use https://origin.modelflare.dev/v1 for ordinary synchronous JSON requests that may take several minutes.
- Use https://modelflare.dev/v1 with stream=true for long requests through Cloudflare. Modelflare sends transport-only SSE heartbeats until the final image is ready.
- Do not redirect an in-flight POST between hosts. Choose the base URL before submitting the request.
Synchronous request
curl https://origin.modelflare.dev/v1/images/generations \
-H "Authorization: Bearer YOUR_MODELFLARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A quiet lakeside cabin at dawn, cinematic natural light",
"n": 1,
"quality": "medium",
"size": "1024x1024",
"response_format": "url",
"output_format": "png"
}'
A URL response contains a private Modelflare link that expires after one hour:
{"created":1710000000,"data":[{"url":"https://modelflare.dev/v1/images/assets/.../content?expires=...&signature=..."}]}
Set response_format to b64_json to receive the validated PNG inline instead of storing an API output object.
The live Models & Pricing page shows medium and high price points for common sizes. Billing uses the exact requested quality and dimensions, ignores ordinary routing-group multipliers, and records the final charge in usage logs.
Edit a reference image
Send one or more publicly reachable HTTP(S) image URLs to POST /v1/images/edits. Each images item contains exactly one image_url:
curl https://origin.modelflare.dev/v1/images/edits \
-H "Authorization: Bearer YOUR_MODELFLARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "Replace the background with a clean white photography studio",
"images": [
{"image_url": "https://example.com/input.png"}
],
"size": "2048x2048",
"response_format": "url"
}'
Or upload one local PNG, JPEG, or WebP file with multipart/form-data:
curl https://origin.modelflare.dev/v1/images/edits \
-H "Authorization: Bearer YOUR_MODELFLARE_API_KEY" \
-F "model=gpt-image-2" \
-F "prompt=Replace the background with a clean white photography studio" \
-F "image=@/path/to/input.png" \
-F "size=2048x2048" \
-F "response_format=url"
The multipart request must contain exactly one image file and stay within 20 MiB in total. The reference URL or uploaded file is sent to the selected upstream provider; URL inputs must remain reachable while fetched. Modelflare does not retain either reference input as an API output asset.
Streaming request
curl -N https://modelflare.dev/v1/images/generations \
-H "Authorization: Bearer YOUR_MODELFLARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-image-2","prompt":"A white cat running through a neon street in the rain","n":1,"quality":"high","size":"1024x1024","response_format":"url","stream":true}'
SSE comments are heartbeats, not model output. Stop after image_generation.completed and data: [DONE].
Supported fields
- model: required; exactly gpt-image-2.
- prompt: required; up to 32,000 Unicode characters.
- n: optional; currently must be 1.
- quality: medium (default) or high.
- size: WIDTHxHEIGHT, using multiples of 16, a maximum edge of 3840 px, an aspect ratio up to 3:1, and 0.66–8.29 MP.
- response_format: url (default) or b64_json.
- output_format: currently png only.
- stream: optional boolean.
- images: required only for /v1/images/edits; a non-empty array of objects containing one public HTTP(S) image_url each. URLs with embedded usernames or passwords are rejected.
- image: the alternative multipart input for /v1/images/edits; exactly one valid PNG, JPEG, or WebP file.
Generation requests reject reference images. The edit endpoint accepts either JSON URL references or one multipart local upload; multiple uploaded files, data/base64 inputs, masks, input_fidelity, variations, partial images, and unknown fields are rejected. Failed upstream, validation, download, or storage operations are not delivered as successful images and reserved Credits are returned through the request-id-safe refund path.
Use a normal API key. Channel-pinned keys are rejected, and a key with model limits enabled must include gpt-image-2.
2. Gemini Image — native Gemini API
Use Nano Banana Pro or Nano Banana 2 through the native Gemini request and response format. These models do not use /v1/images/generations.
Endpoint and long-request mode
- Synchronous: POST https://modelflare.dev/v1beta/models/{model}:generateContent.
- Recommended for image generation: POST https://modelflare.dev/v1beta/models/{model}:streamGenerateContent?alt=sse.
- origin.modelflare.dev does not expose /v1beta. Use the canonical domain for Gemini native requests, and prefer streaming for long jobs.
Streaming request
This example uses Nano Banana 2. Replace the model in the URL with gemini-3-pro-image to use Nano Banana Pro.
curl -N "https://modelflare.dev/v1beta/models/gemini-3.1-flash-image:streamGenerateContent?alt=sse" \
-H "x-goog-api-key: YOUR_MODELFLARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"role": "user",
"parts": [{"text": "Create a clean blue circle centered on a white background. No text."}]
}],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"}
}
}'
Response contract
Each SSE data: event is a native Gemini JSON response. The final image is base64 in candidates[].content.parts[].inlineData.data, with its MIME type in inlineData.mimeType. Text parts may appear in the same response. Finish when the final candidate reports finishReason=STOP or the stream closes; GPT events such as image_generation.completed are not used here.
Models, resolutions, and estimated prices
| Model | Resolution | Estimated price per image |
|---|---|---|
| Nano Banana Pro | 1K / 2K | US$0.06720 |
| Nano Banana Pro | 4K | US$0.12000 |
| Nano Banana 2 | 0.5K | US$0.02241 |
| Nano Banana 2 | 1K | US$0.03360 |
| Nano Banana 2 | 2K | US$0.05040 |
| Nano Banana 2 | 4K | US$0.07560 |
Use uppercase K in imageSize. Prices are estimates for one generated image; the final charge may vary slightly with request content and is recorded in usage logs.
Use a normal Modelflare API key through x-goog-api-key. The key must be able to use the gemini-image group, and model-limited keys must include the selected Gemini image model.