Skip to main content
Several providers serve the same open-weight models. DeepSeek V4 Pro runs on seven of them; prices differ by multiples, and availability moves around during the day. Provider routing lets you ask for the model and leave the choice of provider to the gateway. Routing is opt-in. Requests that pin a provider, or that send no provider header at all, behave exactly as they always have.

Opting in

Two things are required: the routing sentinel in X-Majordomo-Provider, and a routable model slug.
majordomo is not a provider. It is the signal that you want the gateway to choose one.
Routing applies to the OpenAI-compatible surface (/v1/chat/completions and friends). Requests on the Anthropic or Gemini surfaces are passed through unchanged. If a live model experiment matches the request, the experiment wins and routing is skipped for that call, so the two never both rewrite the same request.

Routable models

Each provider names these models differently. You send the slug; the gateway rewrites it to whatever the chosen provider calls it, and the response header tells you which one served you. Asking for a model that is not in this list while X-Majordomo-Provider: majordomo is set returns 400. There is no silent fallback, because guessing a provider for an unknown slug would send your request somewhere you did not choose.

How an endpoint is chosen

Constraints first, cost second. The gateway narrows the candidate list in three passes, then optimizes across whatever survives.
  1. Credential. Drop any provider the request cannot authenticate against. Which credentials count depends on the API key’s credential mode, below.
  2. Data policy. Drop any provider that fails the request’s data-handling requirements. This fails closed: a provider with no explicit zero-retention guarantee never satisfies a request that requires one. See data policy headers.
  3. Health. Drop any provider whose recent error rate is elevated. A provider needs enough recent traffic before its error rate is trusted, so a new or quiet endpoint is not penalized for having no history.
  4. Cost. Among the survivors, cheaper endpoints are weighted proportionally more heavily, so traffic concentrates on the cheapest without pinning entirely to one provider.
If every eligible provider fails the health check, the gateway serves the cheapest one anyway rather than failing the request, and records that it did so in routing_reason. A degraded provider beats a hard error.

Credential modes

Routing has to authenticate against whichever provider it picks, which raises the question of whose credentials it may spend. Each Majordomo API key answers that with a credential mode, set when you create the key and changeable later. Two things worth being precise about, because both are easy to assume wrongly: The mode only affects routed requests. A request that pins a concrete provider always uses the Authorization header you sent. Credential mode never changes what happens to your existing traffic. prefer_own resolves per provider, then still routes on cost. It does not restrict the request to providers you happen to hold keys for. If you have a Together key and we have a Fireworks key, both are candidates, and the cheaper healthy one wins. Where both you and Majordomo hold a key for the same provider, yours is used.
byok is the default for every key, including keys created before credential modes existed. Nothing starts spending Majordomo’s credentials unless you change the mode.
Set the mode in the API Keys section of the dashboard. See API Keys.

Reading the result

Every routed response carries three headers describing what happened:
X-Majordomo-Credential-Source is own when your provider key paid and platform when Majordomo’s did. The same information is stored on the request log as routed_provider, routing_original_model, routing_reason, and credential_source, so you can group historical spend by provider or by which side paid. See the schema reference.

Errors

A 502 on a byok key usually means you have not stored a provider key for any provider that serves the model. Storing one, or switching the key to prefer_own, resolves it.