Routing and failover

How ACOG chooses the connection that serves a request, when it spreads load and fails over, and how to pin a request to one platform.

3 min read Updated View as Markdown Report a problem

ACOG routes by model. The model in a request selects the connections that declared it; you never choose a provider in the request body.

Which connection serves a request

  1. No connection declares the model. The request is refused with 409 model_not_configured. Declare the model on a connection under Admin → Providers.
  2. Your default connection declares the model. The default connection serves it, and only the default connection: there is no spreading and no failover to other connections. If the default answers 429 or 5xx, that is the answer you get. While its circuit breaker is open (see below) you get 503 upstream_unavailable with Retry-After: 5.
  3. Other connections declare the model. ACOG spreads requests across them and fails over between them. When it must order them, it prefers direct, then bedrock, vertex, azure and custom.

Model ids match loosely on version: a request for claude-haiku-4-5 reaches a connection that declared claude-haiku-4-5@20251001 and the other way round, and is sent with the id the connection declared. A match never crosses model families or major versions.

Failover

For a model that is not pinned to the default connection, ACOG retries on another connection that declares the same model when the first attempt:

  • fails with a 5xx or a network error,
  • is rate-limited with 429 (retried only on a different connection), or
  • is refused before sending because its settings are no longer allowed (connection_not_usable).

A request gets up to three attempts in total, with a short randomized backoff between them. Errors that are about the request itself (400, 401, 403, 404, 422) are returned at once.

Circuit breaker

After five consecutive failures on a platform, ACOG stops sending to it for 30 seconds and then lets one request through to test it. While the breaker is open, requests that cannot go elsewhere receive 503 upstream_unavailable with Retry-After: 5.

What can move a request off the default connection

Four things can send a model your default connection declares to another connection, which then spreads and fails over normally:

CauseWhen
Cost arbitrageYou turned it on, and another platform serves the same model for less
The x-acog-channel headerThe request pins a platform (below)
A DLP route restrictionA rule allows the request only on certain platforms
The policy-block fallbackThe provider’s safety system refused the request (below)

Pin a request to one platform: x-acog-channel

When the same model is declared on several platforms (Claude on Anthropic, Bedrock and Vertex, say), send x-acog-channel to choose one:

curl -s https://gateway.acog.tessarac.com/v1/messages \
  -H "Authorization: Bearer $ACOG_API_KEY" \
  -H "x-acog-channel: vertex" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model": "claude-sonnet-4-5", "max_tokens": 256, "messages": [{"role": "user", "content": "Hello"}]}'

Values are direct, bedrock, vertex, azure and custom. The pin overrides everything else, including cost arbitrage. An unknown value, or a platform with no connection that declares the model, is refused with 409 model_not_configured.

Policy-block fallback

Occasionally a provider’s safety classifier refuses a harmless request with an empty answer and stop_reason: "refusal". When that happens, ACOG sends the request once more to a fallback model (by default claude-opus-4-8) on the same connection, adds a short routing note to the answer saying so, and sets the response header x-acog-policy-fallback:

ValueMeaning
appliedThe fallback model answered
skippedThe request was already for the fallback model, so there was nothing to fall back to
unavailableNo fallback answer: the request opted out, the fallback was not allowed (by model access rules, say), or the fallback model also declined or failed. You get the original refusal.

The header is present only when a refusal was seen. To opt out for a request, send x-acog-policy-fallback: off.

Which model answered

Unified routes set x-acog-resolved-model to the model that was actually sent, which differs from the request when you asked for auto or a version alias. See Response headers.