If you’re trying to use your Claude Max subscription with OpenClaw instead of a paid API key, you’re in for a ride. The docs are incomplete, the CLI wizard doesn’t work properly, and you’ll hit multiple 401 errors before figuring it out. Here’s the actual working setup.
The Problem
OpenClaw supports Anthropic as a model provider. You can either use an API key (straightforward) or your Claude Max/Pro subscription via OAuth (not straightforward). The openclaw models auth add wizard offers a “setup-token (claude)” option that asks you to paste a token from the Claude Max webpage. This doesn’t work.
Why It Doesn’t Work
The “Authentication Code” you copy from the Claude Max webpage is not a usable bearer token. It’s a one-time auth code that needs to be exchanged for real OAuth credentials (access token + refresh token). The OpenClaw wizard doesn’t do this exchange. It just stores the raw code and tries to use it directly, which Anthropic rejects.
What You’ll See
Depending on how you configure the auth profile, you’ll cycle through these errors:
HTTP 401 authentication_error: invalid x-api-key— OpenClaw is sending the token as an API key instead of Bearer authHTTP 401 authentication_error: Invalid bearer token— Correct auth method, but the token is the raw auth code, not an exchanged OAuth tokenNo API key found for provider "anthropic"— You settype: "oauth"but OpenClaw doesn’t recognize the profile format
The Fix
Step 1: Log in with Claude Code CLI
Install Claude Code CLI if you haven’t:
npm install -g @anthropic-ai/claude-codeThen log in:
claude auth loginThis opens a browser-based OAuth flow. Complete it. Verify with:
claude auth statusYou should see subscriptionType: "max" (or “pro”).
Step 2: Find the real OAuth tokens
Claude Code stores the exchanged tokens at:
cat ~/.claude/.credentials.jsonYou’ll see something like:
{
"claudeAiOauth": {
"accessToken": "sk-ant-oat01-...",
"refreshToken": "sk-ant-ort01-...",
"expiresAt": 1773867825944,
"subscriptionType": "max"
}
}These are the real tokens you need.
Step 3: Write the OpenClaw auth profile
Edit ~/.openclaw/agents/main/agent/auth-profiles.json:
{
"version": 1,
"profiles": {
"anthropic:default": {
"type": "oauth",
"provider": "anthropic",
"access": "sk-ant-oat01-YOUR_ACCESS_TOKEN_HERE",
"refresh": "sk-ant-ort01-YOUR_REFRESH_TOKEN_HERE",
"expires": 1773867825944
}
},
"usageStats": {}
}Copy the exact values from ~/.claude/.credentials.json:
accessToken→accessrefreshToken→refreshexpiresAt→expires
Step 4: Update openclaw.json
Make sure your ~/.openclaw/openclaw.json has a matching auth section:
{
"auth": {
"profiles": {
"anthropic:default": {
"provider": "anthropic",
"mode": "oauth"
}
}
}
}Key detail: mode must be "oauth", not "token".
Step 5: Restart the gateway
openclaw gateway restart --forceStep 6: Verify
openclaw models statusYou should see your anthropic profile listed with oauth type. Send a test message through the UI or Discord.
Things That Don’t Work
openclaw models auth add→ “setup-token (claude)” — Stores the raw auth code, doesn’t exchange it. Will always 401.openclaw models auth setup-token— Expects ask-ant-oat01-prefixed token, but the webpage gives you a raw code without that prefix.openclaw models auth paste-token— Writes atype: "token"profile, which sends the value asx-api-keyinstead of Bearer auth.- Manually prepending
sk-ant-oat01-to the webpage code — The code is not a valid token regardless of prefix. It needs the OAuth exchange.
Token Expiry
The access token expires (check the expires timestamp). OpenClaw should handle refresh automatically using the refresh token. If it stops working after a while, repeat steps 2-5 to grab fresh tokens from Claude Code CLI.
TL;DR
Don’t use OpenClaw’s auth wizard. Log in with claude auth login, steal the real OAuth tokens from ~/.claude/.credentials.json, and write them into OpenClaw’s auth-profiles.json manually.