Flex Mode

Cheaper processing, same endpoint, same shape

Add one field to your normal POST /v1/chat/completions call — service_tier: "flex" — and get a real discount in exchange for a slower response, on the exact same endpoint, same request, same response shape you already use. No file to upload, no job id, no second endpoint to learn — this matches how OpenAI's and Gemini's own service_tier=flex work, and how OpenRouter exposes it too, so an existing integration that already sets service_tier works against us unchanged.

Need to pool for longer than flex can reach — up to 1 or 6 hours — for deeper savings? See Async Jobs, a dedicated POST /v1/jobs endpoint with poll-or-webhook delivery.

How it works

service_tier: "flex" is a normal, blocking call — we route it to whichever candidate model would normally serve it, and when that candidate is OpenAI or Gemini (AI-Studio or Vertex), we forward a real service_tier=flex upstream and bill you the discounted price those providers actually charge us — not a synthetic markdown. We hold the connection open up to 15 minutes for it (sized to what OpenAI and Gemini's own flex tiers themselves target — OpenAI recommends a 15-minute client timeout, Gemini's stated latency target is 1–15 min). If the model you're calling has no native flex tier, the request still serves — just at the standard price — rather than failing.

Need longer than 15 minutes? Async Jobs (POST /v1/jobs) has no synchronous provider equivalent to be wire-compatible with, so it's a background job instead — pooling for up to 1 or 6 hours, delivered by poll or webhook.

Using the API

Base URL https://api.llmrouter.sh/v1, Bearer key llmr_sk_live_….

"flex" — one call, blocking

Exactly your normal /v1/chat/completions body, plus service_tier: "flex". The call blocks — same as any request without it — and returns a normal 200 with a chat.completion body once the model responds. The response's own service_tier field reports which tier actually served: "flex" when the discount applied, "default" when the resolved model had no native flex tier to use. Give it a long client-side timeout — up to 15 minutes.

python
import requests

response = requests.post(
    "https://api.llmrouter.sh/v1/chat/completions",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json={
        "model": "openai/gpt-5",
        "service_tier": "flex",
        "messages": [{"role": "user", "content": "What is the meaning of life?"}],
    },
    timeout=900,
)
data = response.json()
print(data["choices"][0]["message"]["content"])
print("Served by tier:", data.get("service_tier"))
# → "flex" if a real discount applied, "default" if this model has no native flex tier

Need to submit and come back later instead of blocking? See Async JobsPOST /v1/jobs, delivered by poll or webhook.

Choosing a tier

service_tier: "flex" matches OpenAI's, Gemini's, and OpenRouter's own parameter — a blocking call, real ~50% off when the model has a native flex tier. Need to wait longer than 15 minutes for deeper pooled savings, or submit more than a handful of requests at once? See Async Jobs (single requests, 1h/6h, poll or webhook) and the file-based Batch API (bulk, up to 24h, up to 50,000 requests).

service_tier Window Delivery Price
unset (default) seconds synchronous — normal 200, instant response standard + 1%
"flex" ≤ 15 min synchronous — normal 200, same call blocks longer OpenAI / Gemini flex ~50% off; else standard

"flex"'s window is 15 minutes, not 10 — sized to what OpenAI (recommends a 15-min client timeout) and Gemini (target latency "1-15 min") themselves need. Promising less than the provider's own commitment isn't an SLA we could keep. Longer windows (1h/6h/24h) live on Async Jobs and the Batch API.

Which models support flex

This is decided by OpenAI and Google, not by us, and it changes as they add models — neither publishes it as a queryable API field. We track it directly against each provider's own published list below, and on top of that we detect it live, per model, from the provider's own response — so a model that isn't on this list yet (a new release, say) still gets tried automatically, and a model that turns out not to support it still succeeds at the standard price rather than failing. You never have to hardcode this list in your own integration to use service_tier: "flex" safely.

OpenAI (developers.openai.com/api/docs/pricing)

o4-mini o4-mini-deep-research o3-deep-research gpt-chat-latest
gpt-5.3-codex gpt-5.4 gpt-5.4-mini gpt-5.4-nano
gpt-5.4-pro gpt-5.5 gpt-5.5-pro gpt-5.6-sol
gpt-5.6-sol-pro gpt-5.6-terra gpt-5.6-terra-pro gpt-5.6-luna
gpt-5.6-luna-pro

Notably not on this list: the classic GPT-4o family (gpt-4o, gpt-4o-mini) and the plain gpt-5/gpt-5.1/gpt-5.2 releases — call them with service_tier: "flex" anyway and you'll still get a normal 200, just at standard price (service_tier:"default" in the response).

Gemini (ai.google.dev/gemini-api/docs/flex-inference)

gemini-2.5-flash gemini-2.5-flash-lite gemini-2.5-pro gemini-3-flash-preview
gemini-3.1-flash-lite gemini-3.1-pro-preview gemini-3.5-flash

Available on both the AI-Studio and Vertex transports. Gemma models share Gemini's google provider tag but are a separate model family and not on Gemini's flex-inference list.

These lists are checked against each provider's published docs and kept current in our routing config, not hand-typed into this page — see the model directory or call GET /v1/models for the full, live, routable model catalog and current pricing.

Errors

  • 400 unsupported_service_tier — anything other than unset, "auto"/"default"/"standard"/"flex".
  • 400 flex_streaming_unsupportedstream: true with service_tier: "flex".
  • 429/503 with error.code: "resource_unavailable" — the upstream provider's flex capacity is exhausted (OpenAI's own shape for this). Never billed — retry with backoff, or drop service_tier and resend.
  • 402 insufficient_credits — the same balance check every synchronous request does; "flex" never enqueues anything, so there's nothing to release on failure.

Async Jobs has its own error list — unsupported_completion_window, invalid_webhook_url, job_not_found — since it's a separate endpoint, not a service_tier value.

Pricing

Billed exactly like every other request — the model's per-token price × whatever discount the tier actually earned, plus the flat 1% platform fee. We never advertise a discount we haven't bought: on "flex", models served through OpenAI or Gemini (AI-Studio or Vertex) get that provider's own real service_tier=flex discount forwarded straight through and billed at the discounted price they actually charge us — reported back to you in the response's own service_tier field. Everything else runs at the standard price — "flex" still serves the request rather than failing, just without a price cut. The same OpenAI/Gemini discount applies on Async Jobs' longer windows too.