ClawRouter gives Apus one policy-scoped key for multiple upstream model providers. The bundled clawrouter plugin discovers only the models allowed for that key, routes each model through its declared protocol, and reports the key's budget and aggregate usage on Apus usage surfaces.

Upstream credentials and provider-specific forwarding stay in ClawRouter, so you never install or authenticate each upstream provider plugin on the Apus host. The plugin ships bundled with Apus (enabledByDefault: true); you only need an issued ClawRouter key.

Property Value
Provider clawrouter
Plugin bundled (included in Apus)
Auth CLAWROUTER_API_KEY
Default URL https://clawrouter.ami-docs.dev.apuscorp.com
Model catalog Credential-scoped via /v1/catalog
Quotas Monthly budget and usage via /v1/usage

Getting started

Get a scoped credential

Ask your ClawRouter administrator for a ClawRouter key whose policy
includes the providers, models, and monthly budget you should use.
ClawRouter keys are revealed once when issued.

Configure Apus

```bash
export CLAWROUTER_API_KEY="..."
apus onboard --auth-choice clawrouter-api-key
apus plugins enable clawrouter
```

`clawrouter` is bundled and enabled by default. If your configuration sets
`plugins.allow`, add `clawrouter` to that list before enabling it. For a
custom deployment, set `models.providers.clawrouter.baseUrl` to the
ClawRouter origin; the default is `https://clawrouter.ami-docs.dev.apuscorp.com`.

List granted models

```bash
apus models list --all --provider clawrouter
```

Use the returned model refs exactly as shown. They retain the upstream
namespace, such as `clawrouter/openai/gpt-5.5`,
`clawrouter/anthropic/claude-sonnet-4-6`, or
`clawrouter/google/gemini-3.5-flash`. If `agents.defaults.modelPolicy.allow`
is configured, add each selected ClawRouter ref to it.

Select a model

```bash
apus models set clawrouter/<provider>/<model>
```

You can also select a returned model for one run with
`apus agent --model clawrouter/<provider>/<model> --message "..."`.

Managed non-interactive deployment

Keep the ClawRouter key in the workload's secret injection and store only a SecretRef in apus.json. The canonical managed fields are:

Purpose Config or environment field
Router origin models.providers.clawrouter.baseUrl
Credential models.providers.clawrouter.apiKey -> env SecretRef
Secret value CLAWROUTER_API_KEY in the gateway process environment
Default model agents.defaults.model.primary -> clawrouter/<provider>/<model>
Workload tag models.providers.clawrouter.headers.X-ClawRouter-Project-Id (optional)

For example, a deployment controller can own this JSON5 patch:

{
  plugins: {
    entries: { clawrouter: { enabled: true } },
  },
  models: {
    providers: {
      clawrouter: {
        baseUrl: "https://clawrouter.internal.example",
        apiKey: {
          source: "env",
          provider: "default",
          id: "CLAWROUTER_API_KEY",
        },
        headers: {
          "X-ClawRouter-Project-Id": "fakeco",
        },
      },
    },
  },
  agents: {
    defaults: {
      model: { primary: "clawrouter/openai/gpt-5.5" },
    },
  },
}

If the deployment sets plugins.allow, preserve its existing entries and add clawrouter. Validate and apply without an interactive wizard:

apus config patch --file ./clawrouter.patch.json5 --dry-run --json
apus config patch --file ./clawrouter.patch.json5

The dry run resolves the SecretRef but never prints its value. To rotate the ClawRouter key, update the external Secret that supplies CLAWROUTER_API_KEY and restart the gateway workload so the new process environment is loaded. The config file and model reference do not change.

For a source-built standalone Docker gateway, ClawRouter is already included in the root runtime. Select only the channel plugin that needs separate packaging, such as APUS_EXTENSIONS=clickclack, slack, or msteams; see source-built images with selected plugins. Archive/appliance deployments must package the same landed source through their own artifact pipeline rather than consuming the OCI image.

Readiness and live proof

These checks prove different boundaries; do not substitute one for another:

# ClawRouter process health only; no credential or upstream model is exercised.
curl -fsS https://clawrouter.internal.example/v1/health

# Apus gateway startup readiness only; no model call is made.
curl -fsS http://127.0.0.1:18789/readyz

# Credential-scoped catalog discovery.
apus models list --all --provider clawrouter --json

# Minimal real inference test through the configured ClawRouter provider.
apus models status --probe --probe-provider clawrouter --probe-max-tokens 8 --json

# Workload canary using an exact granted model ref.
apus agent --agent main \
  --model clawrouter/openai/gpt-5.5 \
  --message "Reply exactly: CLAWROUTER_CANARY_OK" \
  --json

Use a model returned by the scoped catalog instead of copying the example model blindly. A successful /readyz response means the gateway can serve requests; it does not claim that ClawRouter, the ClawRouter key, or an upstream provider is ready. The model check and agent canary are the inference proofs.

