# Model routing > How a model name in a request body resolves to a provider: backends, glob patterns, priority order, and model rewrites. Source: https://docs.stg.perdurance.dev/routing/ --- Perdurance never guesses where a request should go. Two things decide it, and both live in the namespace the request was addressed to. A **backend** is a connection to a provider: an address, a dialect, and your credential for it. A **routing rule** maps model names onto one of those backends. A request whose model matches no rule is refused. That is deliberate — a router that guessed would send your prompt, and your money, somewhere you did not choose. ## Backends | Kind | Dialect it speaks | Typical use | |---|---|---| | `openai_compat` | OpenAI | OpenAI itself, and the many servers that copy its API | | `anthropic` | Anthropic | Anthropic's Messages API | | `openrouter` | OpenAI | OpenRouter, including its Anthropic-family models | The kind fixes the dialect, and the dialect has to match the route the request arrived on. A body sent to `/chat/completions` that a rule resolves to an `anthropic` backend is refused with `422`, and no record is written. Perdurance does not translate between dialects. A translation layer owns a mapping it must keep current with two vendors, and every field it fails to understand is a corrupted upstream call. To reach an Anthropic model from an OpenAI-shaped client, use an `openrouter` or `openai_compat` backend that serves it. A backend is created in a namespace and can be attached to others, so one provider connection — one credential — can serve several namespaces without being pasted twice. ### The credential The provider key you give a backend is encrypted with the deployment's `credential-key` before it is stored, and it is never returned by any route. Not to the console, not to the CLI, not to you. If you lose it, you replace it. ## Routing rules A rule is a **pattern**, a **priority**, a **backend**, and optionally a **model rewrite**. ```json { "priority": 100, "pattern": "gpt-*", "backend_id": "…", "model_rewrite": null } ``` ### Patterns are globs The pattern is a glob matched against the model name in the request body — `*` matches everything, `gpt-*` matches `gpt-4.1` and `gpt-4o-mini`, `claude-*-haiku-*` matches by shape. An invalid glob is refused when the rule is created rather than when a request arrives. ### Priority decides, lowest first Rules are taken in ascending priority order and **the first one that matches wins**. So a narrow rule needs a lower number than the catch-all it should beat: | Priority | Pattern | Backend | |---|---|---| | `10` | `claude-*` | The `anthropic` backend | | `20` | `gpt-*` | The `openai_compat` backend | | `1000` | `*` | Wherever everything else should go | Ties are broken by rule id, which is time-ordered — so two rules at the same priority resolve the same way on every process in the deployment, rather than depending on which one answered. ### Model rewriting `model_rewrite` replaces the model name before the request reaches the provider. The body is otherwise forwarded byte for byte; this is the one field Perdurance changes. It is how one backend answers for several names, and how a name your code uses stops being the name your provider uses: - Pin a moving name. `claude-sonnet-latest` → `claude-sonnet-4-20250514`, so a provider's alias moving under you is a rule you change rather than a deploy. - Give a name to a choice. `our-summariser` → whatever model currently does that job, changed in one place instead of everywhere it is called. - Point staging at something cheaper without touching staging's code. Because the rewrite happens after the body is hashed, two requests that differ only in the rewritten name are still two different requests. See [Idempotency](/idempotency). ## Getting it wrong | Symptom | Cause | |---|---| | `422`, nothing stored | The model matched a rule whose backend speaks the other dialect | | `403` naming a rule | A rule refused the request; the message says which | | Requests reaching the wrong provider | A catch-all at a lower priority than the specific rule you expected to win |