OpenClaw is an open-source personal AI assistant that runs locally as a daemon and talks to you through chat apps and its own UI. With Tokens it uses the OpenAI Chat Completions protocol (openai-completions) against https://tokens.bd/v1, or the Anthropic Messages protocol against https://tokens.bd if you prefer.
The Tokens CLI doesn't configure OpenClaw, so use OpenClaw's own onboarding or edit its config file. Both take a couple of minutes.
Install OpenClaw#
curl -fsSL https://openclaw.ai/install.sh | bashiwr -useb https://openclaw.ai/install.ps1 | iexWith npm (Node 24.16+ or 26.1+), run npm install -g openclaw@latest --allow-scripts=openclaw and then openclaw onboard --install-daemon.
Export TOKENS_API_KEY#
Create a key at /dashboard/keys (API keys covers spend caps), then export it:
export TOKENS_API_KEY="tok_live_your_key"$env:TOKENS_API_KEY = "tok_live_your_key" # this window
setx TOKENS_API_KEY "tok_live_your_key" # new windowsOpenClaw runs as a background daemon, so make sure the variable is visible to the daemon, not only to your current terminal. Putting it in your shell profile (or using setx on Windows) and restarting the daemon is the simplest way.
Option A: non-interactive onboarding#
One command registers Tokens as a custom provider and sets the default model:
openclaw onboard --non-interactive --accept-risk --skip-health \
--mode local \
--auth-choice custom-api-key \
--custom-base-url "https://tokens.bd/v1" \
--custom-model-id "deepseek/deepseek-v4.1-flash" \
--custom-api-key "$TOKENS_API_KEY" \
--custom-provider-id "tokens" \
--custom-compatibility openaiopenclaw onboard --non-interactive --accept-risk --skip-health `
--mode local `
--auth-choice custom-api-key `
--custom-base-url "https://tokens.bd/v1" `
--custom-model-id "deepseek/deepseek-v4.1-flash" `
--custom-api-key "$env:TOKENS_API_KEY" `
--custom-provider-id "tokens" `
--custom-compatibility openai--custom-compatibility openai means chat completions, which is what you want. The other values are openai-responses and anthropic. Running openclaw onboard without flags offers the same custom-provider option interactively.
Option B: edit ~/.openclaw/openclaw.json#
OpenClaw reads a JSON5 config from ~/.openclaw/openclaw.json (comments and trailing commas are allowed). OPENCLAW_CONFIG_PATH points it elsewhere. The gateway watches the file and reloads changes without a restart.
{
"agents": {
"defaults": {
"model": { "primary": "tokens/deepseek/deepseek-v4.1-flash" },
"models": { "tokens/deepseek/deepseek-v4.1-flash": { "alias": "Tokens Flash" } },
},
},
"models": {
"mode": "merge",
"providers": {
"tokens": {
"baseUrl": "https://tokens.bd/v1",
"apiKey": "${TOKENS_API_KEY}",
"api": "openai-completions",
"timeoutSeconds": 300,
"models": [
{
"id": "deepseek/deepseek-v4.1-flash",
"name": "DeepSeek V4.1 Flash (Tokens)",
"reasoning": false,
"input": ["text"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 128000, // placeholder: use the real value
"maxTokens": 8192, // placeholder: use the real value
},
],
},
},
},
}Replace contextWindow and maxTokens with the real limits from the model's page in /models. The cost fields are only OpenClaw's local estimate; Tokens bills from its own meter, so zeros are fine.
The default model is written as provider/model-id. Our ids already contain a slash, which OpenClaw handles: its own docs use lmstudio/openai/gpt-oss-20b as an example.
To add the provider without rewriting the file, use openclaw config set models.providers.tokens '<json>' --strict-json --merge.
Anthropic-compatible variant#
If you'd rather use the Messages API, set api: "anthropic-messages" and baseUrl: "https://tokens.bd" (no /v1). OpenClaw doesn't send its implicit anthropic-beta headers to non-Anthropic hosts; if you need them, set models.providers.tokens.headers["anthropic-beta"].
Switch models#
Add another object to the provider's models array for each Tokens model you want, using exact ids from /models or GET /v1/models. Then change the default:
openclaw models set tokens/deepseek/deepseek-v4.1-flashor edit agents.defaults.model.primary. Choosing a model covers which models suit agent work.
Verify it works#
openclaw models list
openclaw models status
openclaw models status --probe--probe sends a real request, so it uses a few tokens. A successful probe should also show in your Usage analytics on the dashboard.
Troubleshooting#
Requests go to the wrong endpoint. Leaving api out on a provider with a baseUrl defaults to openai-completions, which is correct. Only use openai-responses if you know the model's upstream supports /v1/responses.
Long conversations fail. If contextWindow is missing, OpenClaw assumes 200,000 tokens. If maxTokens is missing, it sends no output limit at all. Set both to the model's real values.
401 missing_api_key. The daemon can't see TOKENS_API_KEY. Export it where the daemon starts, or put the key directly in apiKey in your local config (never in a shared or committed file).
Requests look different from OpenAI's. On hosts other than api.openai.com, OpenClaw turns off the developer role (compat.supportsDeveloperRole: false) and skips OpenAI-only fields like service_tier, store and prompt-cache hints. That's expected.
Need vendor-specific request fields. Put them under agents.defaults.models["tokens/<model>"].params.extra_body.
Missing usage numbers in streams. Only set compat.supportsUsageInStreaming: true if you've confirmed the stream includes usage; Tokens sends a usage chunk on OpenAI-style streams only when the client asks for it with stream_options.include_usage.
For 402, 403 and 429 errors, see Troubleshooting.