RouterOne

Create image

Last updated September 1, 2026

Generate images over the OpenAI Images-compatible endpoint. The official SDKs work unchanged.

This endpoint is compatible with the OpenAI Images API. The official SDKs work unchanged after pointing base_url here.

The table below lists every request parameter, with its accepted values and any preconditions.

POSThttps://gateway.routerone.ai/v1/images/generations

Authorization

header
AuthorizationstringRequired

Bearer <your RouterOne key> A RouterOne key created in the console. If you lose it, you can view it again on the keys page.

Request

application/json
modelstringRequired

Model ID, optionally suffixed with :provider to pin a provider.

promptstringRequired

The prompt.

nintegerDefault 1

How many images (1-10, default 1). Billed per image, and the reserve scales with it. Must be 1 when streaming.

sizestring

An exact pixel size, or auto (the default).

⚠️ The accepted set differs per model:

- gpt-image-1.5: a closed set — only 1024x1024 /

1536x1024 / 1024x1536 / auto. Any other pixel string is

rejected upstream, including ones that satisfy the four rules

below;

- **gpt-image-2, gpt-image-2.5-flare,

gpt-image-2.5-sunburst**: those three plus 2048x2048,

2048x1152, 3840x2160, 2160x3840, the 4:3 and 3:4 tiers

1024x768 / 768x1024 / 2048x1536 / 1536x2048 /

3264x2448 / 2448x3264, and any pixel string meeting all

four rules — both edges a multiple of 16, long edge at most 3840,

aspect ratio at most 3:1, total pixels between 655,360 and

8,294,400. A 3840-pixel long edge leaves at most 2160 on the

other side, so the widest tier is 16:9 or wider; the largest 4:3

that fits the pixel ceiling is 3264x2448.

Sending a tier the chosen model does not take is rejected upstream.

See that model's own reference for its exact set.

⚠️ Size drives the image token count, and therefore the price.

auto is exempt — read size in the response to see what you got.

This and the Google-style "aspect ratio + resolution tier" are

parallel; when the upstream speaks only the other one we convert and

say so in amux.notes.

aspect_ratiostring

An alternative spelling of size (the Google-ecosystem form), used together with image_size. Send one form or the other; if both are given, size wins. The accepted set differs per model — see the model pages.

⚠️ On the OpenAI models, prefer size. Those upstreams take exact pixel sizes only, so a ratio is folded into one of them; the fold is lossy, and a ratio with no exact match is approximated or dropped, with a note in amux.notes. The xAI image models are the other way round: they take aspect_ratio natively and do not accept size at all.

image_sizestring

Resolution tier, used with aspect_ratio. The accepted set differs per model.

quality"low" | "medium" | "high" | "xhigh" | "max" | "auto"Default "auto"

⚠️ The accepted set differs per model: xhigh and max are accepted only by gpt-image-2.5-flare and gpt-image-2.5-sunburst; sending either to gpt-image-2 or gpt-image-1.5 is rejected upstream. The xAI image models take low / medium / auto only.

Render quality. It drives the image token count and therefore the price — the tiers can differ by an order of magnitude.

background"transparent" | "opaque" | "auto"Default "auto"

A transparent background needs png or webp; jpeg has no alpha channel. Transparency on gpt-image-2 is still a preview capability.

output_format"png" | "jpeg" | "webp"

Output format, png by default.

output_compressionintegerDefault 100

Compression level; only meaningful for jpeg / webp.

moderation"auto" | "low"Default "auto"

Moderation strictness. Generation endpoint only.

userstring

End-user identifier for abuse monitoring. Omit the key entirely if you do not need it.

streambooleanDefault false

Return SSE. Requires n of 1 and at least one provider that streams.

partial_imagesinteger

How many low-resolution previews to send while streaming. 0 (the default) means the completed event only. You may get fewer than you asked for — a fast render goes straight to the completed event.

Response

200response

Success. data and usage match OpenAI; amux is our extension.

400response

