Images
Generate and edit images with OpenAI, Gemini, Together, xAI and OpenRouter models through one API.
The gateway serves OpenAI’s Images API. Call /v1/images/generations to draw an image from a prompt, or /v1/images/edits to change one you upload. The model routes to any provider that draws images, on your own key or Respan’s credits, and each call is logged with its cost.
Pick a model: filter by output type image on the model catalog , or read Models for how model ids work.
Quickstart
curl https://gateway.respan.ai/v1/images/generations \
-H "Authorization: Bearer $RESPAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-1",
"prompt": "A lighthouse at dusk, watercolor",
"size": "1024x1024"
}'Options
| Parameter | Type | Default | Description |
|---|---|---|---|
model | string | required | The image model, such as gpt-image-1. |
prompt | string | required | What to draw, or what to change in an edit. |
n | integer | 1 | How many images to make. |
size | string | provider default | Image size, such as 1024x1024. |
image | file | none | Edits only: the image to change, sent as multipart form data. |
mask | file | none | Edits only: the area to change. Not taken by Gemini. |
Other OpenAI Images fields pass through when the target provider takes them.
Edit an image
result = client.images.edit(
model="gpt-image-1",
image=open("lighthouse.png", "rb"),
prompt="Add a full moon above the lighthouse",
)Edits are multipart, so put Respan parameters in the X-Data-Respan-Params header (see Respan parameters).
Sizes
OpenAI, Together and xAI take size as is. Gemini draws only certain aspect ratios, so a size is mapped to the nearest one within 5%, or refused with 400.
Output
The response follows OpenAI’s Images shape. Each image in data comes back as b64_json or as a url, depending on what the provider returns.
Providers
| Provider | Generations | Edits |
|---|---|---|
| OpenAI | Yes | Yes |
| Gemini | Yes | Yes, without masks |
| Together | Yes | Yes |
| xAI | Yes | Yes |
| OpenRouter | Yes | Yes |
Respan parameters
Respan parameters work here as on chat: customer_identifier, metadata, thread_identifier, disable_log and the rest. Put them in the JSON body (or extra_body in the OpenAI SDK) for generations, and in the X-Data-Respan-Params header (base64 JSON) for multipart edits. See Respan parameters.
Image requests are not redacted, so an organization with PII redaction on is refused.
Pricing and logs
- Each call is one trace with one
imagerow. The row keeps each image as a URL: the provider’s, or adata:URL of its bytes. An edit’s input image bytes are not kept. - The row is priced from the provider’s usage: image output at the model’s image output rate, and an edit’s input images at its image input rate where the catalog states one. OpenRouter and xAI report their own charge, which is used as is.
- Before a call on Respan’s credits is sent, the gateway holds credits for the prompt plus 8,192 output tokens per image at the model’s image rate.
- On Respan’s credits, a model with no catalog price whose provider reports no cost is refused with
400. A model priced at $0 is served free. - An answer on Respan’s credits that reports no billable usage is refused with
502 no_billable_usageand charged nothing. - A non-streamed image call runs to its end even if your client disconnects, so it is charged its reported usage.
- Image calls pass the same checks as chat (limit policies, RPM, key usage cap, customer budgets), with no TPM limit and no customer rate limit. See Budgets and limits.
Next steps
- Vision and files: send images to chat models instead.
- Video: generate video.
- Logs: find each image row and its cost.
- Pricing: how media is priced.