spawndocs

Configuration

The single JSON config file spawn reads, every property it holds, and how each one shapes a routing decision.

spawn keeps all of its own settings in one JSON file at ~/.spawn/config.json, written on first spawn enable. JSON is the only format spawn reads or writes: there is no YAML or .toml variant. (The one TOML file in the picture, ~/.codex/config.toml, belongs to Codex, not spawn. It is just where Codex itself reads its model provider. See Connect your agents.)

spawn enable writes only the user-facing surface: routing.tiers and routing.rules. Everything else (the port, router internals, confidence floor, effort axis, auth internals) has a sensible default in code and merges in underneath, so the file only shows what you're actually meant to tune. Any key can still be added to the file, or set with spawn config set, to override its default. Run spawn config get to see the full effective config (defaults plus your overlay).

Edit the file directly, or use spawn config set, then restart the gateway (spawn stop && spawn start) to pick up changes.

Example

This is the starter file spawn enable writes:

~/.spawn/config.json
{
  "routing": {
    "tiers": {
      "anthropic": {
        "small": "claude-haiku-4-5",
        "mid": "claude-sonnet-4-6",
        "large": "claude-opus-4-8"
      },
      "openai": {
        "small": "gpt-5.4-mini",
        "mid": "gpt-5.5, low",
        "large": "gpt-5.5, high"
      }
    },
    "rules": []
  }
}

Any other key documented below can be added to this file to override its default.

Target atoms

Every tier and rule use value is a target atom: a string that's either just a model id, or "model, effort":

"claude-sonnet-4-6"
"gpt-5.5, low"

The effort suffix is one of low | medium | high | xhigh | max. An effort pinned in a target beats the automatic effort axis. This is how openai.mid and openai.large can point at the same base model (gpt-5.5) at two different reasoning efforts: the effort dial is the real lever on that ladder.

Properties

Top level

KeyTypeDefaultWhat it controls
portnumber8787Port the gateway proxy listens on. Your agent's endpoint override must point here.

routing.tiers

A map of provider name (anthropic, openai) to its three model tiers. The router picks a tier (small, mid, large); this map decides which target atom that tier resolves to, so you control exactly what runs.

KeyTypeWhat it controls
routing.tiers.<provider>.smallstringTarget for cheap, fast tasks (exploration, docs).
routing.tiers.<provider>.midstringTarget for the default working tier.
routing.tiers.<provider>.largestringTop-tier target for hard or high-risk tasks.

Default ladder:

Providersmallmidlarge
anthropicclaude-haiku-4-5claude-sonnet-4-6claude-opus-4-8
openaigpt-5.4-minigpt-5.5, lowgpt-5.5, high

Provider names match the wire format the agent uses: anthropic for Claude Code, openai for Codex.

routing.rules

Ordered preference overrides on the classifier's dimensions. Rules are checked top-down; the first match wins, otherwise the tier ladder applies.

{
  "routing": {
    "rules": [
      { "when": { "task_type": "design" }, "use": "large" },
      { "when": { "complexity": "easy", "risk": "low" }, "use": "small" },
      { "when": { "risk": "high" }, "use": "claude-opus-4-8" }
    ]
  }
}
KeyTypeWhat it controls
whenobjectConditions on task_type, complexity, and/or risk. Keys AND together; an array value means "any of".
usestringA tier name (small | mid | large, safety bumps still apply) or an explicit target atom (final, no bumps).

Rules replace the array wholesale when set in the config file; there's no merge-by-index with defaults (the default is an empty list, so this rarely matters).

routing.confidenceFloor

KeyTypeDefaultWhat it controls
routing.confidenceFloornumber (0-1)0.55When the classifier's overall confidence drops below this, spawn fails safe and routes up a tier rather than risk under-powering the task.

routing.bumpOnHighRisk

KeyTypeDefaultWhat it controls
routing.bumpOnHighRiskbooleantrueHigh risk bumps both the model tier and the effort one step up, so risky work is never silently nerfed.

routing.effort

Maps each predicted complexity bucket to a reasoning effort level, for targets that don't pin their own effort. Easy tasks run cheap; hard tasks run at full effort.

