ultrarouter docs
Guides

Model policy — which models your account may run

Choose US-only or global, then allow or deny by lab, provider, or model — with a US-hosted open-weight exception. Enforced everywhere a model is picked.

Your workspace model policy decides which models ultrarouter may run on your behalf. You pick a preset, then layer allow/deny rules on top. The policy is enforced everywhere a model can be picked — proxy routing and its fallbacks, evaluation and benchmark candidate pools, the recommendations we surface, and every offline replay a worker performs. A denied model is never picked by anything, and a request whose model is denied is refused before it reaches a provider, naming the rule that decided.

Two facts behind every decision

Every model in the catalog carries two independent, source-dated facts:

  • Provenance — the developing lab's jurisdiction (an ISO 3166-1 alpha-2 country such as US, CN, FR) and whether its weights are open (publicly downloadable) or closed (API-only). Provenance belongs to the logical model; a mirror offer inherits it.
  • Hosting — where a specific offer actually runs (again an ISO country), which can differ from the lab's jurisdiction. A Chinese open-weight model served from a US host has provenance CN but hosting US.

When a fact is not established it is recorded as unknown — never guessed.

Presets

  • global (the default for every workspace) — every model is allowed unless a rule denies it. Nothing changes until you choose otherwise.
  • us_only — only models whose lab and hosting are both US are allowed. Anything else is denied, and a model whose provenance or hosting is unknown is denied too (fail-closed).
  • custom — start from a stated base (allow or deny) and build up from rules.

Rules

Rules layer on top of the preset, most specific first:

  1. per-model — allow or deny a specific logical or concrete model id.
  2. per-provider — allow or deny every offer served by a provider slug.
  3. US-hosted open-weight exception — allow a denied lab's open-weight models when they are US-hosted. Both facts must be established: weights = open and hosting = US; unknown never satisfies it.
  4. per-lab — allow or deny every model whose origin jurisdiction matches.

The precedence resolves a candidate against the first matching rule in that order, then falls back to the preset default. So an explicit per-model or per-provider rule wins over the exception; the exception in turn overrides a per-lab deny or the us_only origin requirement (letting, for example, a Chinese open-weight model run when it is US-hosted); a per-lab rule wins over the preset default.

What "unknown" means for you

Under us_only, a model discovered by a live catalog sync — or a custom provider you configured — carries unknown provenance/hosting and is therefore denied until the facts are curated. This is deliberate: a restrictive policy fails closed. Under global, unknown models remain allowed unless a rule denies them.

Managing your policy

Three endpoints under your workspace (see the API reference):

  • GET /v1/workspaces/{id}/model-policy — read the current policy (any member).
  • PUT /v1/workspaces/{id}/model-policy — replace it (owner or admin). The write is audited and bumps your config version, so the change is honored on the very next request — there is no second cache to invalidate.
  • POST /v1/workspaces/{id}/model-policy/preview — evaluate a proposed policy against the live catalog without changing anything. It returns how many offers it would allow and deny, the counts grouped by lab and by provider, the input-price range of the offers it would exclude, and the denied model ids — everything the onboarding wizard needs to show what a choice would exclude.

Choosing in the dashboard

You do not have to hand-write rules. A new customer meets a short wizard during onboarding — "Which models may your account use?" — and can reopen the same screen any time from Settings → Model policy.

  1. One question first. Two plain choices: Global ("use the best model for each job, wherever it is made or hosted") and US-only ("only models from US labs, served from the US"). Nothing is saved until you press Save; until you choose, Global applies, so behaviour never changes behind your back.

  2. Consequences before you commit. As you change the choice, a live summary — computed from the same catalog the gateway routes over — shows how many of the catalog's models stay available, which countries and providers drop out (with how many offers each loses), the input-price range you would exclude, the models named as excluded, and any of your workflows whose pinned model the choice would block. A choice that would leave nothing to route to says so plainly.

  3. Fine control, only if you want it. Customise opens per-country and per-provider toggles and a searchable per-model list. Every row shows where a model is made and where it is served (a flag and the country name, never a bare code), whether its weights are open or closed, and its price. A model whose origin is not yet established reads honestly as "origin not yet verified — excluded under US-only".

  4. The US-hosted open-weight option. When the catalog actually offers them, you can allow open-weight models from excluded countries when they run in the US — for example a Chinese open-weight model served from a US region via a US host. The wizard lists exactly which models that option would admit. It is hidden when no such offer exists.

  5. Editable later, and audited. The Settings screen shows last changed by / when, and every save writes an audit event (the preset and rule count — never a secret) and bumps your config version, so the gateway honours the change within one cache window.

The wizard is keyboard-complete, screen-reader labelled, works at phone width, and is available in English, Portuguese (Brazil) and Spanish. It calls the same three endpoints below — it is not a second, parallel policy store.

Where it is enforced

The same policy binds every place a model is chosen:

  • Routing and fallbacks — denied offers are filtered out before selection; a fully denied requested model is a model_denied_by_policy refusal (HTTP 403) that names the rule in its message.
  • Evaluation and benchmark candidates — a denied model never enters the candidate pool, so it is never evaluated and can never become a recommendation.
  • Recommendations — because the candidate pool is already filtered, we never propose migrating a call type to a model your policy forbids.
  • Flywheel and evaluation replays — a worker refuses to re-invoke a denied model before any provider call.

An introspective test enumerates every place a model is picked and fails if a new one does not consult the policy, so this coverage cannot silently regress.