For live diagnosis, enable APUS_DEBUG_MODEL_TRANSPORT=1 in the gateway process, issue the canary, and inspect the gateway's logs. The metadata-only model transport diagnostics emit lines shaped like:

[model-fetch] start provider=clawrouter api=openai-responses model=openai/gpt-5.5 method=POST url=https://clawrouter.internal.example/v1/responses
[model-fetch] response provider=clawrouter api=openai-responses model=openai/gpt-5.5 status=200

Without targeted debug flags, start and fast successful response records use debug; non-2xx responses and responses taking at least one second stay at info. See model transport diagnostics.

The plugin sends bounded X-ClawRouter-Client, X-ClawRouter-Agent-Id, and X-ClawRouter-Session-Id headers when those identifiers are available. It also maps the model call's diagnostic callId (<run-id>:model:<n>) to X-Request-ID, so an Apus model-call event can be joined to ClawRouter's metadata-only audit trail. Values within the 128-character request-id budget are identical. Longer values retain the :model:<n> suffix and a deterministic hash so distinct calls remain bounded and joinable. Static deployment metadata such as X-ClawRouter-Project-Id can be set in the provider headers map. Agent and session attribution headers retain their separate 256-character limit. Automatic request ids containing characters outside ClawRouter's ASCII identifier set use the same deterministic bounded form. Explicit configured headers, including any case variant of X-Request-ID, win over automatic values. The transport diagnostic records routing and response metadata; it does not log credentials, request ids, prompts, or completions. ClawRouter's own audit event provides the selected upstream provider and content-retention state.

Model discovery

GET /v1/catalog returns { providers: [...] }, where each provider entry lists its own models[] (with upstream id, capabilities, and pricing) and its supported request routes. Apus does not ship a second, fixed list of ClawRouter models. A catalog model is advertised as an Apus model when:

Adding a model to a supported ClawRouter provider needs no Apus release. Successful catalog responses, including an empty granted-model list, are reused for one hour per endpoint and resolved credential. Ordinary model-list reads serve retained inventory while expired data refreshes in the background. Use Refresh in Models to discover changes immediately; explicit refresh bypasses the response cache. A model that needs a new wire protocol requires plugin support first. Cached inventory is not authorization: ClawRouter checks current grants and budgets when a model request is dispatched.

A model's optional displayName is its picker label; without it, Apus uses the provider display name and catalog id, omitting a repeated <provider>/ prefix from the label (for example, Anthropic ยท claude-sonnet-4-6). The label never changes model identity. Responses and Chat Completions send the catalog id unchanged; only native Anthropic and Gemini routes use upstream at dispatch. A facade that exposes an alias must return only safe catalog metadata, including that alias in the required upstream field, and keep its private target mapping inside the facade.

Protocol and provider plugins

ClawRouter owns upstream credentials; its catalog tells Apus which transport to use, so you never install every upstream company's auth plugin.

Catalog capability / route Apus transport
llm.responses (OpenAI-compatible provider) openai-responses
llm.chat (OpenAI-compatible provider) openai-completions
llm.messages + anthropic.messages route anthropic-messages
llm.stream + streaming google.generate_content route google-generative-ai

The plugin also applies the matching replay and tool-schema policies for those families (OpenAI/DeepSeek/Gemini/Perplexity tool-schema compat; native Anthropic and Google Gemini replay policies). Perplexity models get a strict schema rewrite: patternProperties and additionalProperties are removed and every object schema declares properties, because Perplexity rejects tool schemas without them. A catalog provider exposing only an unsupported request format is intentionally not advertised as an Apus text model. Normalize those providers to one of the supported contracts in ClawRouter rather than sending an incompatible payload.

Quotas and usage

ClawRouter's /v1/usage response feeds the normal Apus provider-usage surfaces: request, token, and spend totals, plus a monthly budget window when the key has a limit. Unmetered keys still show aggregate usage without a percentage window.

Quota lookup uses the same ClawRouter key as model discovery. A failed quota lookup does not block model execution.

Check the live snapshot with:

apus status --usage
apus models status

The same provider snapshot is available to /status in chat and Apus's usage UI. The budget is policy-wide, so requests made by another client using the same ClawRouter policy can change the remaining percentage.

Troubleshooting

Symptom Check
No ClawRouter models Confirm the plugin is enabled and allowed by plugins.allow, then check that the ClawRouter key is active and grants at least one ready provider.
A configured ClawRouter model is missing Inspect its /v1/catalog capability and route support. Unsupported transport contracts are intentionally filtered.
Model override rejected by policy Add the exact catalog ref or clawrouter/* to agents.defaults.modelPolicy.allow.
401 or 403 from catalog or usage Reissue or re-scope the ClawRouter key; Apus does not fall back to upstream provider keys.
Model call fails after discovery Check the provider connection and upstream health in ClawRouter, then retry after its readiness state recovers.
Usage has totals but no percentage The policy is unmetered; add a monthly budget in ClawRouter to expose a percentage window.

Security behavior

Related

Model providers

Provider configuration and model selection.

Usage tracking

Apus usage and status surfaces.