Images
Generate images through Quotaflow's OpenAI-compatible Images API.
Endpoint
POST https://api.quotaflow.ai/openai/v1/images/generations
POST https://api.quotaflow.ai/openai/v1/images/edits
/images/generations and /images/edits are synchronous. Async image jobs and Responses image_generation are not part of the active public contract; they fail closed and never fall back to a legacy route.
Supported model
gpt-image-2openai/gpt-image-2(alias)- Gemini image models such as
gemini-3.1-flash-image-preview(see the Gemini image model request contract below; they can also be called natively on GeminigenerateContent)
Call /models to confirm that the model is enabled for your key.
Generate an image
curl https://api.quotaflow.ai/openai/v1/images/generations \
-H "Authorization: Bearer $QUOTAFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A clean product screenshot style illustration of a teal API dashboard.",
"size": "1024x1024",
"quality": "medium",
"response_format": "b64_json"
}'
For generation requests, n controls the requested number of output images. Keep the HTTP connection open until the synchronous response completes.
Request rules
- Use
https://api.quotaflow.ai; the dashboard host does not accept API requests. response_format: "b64_json"returns inline image bytes.response_format: "url"may return a temporary Quotaflow-hosted URL when hosted output is enabled.- Do not send text reasoning controls such as top-level
thinking. - Unsupported parameters fail closed and are not retried on another execution path.
- Image usage and customer billing come from the immutable V3 Image2 BillingFact. Unverified provider values are not used as billing authority.
Response shape
Successful responses use the OpenAI-compatible data array and may include a usage object. Download temporary URL output before it expires.
For Gemini image models (gemini-3.1-flash-image-preview and related nanobanana models), usage is Quotaflow's own metered output token count (output_tokens and total_tokens), which is also used for billing. It omits input_tokens because the product is priced per image and never uses the vendor's self-reported token count. For gpt-image-2, usage carries input_tokens, output_tokens and total_tokens, with image/text breakdowns in input_tokens_details and output_tokens_details. These are the counts the request is billed on: the usage reported for the generation, or Quotaflow's estimate where that request is billed on an estimate. total_tokens is always input_tokens + output_tokens.
gpt-image-2 request contract
For gpt-image-2, size accepts arbitrary WIDTHxHEIGHT strings when both dimensions are divisible by 16, the aspect ratio is between 1:3 and 3:1, and neither edge exceeds 3840, with 655,360 to 8,294,400 total pixels. background=transparent requires output_format=png or webp; partial_images returns HTTP 400 because streaming is unavailable. background, moderation, and output_compression are forwarded to the upstream Images API when supplied.
Gemini image model request contract
For Gemini image models such as gemini-3.1-flash-image-preview, a request accepts exactly model, prompt, n, size, quality, response_format and user, plus the edit images below.
size:auto,1024x1024,1024x1536or1536x1024.autoor an omitted size means1024x1024.quality:autoorstandard; both meanstandard.n: 1 to 4.response_format:b64_jsononly. URL output is not available for these models.useris accepted for compatibility but is not forwarded upstream.- Any other field, for example
aspect_ratio,image_config,background,output_format,maskorstream, returns HTTP 400invalid_request_errorwith that field inparam.
POST /images/edits takes 1 to 14 reference images, 20 MB in total, as PNG, JPEG, WebP, HEIC or HEIF, in either OpenAI edit shape:
- multipart: one or more
imageorimage[]file parts, with the text fields above; - JSON:
"images": [{"image_url": "data:image/png;base64,..."}].
Remote image URLs are not fetched and images[].file_id is not supported; send each image inline. Reference images are included in the per-image price.
curl https://api.quotaflow.ai/openai/v1/images/edits \
-H "Authorization: Bearer $QUOTAFLOW_API_KEY" \
-F model=gemini-3.1-flash-image-preview \
-F prompt="Place this product on a marble counter." \
-F "image[]=@product.png"
Gemini image models on the native generateContent endpoint
Gemini image models can also be called with Google's native request and response shape:
POST https://api.quotaflow.ai/v1beta/models/{model}:generateContent
A native request is served by the same image product, supplies and per-image price as /images/generations and /images/edits. It accepts:
contents: exactly one user turn (roleuseror omitted). Itspartsaretextparts, joined in order into the prompt, and optionalinlineDatareference images (mimeTypeand base64data) with the same limits as/images/edits: 1 to 14 images, 20 MB in total, PNG, JPEG, WebP, HEIC or HEIF.generationConfig.responseModalities: must includeIMAGE.["TEXT", "IMAGE"]is accepted; the answer carries the image.generationConfig.imageConfig: omitted, oraspectRatio1:1withimageSizeomitted or1K. The output is 1024x1024. Other aspect ratios and sizes return HTTP 400 saying they are not available yet; they open once they are measured. An omittedaspectRatiomeans 1:1 here, including when a reference image is sent.generationConfig.candidateCount: omitted or1. Google's own endpoint refuses multiple candidates for these models.generationConfig.thinkingConfig:thinkingLevel,includeThoughtsandthinkingBudget, forwarded to Google exactly as sent. The Gemini 3 image models are thinking models; the level changes latency and quality, not the per-image price. A request that sets any of these members is served only by supplies on Google's nativegenerateContentwire, never with the member dropped. Any other member ofthinkingConfigreturns HTTP 400 naming it. Google returns no thought parts for image models even withincludeThoughts; the response shape below is unchanged.- Google's snake_case spellings (
inline_data,mime_type,generation_config,response_modalities,image_config,thinking_config, ...) are accepted, as Google accepts them.
Every other field — for example safetySettings, systemInstruction, tools, fileData, a model turn or generationConfig.temperature — returns HTTP 400 with status INVALID_ARGUMENT and a message naming the field. :streamGenerateContent is not available for image models and returns HTTP 400; call :generateContent.
The response is Google's native shape: one candidate whose content.parts[0].inlineData carries mimeType and base64 data, with finishReason STOP, plus usageMetadata with candidatesTokenCount, totalTokenCount and candidatesTokensDetails (modality IMAGE). Those are Quotaflow's own metered output token count, the same one used for billing; promptTokenCount is omitted for the same reason input_tokens is. Errors use Google's {"error": {"code", "message", "status"}} envelope.
curl "https://api.quotaflow.ai/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
-H "x-goog-api-key: $QUOTAFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"role": "user", "parts": [
{"text": "Place this product on a marble counter."},
{"inlineData": {"mimeType": "image/png", "data": "<base64 PNG>"}}
]}],
"generationConfig": {"responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"}}
}'
Not supported / differences from OpenAI
- Streaming (
streamandpartial_images) is unavailable; requests using it are rejected. - OpenAI Files API references (
images[].file_idandmask.file_id) are rejected because they are bound to one OpenAI account and a router cannot resolve them. useris accepted for compatibility but is not forwarded upstream.styleis forwarded verbatim and the upstream decides whether it is supported.response_format=urlis a Quotaflow extension. It returns a hosted URL with the TTL implemented by the selected output host; download it promptly because the router does not promise OpenAI's URL lifetime.- For
gpt-image-2, omittedqualitydefaults tomedium;size=autois sent upstream as1024x1024. - The current endpoint is synchronous only;
asyncsubmission is rejected.
GPT Image 2.5
gpt-image-2.5-flare and gpt-image-2.5-sunburst (also available under their openai/ names) use /images/generations and /images/edits, without Responses API support. Quality accepts low, medium, high, xhigh, max, and auto, defaulting to auto; unknown values return 400 naming quality. The shared custom size rule requires multiples of 16, no edge above 3840, aspect ratio 1:3 to 3:1, and 655,360–8,294,400 total pixels. Billing uses reported usage without GPT Image 2 estimates. Both models cost $5 text input, $1.25 cached text input, $8 image input, $2 cached image input, and $30 image output per million tokens. See GPT Image 2.5. The omitted-quality medium default above applies only to gpt-image-2.