APIs
Image generation
AI Gateway exposes the OpenAI /v1/images/* endpoints verbatim. Two operations are supported — generate from a prompt and edit an existing image (optionally with a mask). Every call is logged as a generation in the dashboard with the same trace metadata you set on chat endpoints.
Endpoints at a glance
Two endpoints, two body shapes. Generation is JSON; edits require multipart/form-data because they accept files.
| Field | Type | Description |
|---|---|---|
| POST /v1/images/generations | JSON | Generate one or more images from a text prompt. |
| POST /v1/images/edits | multipart/form-data | Edit a base image (optionally guided by a mask) from a text prompt. White pixels in the mask mark the region the model is allowed to repaint. |
Generate an image
Drop-in compatible with the OpenAI SDK. The same metadata fields described in Monitoring & traces (trace_id, trace_name, generation_name, session_id, session_name) are accepted here.
import { client } from "./client";
const result = await client.images.generate({
model: "dall-e-3",
prompt:
"A flat-design illustration of Charon ferrying a small AI robot across a misty river.",
n: 1,
size: "1024x1024",
quality: "hd",
style: "vivid",
response_format: "b64_json",
});
console.log(result.data[0].b64_json?.slice(0, 32), "…");Plain HTTP equivalent
curl https://<your-caronte>/v1/images/generations \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dall-e-3",
"prompt": "A flat-design illustration of Charon ferrying a small AI robot across a misty river.",
"n": 1,
"size": "1024x1024",
"quality": "hd",
"style": "vivid",
"response_format": "b64_json"
}'Request fields
| Field | Type | Description |
|---|---|---|
| modelrequired | string | Image model id (e.g. dall-e-3, dall-e-2, gpt-image-1). Must be allowed on the API key. |
| promptrequired | string | Text description of the image. |
| n | integer | 1–10. Defaults to 1. dall-e-3 only accepts 1. |
| size | string | WIDTHxHEIGHT or auto. Accepted values depend on the model — see Sizes & aspect ratios. |
| quality | string | standard, hd for dall-e-3; high, medium, low, auto for GPT Image models. |
| style | "vivid" | "natural" | dall-e-3 only. |
| background | "transparent" | "opaque" | "auto" | GPT Image models (gpt-image-*) only. |
| output_format | "png" | "jpeg" | "webp" | GPT Image models only. |
| output_compression | integer | 0–100, GPT Image models with webp/jpeg. |
| moderation | "low" | "auto" | GPT Image models only. |
| response_format | "url" | "b64_json" | Defaults to url. Use b64_json when the URL host isn't reachable from the client. |
| seed | integer | null | Generation seed — Gemini only, not forwarded to OpenAI. |
| user | string | Stable end-user identifier. Required when the API key has force_user: true. |
| metadata | object | Trace metadata (trace_id, trace_name, generation_name, session_id, session_name). |
Response shape
{
"created": 1716651200,
"data": [
{
"url": "https://...",
"b64_json": null,
"revised_prompt": "A flat-design illustration… (model-rewritten prompt)"
}
],
"usage": {
"input_tokens": 42,
"output_tokens": 0,
"total_tokens": 42
}
}Edit an image
Multipart form-data — send the image (and optionally a mask) as a file part. White pixels in the mask mark the region the model is allowed to repaint.
import fs from "node:fs";
import { client } from "./client";
const result = await client.images.edit({
model: "gpt-image-1",
image: fs.createReadStream("./room.png") as never,
mask: fs.createReadStream("./room-mask.png") as never,
prompt: "Replace the sofa with a modern dark-green velvet one.",
size: "1024x1024",
response_format: "b64_json",
});
console.log(result.data[0].b64_json?.slice(0, 32), "…");curl https://<your-caronte>/v1/images/edits \
-H "Authorization: Bearer $API_KEY" \
-F model="gpt-image-1" \
-F prompt="Replace the sofa with a modern dark-green velvet one." \
-F size="1024x1024" \
-F response_format="b64_json" \
-F image=@room.png \
-F mask=@room-mask.pngForm fields beyond image, mask, prompt, model
| Field | Type | Description |
|---|---|---|
| n | integer | 1–10. |
| size | string | WIDTHxHEIGHT or auto. Accepted values depend on the model — see Sizes & aspect ratios. |
| quality | string | high, medium, low, standard, auto — GPT Image models (gpt-image-*) only (except standard, the dall-e-2 value). |
| background | "transparent" | "opaque" | "auto" | GPT Image models only. |
| input_fidelity | "high" | "low" | GPT Image models only. |
| output_format | "png" | "jpeg" | "webp" | GPT Image models only. |
| output_compression | integer | 0–100, only for GPT Image models with webp/jpeg. |
| response_format | "url" | "b64_json" | url for dall-e-2, b64_json for gpt-image-1. |
| user | string | Stable end-user identifier. |
On OpenAI models every field of both endpoints is forwarded verbatim, except metadata (Caronte tracing) and seed (Gemini only): parameters OpenAI adds work without a gateway update, and an invalid value comes back as OpenAI's own 400. stream is not supported and is rejected with a 400.
Sizes & aspect ratios
size is the only field that controls the output format, and both endpoints accept the same values. How it is applied depends on the provider behind the model.
OpenAI models
size is forwarded verbatim and OpenAI validates it — e.g. dall-e-3 takes 1024x1024, 1792x1024, 1024x1792; gpt-image-1 takes 1024x1024, 1536x1024, 1024x1536, auto. A value the model does not support comes back as OpenAI's own 400.
Gemini models
Gemini takes an aspect ratio and a resolution tier, not a pixel size. The gateway converts the proportions of WIDTHxHEIGHT to the nearest of the ratios below, so any size with the right proportions works — the OpenAI sizes too (1536x1024 → 3:2, 1792x1024 → 16:9).
| Aspect ratio | Example size (1K) | Availability |
|---|---|---|
| 1:1 | 1024x1024 | All Gemini image models |
| 2:3 / 3:2 | 848x1264 / 1264x848 | All Gemini image models |
| 3:4 / 4:3 | 896x1200 / 1200x896 | All Gemini image models |
| 4:5 / 5:4 | 928x1152 / 1152x928 | All Gemini image models |
| 9:16 / 16:9 | 768x1376 / 1376x768 | All Gemini image models |
| 21:9 | 1584x672 | All Gemini image models |
| 1:4 / 4:1 | 512x2048 / 2048x512 | Gemini 3.1 Flash Image family only |
| 1:8 / 8:1 | 384x3072 / 3072x384 | Gemini 3.1 Flash Image family only |
- The gateway does not check which ratios a model supports: a model that lacks one (e.g.
1:4on Gemini 2.5 Flash Image or Gemini 3 Pro Image) answers with a 400. - The resolution tier follows the pixel count of
size: under 2 megapixels is 1K (the model default), 2–8 megapixels is 2K, above is 4K — e.g.2048x2048or2752x1536→ 2K,4096x4096→ 4K. Higher tiers cost more output tokens. Models limited to 1K (e.g. Gemini 3.1 Flash-Lite Image) reject 2K and 4K with a 400; the gateway appends thesizeand the tier it was sent as to the error message. - With
autoor nosize, generations use the model's default ratio and edits follow the input image. - A
sizethat is notWIDTHxHEIGHTorauto(e.g.16:9) is rejected with a 400 onparam: "size". - Gemini-native fields such as
aspect_ratioorimage_sizein the body are ignored.
Notes & limits
A few practical considerations when wiring image endpoints into your app.
- The API key must have access to the image model — same allow-list rules as text models.
- Budgets and request caps apply to image endpoints exactly like to chat endpoints. PII masking does not cover image endpoints — the
promptis forwarded as-is even when a key has masking enabled (masking is limited to non-streaming chat & responses). - For very large
b64_jsonpayloads preferresponse_format: "url"to avoid base64-bloating client memory. - Uploaded image files (and masks) must be under 50 MiB — the same hard cap that applies to
/v1/filesuploads.
note · Image generation via Code Interpreter
matplotlib or Pillow from the sandboxed caronte:code_execution tool — outputs land in the response as container_file_citation annotations. Use the image endpoints for model-driven generative imagery and the Code Interpreter for deterministic, data-driven visualisations.