OffRouter loads configuration from a few places. The hierarchy is merged in this order:
$OFFROUTER_HOME/config.toml or ~/.offrouter/config.toml$OFFROUTER_HOME/profiles/*.toml (Profile overlays)<workspace>/.offrouter/config.toml (Project config — only loaded if workspace is trusted)OFFROUTER_HOME: Overrides the default ~/.offrouter config directory.OFFROUTER_PROFILE: Sets the active profile (e.g. claude-personal). Overrides the CLI flag --profile.OFFROUTER_WORKSPACE_TRUSTED: Set to true to explicitly trust the current workspace and allow loading .offrouter/config.toml from the project.DO_NOT_TRACK: When set to a truthy value, forces anonymous telemetry off for that process.config.toml SchemaThe root config file allows you to define allowlists, denylists, global policy, and provider setup.
allowlisted_profiles (Array of Strings): Only these profile IDs are allowed to route.denied_profile_patterns (Array of Strings): Disallow these patterns (e.g. ["*-work"]). Defaults to ["*-work"].[policy] BlockGlobal behavior defaults.
subscription_first (Boolean): Prioritize subscription accounts over API keys. Defaults to true.allow_api_key_fallback (Boolean): Allow fallback to API keys if subscriptions fail or are unavailable. Defaults to false.allow_third_party_subscription_adapters (Boolean): Allow unofficial third-party adapters. Defaults to false.near_limit_threshold (Number): 0 to 1 value (e.g., 0.1 for 10%) indicating when to warn about approaching rate limits.denied_providers (Array of Strings): Disallow these provider IDs.spend_cap_usd (Number): Hard cap on estimated paid API-key spend. At or over the cap, API-key routes are denied; subscription and local routes are never blocked. Per-provider spend_cap_usd under [providers.<id>] overrides this. Check spend with offrouter status --costs.require_api_spend_approval (Boolean): When true, paid API-key routes require an explicit per-invocation acknowledgment — route --approve-api-spend on the CLI or the approve_api_spend input on MCP tools. Without it, API-key candidates are denied with api_spend_approval_required. Subscription and local routes are never affected.subscription_switch (String): "auto" (default) or "ask". In "ask" mode, when the ranked subscription candidate belongs to a different account than the most recently used account for that provider family (tracked in the usage store), the switch is denied with subscription_switch_requires_ack unless acknowledged — route --approve-switch on the CLI or the approve_switch input on MCP tools. First use of a provider family never asks; local and API-key routes are never affected.outbound_secret_scan (String): "warn" (default), "block", or "off". Scans outbound prompts for credential shapes before dispatch; block fails the request before any network call.[telemetry] Block
Optional declared preference only. Consent and the anonymous id live in
~/.offrouter/telemetry.json (managed by
offrouter telemetry / interactive init). Setting
this block alone never starts sending events. See the
telemetry docs.
enabled (Boolean, optional): Declared preference. Default unset means undecided.[providers.<id>] BlockConfiguration for external provider runtimes or API accounts.
enabled (Boolean): Defaults to true.base_url (String): Optional override for OpenAI-compatible endpoints.accounts (Array of Objects): E.g., [{ id = "my-account", label = "Personal" }].allowed_models (Array of Strings): When present, only these model ids may route through this provider. Supports a single trailing * prefix glob such as "gpt-5.6-*" for exact prefixes; absent means all models.denied_models (Array of Strings): Model ids that are always blocked for this provider. Deny beats allow. Supports a single trailing * prefix glob such as "gpt-5.6-*".[[routing.rules]] Array of TablesUser-defined routing rules let you pin a model, provider, or tier for a specific caller role or classifier family. Rules are explicit user intent; they run after policy gates and before the automatic subscription-first ranking. A rule can only pick among policy-allowed candidates — a pinned model that is denied stays denied, and routing falls through to the next matching rule, then auto.
role (String, optional match key): caller-supplied role such
as plan, implement, review,
bulk, etc. Matched exactly against the --role
CLI flag or the role input on MCP tools.
family (String, optional match key): classified model
family. One of fast-coder or frontier-coder.
Matched against the heuristic/LLM classifier output.
role or family is required.
When both are present, they are AND-ed.
model (String, target): exact pin in
provider/model-id form. Only allowed candidates with this
provider and model are considered.
provider (String, target): any allowed model on the given
provider.
tier (String, target): prefer
subscription, local, or api-key.
Reorders allowed candidates so the preferred tier ranks first without
crossing any policy gate.
model, provider, or
tier is required.
Rules are evaluated in declaration order; the first matching rule wins.
If no rule matches, OffRouter falls back to auto routing
(subscription-first + health + classifier). Unknown keys inside a rule
produce a config warning and are stripped. A rule that references a
provider not configured in [providers] is also warned and
ignored.
[[routing.rules]]
role = "plan"
model = "anthropic/claude-fable-5"
[[routing.rules]]
family = "fast-coder"
tier = "local"
[[routing.rules]]
role = "bulk"
provider = "moonshot"
reserve_subscription_for (when present) is an auto-mode
behavior that applies only when no rule matched. Rules are evaluated
first; if none match, the auto pipeline and any reserve logic decide the
route.
profiles/*.toml)You can create named profile overrides in ~/.offrouter/profiles/<profile-id>.toml. It supports:
id (String): Profile ID. Defaults to the base filename.denied_providers (Array of Strings): Additional blocks for this profile.allow_api_key_fallback (Boolean): Override global policy.subscription_first (Boolean): Override global policy.~/.offrouter/config.toml# Root configuration
# Allow routing for personal profiles
allowlisted_profiles = ["claude-personal", "codex-personal"]
# Ensure work profiles are blocked
denied_profile_patterns = ["*-work"]
[policy]
# Use paid subscriptions first
subscription_first = true
# Allow fallback to explicit API keys
allow_api_key_fallback = true
# Warn when less than 10% of allowance remains
near_limit_threshold = 0.1
# Deny some specific providers entirely
denied_providers = ["untrusted-provider-id"]
# Provider definitions
[providers.ollama]
enabled = true
base_url = "http://localhost:11434/v1"
[[providers.ollama.accounts]]
id = "local"
label = "Local Ollama Instance"
[providers.anthropic]
enabled = true
[[providers.anthropic.accounts]]
id = "anthropic-key"
label = "Anthropic API Key"