Skip to content

Guides

Routing

Every request goes through two layers: model selection (which model runs) and provider selection (which endpoint serves it, with automatic failover). You can hand both to unoblox, or constrain them precisely per request.

Automatic model selection

Send a router alias as the model and unoblox picks a concrete model — from the set your key can use — that can satisfy the request's capabilities (tools, vision, reasoning, context length):

AliasOptimizes for
unoblox/autoBest value: the highest quality-per-rupee model that can serve the request.
unoblox/paretoThe cost/quality frontier — the balanced "knee", avoiding dominated models.
unoblox/freeLowest cost, preferring genuinely zero-priced models first.
request
{
  "model": "unoblox/auto",
  "messages": [{ "role": "user", "content": "Summarize this ticket." }]
}

The choice is reported back on response headers so you can log and audit it:

HeaderMeaning
x-unoblox-selected-modelThe concrete slug that was chosen.
x-unoblox-selectorWhich selector made the pick (e.g. the router alias).
x-unoblox-selection-reasonA short human-readable reason for the choice.
x-unoblox-variant-notePresent when a variant degraded (see Models).

unoblox/fusion is reserved for a future multi-model strategy and currently behaves like unoblox/auto. Adding the :exacto variant to unoblox/auto flips it to quality-first.

Multi-model failover

Supply a models array to define an ordered fallback chain. unoblox tries the primary model first, then each entry in models in turn (duplicates and per-entry variant suffixes are dropped), walking the chain once:

request
{
  "model": "<model-id>",
  "models": ["<model-id>", "<model-id>"],
  "messages": [{ "role": "user", "content": "Summarize this ticket." }]
}

The chain advances to the next model when the current one cannot be served — no eligible endpoints, a 404, a policy block, or all of its endpoints failing. It stops immediately (no further fallback) on a fatal condition: an unsupported capability, a hard backend error, or a fail-closed BYOK credential. If the whole chain is exhausted, the last routing error is returned.

Provider failover

Within a single model, unoblox load-balances across the providers that serve it and fails over automatically. An attempt moves to the next endpoint on a 429, any 5xx, a timeout, or a transport error. A non-429 4xx is a client error and is returned to you as-is (no failover) — fix the request rather than retry.

Failover is bounded and billed once.

The token reserve is held once per request; only the endpoint that actually produces the completion is settled — the failover walk itself never charges you more than once. This is unrelated to Idempotency-Key, which identifies the request for client-side retry detection, not provider-side failover — see Rate limits & idempotency.

Provider preferences

The optional provider object constrains which endpoints are eligible and in what order. Provider slugs are the ones listed at /providers — a slug that matches nothing is refused (400) when combined with allow_fallbacks: false, as below:

request
{
  "model": "<model-id>",
  "messages": [{ "role": "user", "content": "Summarize this ticket." }],
  "provider": {
    "order": ["<provider-slug>"],
    "allow_fallbacks": false,
    "sort": "throughput",
    "require_parameters": true,
    "data_collection": "deny"
  }
}
FieldTypeEffect
orderstring[]Prefer these providers first, in this order. Bypasses session affinity.
only / allowstring[]Allowlist — restrict routing to these providers.
ignorestring[]Denylist — never route to these providers.
allow_fallbacksbooleanfalse = strict pin: never route outside the allowed set.
sortstring | objectOrder eligible providers (see below).
require_parametersbooleanOnly providers that support every parameter you sent.
data_collection"deny"Exclude providers that retain or train on request data.
zdrbooleanRequire zero-data-retention endpoints.
regionstringRestrict to endpoints in a region.
quantizationsstring[]Restrict to endpoints of these quantizations.
max_pricenumber | objectExclude endpoints above this price ceiling.

Sorting

provider.sort takes a string — price, throughput or latency — or the object form { "by": "price" } with by as the only key. { "by": "price", "partition": "…" } is rejected with a 400 — partitioned routing is not available. The value exacto is also accepted and sets the accuracy posture (equivalent to the :exacto variant) rather than a sort order.

Requiring full parameter support

require_parameters: true (or the :exacto variant, or sort: "exacto") narrows candidates to endpoints that implement every parameter in your request — useful when you depend on tools, response_format or a large context and cannot tolerate an endpoint silently ignoring one.

Fitting long prompts (middle-out)

Set transforms: ["middle-out"] to have unoblox compress an over-long prompt to fit the model's context window. It keeps the head (system messages and the first turn) and the tail (the most recent message), drops middle messages until the prompt fits, and inserts a single notice where content was removed. It is a no-op when the prompt already fits.

request
{
  "model": "<model-id>",
  "messages": [ /* a very long conversation */ ],
  "transforms": ["middle-out"]
}

Presets

A preset is a saved, named request configuration — a default model, a system prompt, and default parameters — stored on your workspace and referenced as @preset/slug in the model field (or as a top-level preset field). Your request's own model and parameters take precedence; the preset fills in whatever you omit. An applied preset is echoed on the x-unoblox-preset header.

request
{
  "model": "@preset/support-bot",
  "messages": [{ "role": "user", "content": "Where is my order?" }]
}

Pinning trades caching for control.

Deterministic response caching applies only to unconstrained requests. Pinning a provider (order, only, or a strict pin) makes a request non-cacheable, as do sampling knobs and tool use. See Pricing & credits for how caching is billed.