OpenClaw + minirouter
Draft provider block for registering minirouter in OpenClaw's config, plus the spend controls an unattended agent needs.
Settings
config.json5 in the OpenClaw config directory
In order
- models.providers.minirouter.baseUrlhttps://api.minirouter.sh/v1
Complete, including /v1. OpenClaw treats this as the OpenAI-compatible root and appends /chat/completions itself.
- models.providers.minirouter.apiopenai-completions
- models.providers.minirouter.apiKey${MINIROUTER_KEY}
Read from the environment rather than written into the config file.
- agents.defaults.model.primaryminirouter/meta/llama-3.3-70b
Defining the provider is not enough — the model also has to be reachable from the agent defaults, or OpenClaw declines to use it.
{
agents: {
defaults: {
model: { primary: "minirouter/meta/llama-3.3-70b" }
}
},
models: {
providers: {
minirouter: {
baseUrl: "https://api.minirouter.sh/v1",
apiKey: "${MINIROUTER_KEY}",
api: "openai-completions",
timeoutSeconds: 300,
// cost is OpenClaw's own accounting field, in USD per million
// tokens. Copy the current rates for each model you add from
// https://minirouter.sh/models rather than leaving these stale.
models: [
{
id: "meta/llama-3.3-70b",
name: "Llama 3.3 70B (minirouter)",
reasoning: false,
input: ["text"],
cost: { input: 0.756, output: 0.756 },
contextWindow: 128000,
maxTokens: 8192
}
]
}
}
}
}Draft candidates · 4 models
All models →- Modelmeta/llama-3.3-70bWhyGeneral-purpose candidate for the always-on turn loop.→
- Modelmistral/ministral-14bWhySmall, cheap candidate for the routine turns that make up most of the day.→
- Modelzai/glm-5WhyTool-calling candidate for multi-step chores.→
- Modeldeepseek/deepseek-v3WhyReasoning-oriented candidate for the turns that need it.→
Only rows confirmed in the current live catalog are linked. A plain row is a draft recommendation, not a claim that the model is currently available. Paste ids exactly as written, author/name.
When it fails
- SymptomProvider loads but every model call 404sCodeinvalid_request
Paste https://api.minirouter.sh/v1 complete, including the /v1. These clients treat the base URL as the OpenAI-compatible root and append /chat/completions themselves, so trimming the /v1 leaves them calling a path that does not exist. docs/errors#invalid_request →
- SymptomProvider is defined but the model is refusedCodeclient-side
Declaring a provider does not make its models usable. The model has to be reachable from agents.defaults as well — check the primary model id matches the provider name and the model id exactly, provider/author/name.
- SymptomCredits gone overnight with nothing to showCodeinsufficient_credits
An agent in a retry loop spends at machine speed. Set dailyLimitNano on the key the agent uses — one key per agent, so a runaway is contained to that key rather than the whole balance. docs/errors#insufficient_credits →
- Symptom401 on every requestCodeinvalid_api_key
Wrong or rotated key. Keys start with mr-live-; after a rotation the old key keeps working for 24 hours, then dies. docs/errors#invalid_api_key →
- SymptomThe agent goes quiet mid-conversation in a chat channelCodeinsufficient_credits
The balance reached $0 mid-stream. The stream ends with a terminal error naming the exact charge for tokens already delivered — but you are reading it inside WhatsApp or Telegram, where there is no UI but the message itself, which is why that error carries a URL. docs/errors#insufficient_credits →
Every API error string carries a URL resolving to /docs/errors.
Other always-on personal agents
- Hermes AgentAlways-on personal agent
- OpenHandsAutonomous coding agent
Why this workload bills the way it does, what it costs to contain, and which models suit it: /use/personal-agents.