OAuth tokens require undocumented system prompt validation for non-Haiku models — returns generic 400
Summary
Anthropic's Messages API silently validates the system field when requests are authenticated with OAuth tokens (sk-ant-oat-*). For all models except Haiku, the API requires the system prompt to begin with the exact string:
You are Claude Code, Anthropic's official CLI for Claude.
This string must be either:
- The entire first entry in a
systemarray, OR - The start of a plain
systemstring
Without it, the API returns HTTP 400 invalid_request_error with the unhelpfully generic message "Error". Haiku is exempt from this validation.
This requirement is undocumented, has no public guidance, and related issues are being auto-closed by bots without staff engagement.
Proof
All tests use the same OAuth token, headers, and model (claude-opus-4-6). The only variable is the system field.
No system prompt → 400
curl -s -X POST "https://api.anthropic.com/v1/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "anthropic-beta: claude-code-20250219,oauth-2025-04-20" \
-H "anthropic-version: 2023-06-01" \
-H "user-agent: claude-cli/2.1.85 (external, cli)" \
-H "x-app: cli" \
-H "content-type: application/json" \
-d '{"model":"claude-opus-4-6","max_tokens":50,"messages":[{"role":"user","content":"say hi"}]}'
{"type":"error","error":{"type":"invalid_request_error","message":"Error"}}
// HTTP 400
Identity concatenated into a single block → 400
# Same request but with:
"system": [{"type":"text","text":"You are Claude Code, Anthropic's official CLI for Claude. You help with tasks."}]
{"type":"error","error":{"type":"invalid_request_error","message":"Error"}}
// HTTP 400
Identity as separate first entry → 200 ✓
# Same request but with:
"system": [
{"type":"text","text":"You are Claude Code, Anthropic's official CLI for Claude."},
{"type":"text","text":"You help with tasks."}
]
{"model":"claude-opus-4-6","id":"msg_...","content":[{"type":"text","text":"Hi! 👋 How can I help you today?"}]}
// HTTP 200
Identity as plain string → 200 ✓
# Same request but with:
"system": "You are Claude Code, Anthropic's official CLI for Claude."
{"model":"claude-opus-4-6","id":"msg_...","content":[{"type":"text","text":"Hi! 👋 How can I help you today?"}]}
// HTTP 200
Model matrix (with correct system prompt)
| Model | Without identity | With identity |
|-------|-----------------|---------------|
| claude-opus-4-6 | 400 | 200 |
| claude-sonnet-4-6 | 400 | 200 |
| claude-haiku-4-5-20251001 | 200 | 200 |
Impact
This undocumented requirement affects every third-party consumer using Claude Max OAuth tokens outside the Claude CLI:
- OpenClaw — the open-source AI gateway used by hundreds of self-hosted deployments
- opencode-claude-auth — community OAuth bridge for OpenCode
- Custom integrations — anyone using
sk-ant-oat-*tokens with the Anthropic SDK
The community has been debugging this for weeks. Multiple issues have been filed:
- #34412 — OAuth 500 on Sonnet/Opus (tagged
invalid, no staff response) - #35269 — Opus/Sonnet silently blocked on MaxPlan
- #8052 — Large thread about "Credential Restricted to Claude Code"
- #24198 — "only authorized for use with Claude Code" error
All were auto-closed by bots or tagged invalid with no Anthropic staff engagement or explanation.
The asks
- Document the OAuth validation requirements publicly. If OAuth tokens require specific system prompt content, headers, and user-agent strings, publish this in the API docs so consumers can comply.
- Improve the error message.
{"message":"Error"}gives zero debugging signal. A message like"OAuth tokens require a Claude Code system prompt identity"would save the community hundreds of hours of debugging.
- Engage with the community. Multiple issues about this have been filed over the past month. A single official comment explaining the requirements (or confirming this is intentional) would resolve dozens of open threads.
Environment
- OAuth token:
sk-ant-oat01-*(Claude Max subscription, setup token viaclaude setup-token) - Tested from: Ubuntu 24.04 server, curl 8.5.0
- Models: claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5-20251001
- Headers:
anthropic-beta: claude-code-20250219,oauth-2025-04-20,user-agent: claude-cli/2.1.85 (external, cli),x-app: cli
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