# Image router: routing image generation across providers

URL: https://infro.io/blog/image-model-routing
Author: INFRO Editorial (https://infro.io/blog/editorial)
Publisher: INFRO
Published: 2026-10-19
Last modified: 2026-10-19
Last reviewed: 2026-10-19 (next review due 2026-11-18)
Topic: Agents and multimodal systems
Format: Guide

> An image router sends each image generation request to one of several providers that serve the model, in an order you choose. Because each provider takes different sizes, aspect ratios, quality levels and reference images, a safe router checks every setting against the target before calling it, skips targets that cannot honour it, and never silently changes the output to make a fallback succeed.

Key takeaways:
- One image model is usually served by several providers, and each takes a different set of sizes, aspect ratios, quality levels, reference images and seeds.
- Per-image prices for the same model differ by provider and by resolution, so the route order is also a cost decision.
- Fail over only to targets that can honour every setting in the request. Refuse before the call instead of quietly rendering a different size or quality.
- Providers mix synchronous calls, queues and webhooks. An image router has to hide that difference without hiding a slow render.
- Seeds and content policies are not portable across providers, so a fallback image is a new image, not a copy of the one you would have had.

An **image router** decides which provider serves each image generation request, and what to do when that provider fails. It matters because the same image model is often served by its vendor, by cloud platforms and by hosted inference providers, and each of them accepts different sizes, aspect ratios, quality levels and reference images, at different prices. A good image router fails over between them without changing the image you asked for.

Routing text requests is well understood: an ordered list of providers, a retry policy, failover before the first byte of the answer. Images look similar and are not. This guide covers what makes multi-provider image generation different, how to route around it, and where safe fallback ends.

## Why route image generation at all?

Three reasons show up in production, usually in this order.

- **Availability.** An image feature in a product (thumbnails, avatars, ad variants, product shots) breaks the same way a chat feature does when its one provider is throttled or down. A second provider for the same model keeps it working.
- **Rate limits and throughput.** Image endpoints have their own limits, often lower than text. A batch of a few thousand renders can exhaust one account's allowance; spreading across accounts or providers finishes it.
- **Cost.** The same model can be listed at different per-image rates on different providers, and the difference compounds at volume. The route order decides which rate most of your images are billed at.

What is not on the list is "quality". Routing between providers of the same model should not change quality at all. Routing between different models does, and is covered in [AI image models compared](https://infro.io/blog/ai-image-models-compared-2026).

## One model, many hosts, different settings

Take one model as an example. Google documents its Nano Banana Pro model (`gemini-3-pro-image`) on the Gemini API with output sizes of 1K, 2K and 4K, 1K by default, and up to 14 reference images in total, of which up to 6 can be object references and up to 3 style references[1]. fal hosts the same model with the same three resolutions and lists ten aspect ratios from 21:9 to 9:16[2].

Other models vary more. OpenAI's GPT Image models take an exact `WIDTHxHEIGHT` size whose edges must be multiples of 16, with neither edge above 3840 pixels and the total between 655,360 and 8,294,400 pixels; resolutions above 2560x1440 are labelled experimental[3]. The same guide lists quality levels from `low` to `max`, with `xhigh` and `max` only on the 2.5 models[3]. A hosted provider of the same model may expose the size as a tier, as a ratio, or as a fixed list of pixel sizes.

The settings that differ from host to host fall into a short list:

| Setting | How it varies across providers | What goes wrong if ignored |
| --- | --- | --- |
| Size | Exact pixels, resolution tiers (1K/2K/4K), or a fixed list | The provider rounds to its nearest size, or refuses |
| Aspect ratio | Different sets of supported ratios | A 21:9 banner comes back as 16:9 |
| Quality | Present on some models only, with different levels | A `high` request runs at the provider's default |
| Number of images | Different maximums per call | Fewer images than requested, with no error |
| Reference images | Different counts, roles and upload formats | References dropped or the call refused |
| Edits and masks | Some hosts take a mask, some only a prompt | The whole image is edited instead of one region |
| Seed | Taken by some hosts, ignored or refused by others | No reproducibility, without any signal |

Table: The same model name does not guarantee the same request contract.

## Prices differ per image and per resolution

Image models are billed per image, not per token, and the rate depends on resolution and sometimes quality. For Nano Banana Pro on the Gemini API's standard paid tier, Google lists $0.134 per 1K or 2K image and $0.24 per 4K image[4]. fal lists $0.15 per image for the same model and bills 4K output at twice that rate[2]. Neither is better in general: which is lower depends on your resolution mix, and your own negotiated rates may differ from both list rates.

> **Example: A batch of 10,000 images**
> At the list rates above, 10,000 Nano Banana Pro images at 2K would be about $1,340 on the Gemini API standard tier and $1,500 on fal. The same batch at 4K would be about $2,400 and $3,000. These figures are illustrative arithmetic on one day's list rates, before any negotiated rate, batch tier or failed attempt.

Two consequences for routing. First, the primary target is a cost choice as much as a reliability one, so put the provider whose rate you want on most traffic first. Second, a router that silently upgrades a request to a higher resolution on a fallback target to make it succeed also changes the cost, often by a multiple.

## How should an image router fail over?

For text, a failover target either speaks the same request or is skipped. For images, a target can accept the request and quietly render something different: a nearest supported size, the default quality, fewer images, references ignored. The request "succeeds", and the image is wrong in a way no error code reports.

The rule that prevents this is simple to state: **check every setting against what the target takes before calling it, and skip targets that cannot honour the request.**

1. **Normalize the request** into model-level settings: resolution tier, aspect ratio, quality, number of images, references with their roles, mask, seed.
2. **For each target in order**, compare those settings with that provider's record for that model. A target that cannot take one of them is skipped before any call, with the reason recorded.
3. **Translate** the settings into the provider's own fields: a tier where it takes tiers, a ratio where it takes ratios, pixels where it takes pixels, within its limits.
4. **Call, and fail over on provider failures** (timeouts, rate limits, server errors) to the next target that passed step 2.
5. **When no target can honour the request**, refuse it with a message that names what the model takes on each host, for example "renders at 1K and 2K, not 4K". No provider is called and nothing is billed.

Refusing is the honest outcome. An application asking for a 4K image for print does not want a 1K image that happens to succeed; it wants to know that none of its configured providers can render 4K for that model today.

> **Note: Exact sizes are a special case**
> If an application sends an exact pixel size that only one provider supports, a router cannot fit it to other targets without changing the request. Prefer a resolution tier plus an aspect ratio where your feature allows it: the router can then translate the request for each target instead of passing the same pixels to every provider.

## Synchronous, queued and webhook providers

Providers do not agree on how an image request returns. Replicate's API is asynchronous by default: creating a prediction returns an id at once, a `Prefer: wait` header holds the request open (60 seconds by default), and a webhook can deliver the final result[5]. fal's queue returns a request id with status, result and cancel URLs, and can POST the result to a webhook when it finishes[6]. The Gemini and OpenAI image APIs answer within the HTTP request.

An image router has to present one behaviour to the application. Two workable choices:

- **Synchronous to the caller.** The router waits on queued providers on the caller's behalf and answers when the image is ready. Simple for fast models, but a client timeout can abandon an image the provider still renders and bills.
- **Jobs for slow work.** The router returns a job id and delivers the result by webhook or polling, whatever the provider does underneath. This is the right shape for 4K renders, large batches and video. [Async media jobs and webhooks](https://infro.io/blog/async-media-jobs-webhooks) covers signatures, retries and idempotency.

Either way, provider output URLs often expire. Copy the image to storage you control before handing a link to your users.

## Content policies, watermarks and seeds are not portable

Providers apply their own safety systems to prompts and outputs. OpenAI's image API exposes a `moderation` parameter with `auto` as standard filtering and `low` as less restrictive[3]; other hosts apply the vendor's or their own filtering with no setting at all. A prompt refused by one provider may be accepted by another, which is why a refusal on safety grounds should normally stop the request, not fail over until some provider accepts it.

Provenance marks differ too. Google states that every image generated by its Gemini image models carries a SynthID watermark[1]. If your compliance process depends on a mark like that, a route that falls back to a different model may produce images without it.

Seeds do not travel. A seed reproduces an image only within one provider's implementation of one model, and several providers take no seed at all. Caching image generation therefore means caching outputs: store the bytes against a hash of the normalized request (model, prompt, settings, references) and serve repeats from your storage, rather than hoping a seed reproduces the same image elsewhere.

## A checklist for multi-provider image generation

- [ ] Each route serves one model, or names a second model only where any reasonable image is acceptable.
- [ ] The router holds a per-provider record of sizes, ratios, quality levels, image counts, references and seed support for every model it serves.
- [ ] A setting a target cannot take is refused before the call; the refusal names what the model takes.
- [ ] Failover happens on provider failures, never by quietly lowering resolution or quality.
- [ ] Safety refusals stop the request instead of searching for a provider that accepts it.
- [ ] Cost is estimated per image at the resolution and quality requested, before the call, against your own rates where you have them.
- [ ] Slow renders run as jobs with webhooks, and outputs are copied to your own storage.
- [ ] Each image's record names the provider and account that rendered it and every failed attempt.

The [multimodal AI API guide](https://infro.io/blog/multimodal-ai-api-guide) covers the same concerns for video and audio, where the asynchronous part dominates.

## How INFRO routes image requests

INFRO is a BYOK control plane: you connect your own provider accounts, and `POST /v1/images/generations` and `/v1/images/edits` route over them with the same routes, failover and request log as text. Image requests can be served by connections to OpenAI, Azure OpenAI, Google AI, Google Vertex AI, Together AI, OpenRouter, Runway, KIE, LaoZhang API, fal, Replicate and OpenAI-compatible endpoints, as listed in the [image generation docs](https://infro.io/docs/modalities/images).

INFRO keeps a record of the settings each model takes on each provider, read from that provider's documentation. Before calling a target, the gateway checks `resolution`, `aspect_ratio` and `quality` against that record, and reference images by count and role. A setting the target cannot take is never sent: the next target is tried, and when no target can take it the request is a `400` naming what the model accepts, with no provider called and nothing billed. Settings are then sent in each provider's own form. Provider order comes from the route's targets, or for a request that names a model directly, from the order you connected providers; per-request `fallbacks` can name further image models, tried only after every connection for the first has failed.

```json
{
  "model": "google/nano-banana-pro",
  "prompt": "A product shot of a ceramic mug on a linen tablecloth, morning light",
  "resolution": "2K",
  "aspect_ratio": "4:5",
  "n": 1
}
```

Each response names the provider and connection that rendered the image and carries `usage.cost`, an estimate of what your provider will bill, or `null` when no rate is known. `POST /v1/estimates` prices a request per image at its resolution and quality tier before you send it, and generated images are copied to INFRO storage behind signed links. Your providers bill you for the images; INFRO charges a subscription and takes no share of model spend. For creative teams, [INFRO Studio](https://infro.io/blog/infro-studio-ai-image-video-audio) runs the same routing with a provider order you set per model. The [quickstart](https://infro.io/docs/quickstart) connects a first provider.

## Questions

### Can I fail over from one image model to a different one?

You can, but treat it as a product decision rather than a reliability one. A different model draws differently, renders text differently and may not take the same references, so the fallback image will not match what the primary would have produced. Many teams fail over between providers of the same model first and name a second model only for features where any reasonable image is acceptable.

### Why does the same image model cost different amounts on different providers?

Each provider sets its own per-image rate and its own rule for higher resolutions. A model's vendor, a cloud platform and a hosted inference provider can all list the same model at different prices, and some charge a multiple for 4K output. The provider you route to first is the one that bills you for most of your images.

### Should image generation be synchronous or asynchronous?

Fast models at standard resolution usually finish within an ordinary HTTP request. High resolutions, large batches and slow providers are safer behind a job with a webhook or polling, so a client timeout does not discard an image you are still billed for. Pick per workload, not per provider.

### Does a seed give me the same image on another provider?

No. A seed is only meaningful inside one provider's implementation of one model, and several providers do not accept a seed at all. To reuse an image, store the output itself rather than the parameters that produced it.

## Sources

1. Image generation with Gemini (Nano Banana) — Google AI for Developers. https://ai.google.dev/gemini-api/docs/image-generation (accessed 2026-10-19)
2. Nano Banana Pro — fal. https://fal.ai/models/fal-ai/nano-banana-pro (accessed 2026-10-19)
3. Image generation — OpenAI. https://developers.openai.com/api/docs/guides/image-generation (accessed 2026-10-19)
4. Gemini Developer API pricing — Google AI for Developers. https://ai.google.dev/gemini-api/docs/pricing (accessed 2026-10-19)
5. Create a prediction — Replicate. https://replicate.com/docs/topics/predictions/create-a-prediction (accessed 2026-10-19)
6. Queue — fal. https://fal.ai/docs/model-apis/model-endpoints/queue (accessed 2026-10-19)