Invalid request. Also covers "streaming asked for but no provider streams" and "streaming with n above 1" — both say what to change.

402response

Not enough available balance to cover this request's reserve.

Available = balance − expired lots − already reserved.

503response

No provider available. Two common causes: this model has no image provider

configured, or the size tier you asked for has no price on that provider —

metadata says which.

Supported models

Six: gpt-image-2.5-flare, gpt-image-2.5-sunburst, gpt-image-2, gpt-image-1.5, x-ai/grok-imagine-image-2.0 and x-ai/grok-imagine-image-quality.

⚠️ The parameter panel above is the union for this endpoint, not what any single model actually accepts. Even dimensions are expressed differently: the four OpenAI models take an exact pixel string (size), while the two xAI models take a ratio plus a resolution tier (aspect_ratio + image_size) and do not accept size at all.

The two GPT-Image-2.5 variants share one parameter surface; they differ in latency and output quality, not in what they accept.

gpt-image-2.5 (flare / sunburst)gpt-image-2gpt-image-1.5grok-imagine-image-2.0grok-imagine-image-quality
Dimensionscommon tiers plus any legal pixel string (up to 4K)same1024x1024 / 1536x1024 / 1024x1536 / auto, and nothing elseaspect_ratio + image_size (1K / 2K)same
qualitylow / medium / high / xhigh / max / autolow / medium / high / autosame as gpt-image-2low / medium / autounsupported
input_fidelityunsupportedunsupportedsupported——
Streamingyesyesyesnono
Text output tokensnonenoneyes (internal reasoning, billed at the text output rate)nonenone

⚠️ xhigh and max exist only on GPT-Image-2.5. Sending either to gpt-image-2 or gpt-image-1.5 is rejected upstream. The tiers also do not map one to one across generations: at the same size, 2.5's high costs what 2.0's medium did, and 2.5's max costs what 2.0's high did.

If you only call one of them, its own reference is shorter: gpt-image-2.5-flare · gpt-image-2.5-sunburst · gpt-image-2 · gpt-image-1.5 · grok-imagine-image-2.0 · grok-imagine-image-quality.

Two things that differ from the text endpoints

We store the artifacts. amux.images carries directly usable addresses. They get cleaned up — download anything you need to keep; afterwards the address returns 404.

A reserve is held at submit, then settled against actual usage with the difference released. An insufficient balance fails with 402 up front rather than after the image was made.

Streaming

stream: true returns SSE with the same events OpenAI uses: zero or more image_generation.partial_image, then one image_generation.completed carrying the final image and usage.

Two limits: n must be 1 (nothing in the events says which image a frame belongs to), and only providers that declare streaming take part in routing — when none does you get an explicit error rather than a silent fallback.

Unsupported parameters

response_format (gpt-image always returns base64), style (dall-e only) and seed (no such parameter on the official image endpoints). Sending them gets them dropped, with a note in amux.notes.

⚠️ The image path has no unknown-parameter passthrough (the text path does); fields outside the panel are not forwarded upstream.

Errors

The error shape matches OpenAI. See Errors and retries for the type values and their retry semantics.

cURL
curl https://gateway.routerone.ai/v1/images/generations \
  -H "Authorization: Bearer $ROUTERONE_API_KEY" \
  -d '{
    "model": "openai/gpt-image-2",
    "prompt": "A red fox sitting in snow, photorealistic",
    "size": "1024x1024"
  }'
{
  "created": 1786000000,
  "size": "<string>",
  "quality": "<string>",
  "background": "<string>",
  "output_format": "<string>",
  "data": [
    {
      "b64_json": "<string>",
      "revised_prompt": "<string>"
    }
  ],
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0,
    "total_tokens": 0
  },
  "amux": {
    "task_id": "<string>",
    "generation_id": "<string>",
    "provider": "<string>",
    "cost_nano": "<string>",
    "images": [
      {
        "index": 0,
        "url": "<string>"
      }
    ],
    "notes": [
      "<string>"
    ]
  }
}