skip to content
Routing

Gateway

Routing

One endpoint in front of every model and every provider. The gateway picks the route, fails over when it has to, and tells you what served.

Conifer is one key and one base URL in front of every model in the catalog. Your request arrives on the OpenAI chat wire, the OpenAI Responses wire or the Anthropic Messages wire. The gateway checks the key, works out which provider should serve the model, sends the request there, retries elsewhere if that provider fails, and answers with a receipt that says which model served and what it cost. This page covers each of those in turn.

Named vs routed

A named request carries a catalog id, such as claude-haiku-4-5. That exact model answers, or the request is refused. Nothing cheaper is swapped in behind a 200. An id the catalog does not carry is a 404 model_not_found. A namespaced spelling such as anthropic/claude-opus-5 is accepted and served as claude-opus-5.

A routed request leaves the choice to Conifer. From any client, send auto, balanced or best as the model and Conifer chooses the model for that turn, or send default for its default pin. The router explains the three ids and the receipt they produce. From the CLI, pick a route instead of a model. --route all lets it choose from everything you can reach, and a saved route carries a policy such as balanced or best. Palm does the same for Claude Code, turn by turn.

Either way the receipt tells you what happened. x-conifer-requested-model is the id you sent and x-conifer-effective-model is the model that answered. Pinning a model in a tool, for example claude --model claude-haiku-4-5, is a named request and turns routing off for that tool.

The wire

Use whichever wire your client already speaks. Claude Code speaks Anthropic Messages, Codex speaks Responses, and almost everything else speaks OpenAI chat. All three are on the same host with the same key, so the only decision is the base URL. The OpenAI wires end in /v1 and the Anthropic wire has no suffix. See Replace your provider key for the two-line change.

One rule to know: /v1/messages serves Anthropic models only. Send a non-Anthropic id there and you get a 400 wire_upstream_mismatch. Every model in the catalog is available on the chat wire.

Providers and failover

Many models are served by more than one provider. You do not pick one. The gateway sends each request to the best available provider for that model, and if a provider rate-limits, errors or times out, it retries the same model with another. The price is the catalog price for the model whichever provider served it, and when a retry happened the receipt reason reads provider_failover. If no provider can serve the request, it fails and nothing is charged.

Failover never changes the model unless you ask for that. To name a chain of your own, send x-conifer-fallback-models with up to three catalog ids. They are tried in order after the model you named cannot be served, and whichever one answers is disclosed in x-conifer-effective-model.

terminal
curl https://api.conifer.build/v1/chat/completions \
  -H "Authorization: Bearer $CONIFER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "x-conifer-max-cost-nanousd: 50000000" \
  -H "x-conifer-fallback-models: claude-sonnet-5,gpt-5.4" \
  -d '{
    "model": "claude-haiku-4-5",
    "max_tokens": 512,
    "messages": [{"role": "user", "content": "three names for a build cache"}]
  }' -D -

Headers you can send

Request headerWhat it does
x-conifer-max-cost-nanousdA hard ceiling on what this request may cost, in integer nanodollars ($1 = 1e9). Over the ceiling the request is refused with 402 cost_ceiling_exceeded before any provider is called, and nothing is spent.
x-conifer-fallback-modelsUp to three comma-separated catalog ids to try, in order, if the model you named cannot be served. Chat and Responses wires only.
x-conifer-cacheoff skips the gateway's prompt caching for this one request.
x-conifer-deferallow runs a non-streaming request as a deferred job with a completion window of at least 24 hours. The gateway answers 202 and you fetch the result from /v1/jobs.

The cache

The gateway manages the provider’s prompt cache for you. On Anthropic models it marks the stable part of a conversation for caching once it can see that more turns are coming, so a long system prompt or a tool list is paid for once and read cheaply after that. If your request already carries cache_control markers, they are used as sent. Send x-conifer-cache: off to skip caching on one request.

Cache reads are billed well below the input rate and cache writes a little above it. The exact rates are in the pricing fields of each catalog entry. Cached tokens come back in the body as usage.prompt_tokens_details.cached_tokens on the chat wire and cache_read_input_tokens on the Messages wire, and in the receipt as the cache_read and cache_write parts of the cost.

The receipt

response headers
x-conifer-requested-model: claude-haiku-4-5
x-conifer-effective-model: claude-haiku-4-5
x-conifer-receipt-reason: as_requested
x-conifer-cost-nanousd: 1340000
x-conifer-cost-components-nanousd: fresh=920000,cache_write=0,cache_read=0,output=420000
x-conifer-request-id: req_…
HeaderValue
x-conifer-requested-modelThe id you sent, in your spelling.
x-conifer-effective-modelThe model that answered and was billed. The same as the requested id unless you sent auto, balanced, best or default, or a fallback you named served.
x-conifer-receipt-reasonas_requested, provider_failover when a retry happened, or routed when a Conifer route chose the model.
x-conifer-endpointcredits, or byok:<provider> when your own provider key served the request.
x-conifer-cost-nanousdThe settled cost in nanodollars. Absent on a streamed response, where the cost rides the final usage event instead. Absent means not yet known, never zero.
x-conifer-cost-components-nanousdfresh, cache_write, cache_read and output in nanodollars. The four sum to the cost.
x-conifer-request-idThe request id to quote in a support message. Also sent as x-request-id and request-id.