KeyTypeDefault
routing.effort.enabledbooleantrue
routing.effort.byComplexity.easy"low" | "medium" | "high" | "xhigh" | "max""low"
routing.effort.byComplexity.mediumsame"medium"
routing.effort.byComplexity.hardsame"high"

To route by effort alone (same model, vary effort), point every tier at one model and pin an effort on each target instead of relying on this axis.

router

Settings for how spawn runs the local classifier (spawn-router). Most installs never need to touch these.

KeyTypeDefaultWhat it controls
router.engine"node" | "python""node""node" runs in-process via onnxruntime-node (downloads weights on first use). "python" shells out to a spawn-router checkout for the PyTorch model.
router.hfRepostring"afterbuild/spawn-router"Hugging Face repo the node engine downloads ONNX weights from.
router.modelRevisionstring"main"HF revision/tag for the sha256-pinned download.
router.repoDirstring~/.spawn/routerPath to the spawn-router repo checkout ("python" engine only).
router.modelDirstring<repoDir>/artifacts/coding-router-v6Checkpoint directory.
router.pythonPathstringthe repo's .venv if present, else "python"Python executable ("python" engine only).
router.scriptstring"onnx_predict.py"Serving script; "predict.py" falls back to the PyTorch path.

projects

Per-project routing overrides, keyed by absolute path prefix. The longest matching prefix wins at task kickoff.

{
  "projects": {
    "/home/me/work/critical-service": {
      "tiers": { "anthropic": { "small": "claude-sonnet-4-6" } },
      "rules": [{ "when": { "risk": "high" }, "use": "large" }],
      "pin": "claude-opus-4-8"
    }
  }
}
KeyTypeWhat it controls
tiersobjectPartial tier overrides, same shape as routing.tiers.
rulesarrayPrepended before the global rules for this project; first match still wins.
pinstringAn explicit target atom that short-circuits the ladder entirely for this project.

Each override needs at least one of tiers, rules, or pin.

auth

KeyTypeDefaultWhat it controls
auth.mode"subscription" | "api_key""subscription"How upstream requests authenticate. Set by spawn enable; both are first-class. See Authentication.

upstreams and subscriptionUpstreams

Base URLs the gateway forwards to, per provider and auth mode. Only override these if you're pointing at a different endpoint (e.g. an enterprise proxy).

KeyDefault
upstreams.anthropichttps://api.anthropic.com
upstreams.openaihttps://api.openai.com
subscriptionUpstreams.anthropichttps://api.anthropic.com
subscriptionUpstreams.openaihttps://chatgpt.com/backend-api/codex

apiKeys and anthropicAuthHeader

Per-provider, gateway-held API keys. If a key is present for a provider, the gateway strips the client's own credentials and injects this key (api-key billing for that provider only); if absent, the client's own subscription/OAuth login rides through untouched. This means, for example, one client can ride a Claude subscription while another uses an OpenAI API key.

KeyTypeDefaultWhat it controls
apiKeys.anthropicstringunsetGateway-held Anthropic API key.
apiKeys.openaistringunsetGateway-held OpenAI API key.
anthropicAuthHeader"x-api-key" | "authorization" | "both""x-api-key"Header used to inject the Anthropic key (ignored unless apiKeys.anthropic is set).

Authentication

The auth.mode field records the choice you made at spawn enable:

  • "subscription" (default): the gateway forwards your agent's own Pro/Max or ChatGPT login. No API key is needed.
  • "api_key": the gateway forwards your own provider API key to the standard provider API.

Both are first-class. Switch by re-running spawn enable with --subscription or --api-keys, or edit auth.mode directly. See the gateway for the full tradeoff.

Reading and writing values

Terminal
spawn config get                          # full effective config (defaults + your overlay)
spawn config get routing.tiers.openai.mid
spawn config set routing.tiers.openai.mid "gpt-5.5, low"

spawn routing show                        # tiers, rules, effort axis, with * marking overrides

For the lifecycle commands that create and read this file, see the CLI. For how each routing knob behaves end to end, see Routing.

On this page