All posts
2026-03-309 min

OpenClaw + Claude Max: Auto-Renewing Anthropic OAuth Tokens So Your Agents Never Go Silent

AnthropicAuthenticationClaude MaxAutomationOpenClawSelf-Hosting

The Tweet That Started This

This morning someone posted exactly what half the OpenClaw community has been silently suffering through:

> *"This morning I woke up to all 6 of my AI Agents running perfectly — for the first time without me touching anything. That's new. I run OpenClaw with Claude Max on Mac Mini, and Anthropic's OAuth access tokens expire every 8 hours. When they do, every agent goes silent."*

If you run OpenClaw with Claude Max (Anthropic's subscription plan), you're not using an API key — you're using an OAuth session that Anthropic issues through their web login flow. Unlike an API key that never expires, these OAuth access tokens have a hard 8-hour TTL.

Every 8 hours: silence. Every morning: manual fix. That's the default experience unless you solve it.

This post covers exactly how to automate the renewal so you never touch it again.

---

Why This Happens: OAuth vs. API Key

When you connect OpenClaw to Anthropic via Claude Max (not the API tier), the auth flow works like this:

1. You log in via browser — Anthropic issues an access token (short-lived, ~8h) and a refresh token (long-lived)

2. OpenClaw uses the access token for every request

3. After 8 hours the access token expires — requests start returning 401

4. OpenClaw marks the account as unauthenticated — agents stop responding

The refresh token can get a new access token without re-logging in. The problem is that, by default, nothing in your setup is calling that refresh endpoint automatically.

---

Step 1: Find Your Tokens

OpenClaw stores auth credentials here:

```bash

cat ~/.openclaw/config.json | grep -A 10 '"anthropic"'

```

You're looking for a structure like:

```json

{

"anthropic": {

"authType": "oauth",

"accessToken": "sk-ant-oaXXX...",

"refreshToken": "rt-XXXXX...",

"expiresAt": 1743091200000

}

}

```

The `refreshToken` is what you need. It's long-lived (typically 30-90 days) and can be used to get new access tokens without user interaction.

---

Step 2: The Refresh Script

Create this script at `~/scripts/refresh-anthropic-token.sh`:

```bash

#!/bin/bash

set -e

CONFIG="$HOME/.openclaw/config.json"

BACKUP="$HOME/.openclaw/config.json.bak"

# Read current refresh token

REFRESH_TOKEN=$(cat "$CONFIG" | python3 -c "

import json, sys

cfg = json.load(sys.stdin)

print(cfg.get('anthropic', {}).get('refreshToken', ''))

")

if [ -z "$REFRESH_TOKEN" ]; then

echo "ERROR: No refresh token found in config.json"

exit 1

fi

# Call Anthropic's token endpoint

RESPONSE=$(curl -s -X POST "https://console.anthropic.com/v1/oauth/token" \

-H "Content-Type: application/json" \

-d "{

\"grant_type\": \"refresh_token\",

\"refresh_token\": \"$REFRESH_TOKEN\"

}")

NEW_ACCESS_TOKEN=$(echo "$RESPONSE" | python3 -c "

import json, sys

data = json.load(sys.stdin)

if 'access_token' not in data:

print('ERROR: ' + str(data), file=sys.stderr)

sys.exit(1)

print(data['access_token'])

")

NEW_EXPIRES=$(echo "$RESPONSE" | python3 -c "

import json, sys, time

data = json.load(sys.stdin)

expires_in = data.get('expires_in', 28800) # default 8h

print(int((time.time() + expires_in) * 1000))

")

# Back up config and update

cp "$CONFIG" "$BACKUP"

python3 -c "

import json, sys

with open('$CONFIG') as f:

cfg = json.load(f)

cfg['anthropic']['accessToken'] = '$NEW_ACCESS_TOKEN'

cfg['anthropic']['expiresAt'] = $NEW_EXPIRES

with open('$CONFIG', 'w') as f:

json.dump(cfg, f, indent=2)

print('Token updated. Expires at:', $NEW_EXPIRES)

"

# Reload OpenClaw gateway so it picks up new token

openclaw gateway restart --quiet 2>/dev/null || true

echo "Done. New token active."

```

Make it executable:

```bash

chmod +x ~/scripts/refresh-anthropic-token.sh

```

---

Step 3: Test It

Run manually once to confirm it works:

```bash

~/scripts/refresh-anthropic-token.sh

```

You should see:

```

Token updated. Expires at: 1743120000000

Done. New token active.

```

Then verify your agents are still responding by sending a message in your configured channel.

---

Step 4: Automate with Cron

You want to refresh every 6 hours — safely before the 8-hour expiry, with a 2-hour buffer.

Add to crontab:

```bash

crontab -e

```

```cron

0 */6 * * * /bin/bash $HOME/scripts/refresh-anthropic-token.sh >> $HOME/.openclaw/logs/token-refresh.log 2>&1

```

Or if you prefer OpenClaw's built-in cron system (recommended — uses the same scheduler your agents use):

In your OpenClaw config:

```json

{

"cron": {

"jobs": [

{

"name": "Anthropic Token Refresh",

"schedule": { "kind": "every", "everyMs": 21600000 },

"payload": {

"kind": "systemEvent",

"text": "Run shell: bash $HOME/scripts/refresh-anthropic-token.sh"

}

}

]

}

}

```

Or use the OpenClaw cron CLI:

```bash

openclaw cron add \

--name "Anthropic Token Refresh" \

--every 6h \

--cmd "bash $HOME/scripts/refresh-anthropic-token.sh"

```

---

Step 5: Add a Health Check

The script above is silent when it works — but you want to know when it *fails*. Add a notification:

```bash

# At the top of the script, wrap everything in error handling:

trap 'echo "TOKEN REFRESH FAILED at $(date)" | openclaw notify --channel telegram' ERR

```

Or use the OpenClaw watchdog — if your agent doesn't respond to a heartbeat after token refresh, it triggers an alert automatically.

---

Alternative: Use the API Tier Instead

If this feels like too much plumbing, the cleanest solution is switching from Claude Max (subscription) to the Anthropic API (pay-per-token):

| | Claude Max | Anthropic API |

|---|---|---|

| Auth | OAuth (8h TTL) | API key (no expiry) |

| Cost | Flat monthly fee | Pay-per-token |

| Best for | Heavy personal use | Predictable workloads |

| Token management | Manual or scripted | None needed |

For most OpenClaw setups with 3-6 agents running 24/7, the API tier ends up cheaper than Claude Max anyway — especially with `claude-haiku-3-5` for routine tasks and `claude-sonnet` only for complex ones.

---

Debugging: When the Refresh Fails

401 on the refresh endpoint:

Your refresh token itself may have expired. You'll need to re-authenticate manually: `openclaw auth login --provider anthropic`. This should give you a new refresh token with a fresh TTL.

Config update succeeds but agents still 401:

The gateway didn't pick up the new token. Force a restart: `openclaw gateway restart`.

Refresh token not in config.json:

Older OpenClaw versions store tokens differently. Check: `~/.openclaw/auth/` — there may be per-provider token files there instead.

curl: command not found in cron:

Cron runs with a minimal PATH. Either use full path (`/usr/bin/curl`) or source your profile at the top of the script: `source $HOME/.profile`.

---

The OpenClaw-Native Approach

If you're on OpenClaw 0.9+, there's a cleaner path: the gateway has a built-in auth refresh hook. You can configure it directly:

```json

{

"providers": {

"anthropic": {

"authType": "oauth",

"autoRefresh": true,

"refreshIntervalMs": 21600000

}

}

}

```

When `autoRefresh: true`, the gateway handles token rotation internally — no script, no cron job. This is the recommended approach for 0.9+. Check your version: `openclaw --version`.

If you're on an older version, the script approach above is the reliable fallback.

---

Summary

| Problem | Anthropic OAuth tokens expire every 8 hours |

|---|---|

| Symptom | All agents go silent overnight |

| Fix (scripted) | refresh-anthropic-token.sh + cron every 6h |

| Fix (native) | `autoRefresh: true` in config (OpenClaw 0.9+) |

| Nuclear option | Switch to Anthropic API tier (API keys don't expire) |

The first time this hits you at 3 AM — all 6 agents dead, client messages piling up — you fix it in 20 minutes and never think about it again. That's what this post is for.

The full configuration, all scripts, and monitoring setup are in the OpenClaw Setup Playbook.

Auch auf Deutsch verfügbar. 🇩🇪

Want to learn more?

Our playbook contains 18 detailed chapters — available in English and German.

Get the Playbook