ANTHROPIC_API_KEY set, current, and not revoked?). Layer 2: Org/workspace (does the key's workspace have model access enabled?). Layer 3: Region/IP (VPN exit, country restriction). Layer 4: Model access (is claude-opus-4-7 explicitly enabled for your workspace?). Layer 5: Abuse signals (high concurrency from new account). Fix is usually layer 1 or 2 — verify the key in the Anthropic console + confirm Model Access on the right workspace. One curl command below isolates the cause in 30 seconds.
Each layer is independently checkable in 60-90 seconds. Skipping layers is what turns a 5-minute fix into a 5-hour rabbit hole on GitHub issues that don't apply to your setup.
The most-skipped layer because "obviously the key is set." But shells reload, .env files get out of sync, and keys get rotated/revoked in the Anthropic console without the local environment knowing. Verify with one command before assuming anything else.
An Anthropic account can have multiple workspaces, each with its own model-access settings, credit, and rate limits. The most common cause of "request failed with status code 403" after a fresh setup is a key generated in a workspace that has not been granted access to the specific Claude model Claude Code is calling.
claude-opus-4-7 and claude-sonnet-4-7) shows "Enabled". If it shows "Request access" or "Not enabled", that is your 403.Anthropic restricts API access from a list of regions. If your VPN exits in a restricted country, or your residential IP is shared with a high-abuse subnet, the API will return 403 with a payload like "error":{"type":"permission_error","message":"Region not supported"}.
Adding a payment method does not auto-enable every Claude model. Anthropic gates model access per workspace, especially for newer or higher-tier models. Claude Code defaults to Opus and Sonnet; if your workspace has only Haiku enabled (or vice versa), the request returns 403 with a permission error specific to the model name.
New accounts that suddenly fire dozens of parallel requests, or accounts whose IP shares space with known scrapers, can trip Anthropic's abuse heuristics. The signature is intermittent 403s — it works once, fails twice, works once more — never a clean failure.
"type":"permission_error" with a message about unusual activity. Drop your concurrency to 1 request at a time, wait 5 minutes, then retry. If it works at concurrency=1 and fails at concurrency=10, that's your signal. Contact Anthropic support with your account email + a sample request ID — they can clear the flag.If you've already eyeballed the layers and want a faster path, walk this tree based on what the error response actually says.
~/.claude/settings.json + .claude/settings.local.json for stale keys or wrong base URL.ANTHROPIC_API_KEY → restart shell."Region not supported" → Layer 3: VPN exit / IP region."Model not enabled" or model-name in message → Layer 4: enable model in workspace."unusual activity" / "permission_error" generic → Layer 5: abuse flag.x-api-key header or rewriting the host. Try curl -v through the proxy and confirm the header arrives intact at api.anthropic.com.
Three ways out of a 403, ranked by how invasive the fix is.
Run the Layer 1 curl. If it returns 200, your key works — fix Claude Code's local config. If it returns 401/403, fix at console.anthropic.com: regenerate key, switch to the right workspace, enable model access. Restart your terminal so the new ANTHROPIC_API_KEY is read.
If the curl returns 403 even from a fresh API key in a workspace where Model Access is shown as "Enabled", you need Anthropic to look at the account. Open a ticket at support.anthropic.com with: account email, workspace ID, the exact x-request-id from the 403 response headers, and the curl command (with key redacted). Response is typically 24-48 hours.
Sometimes the 403 is downstream of a non-obvious config — a corporate proxy stripping headers, an MCP server holding a stale key, a multi-account setup using aws-vault-style credential stores that mask ANTHROPIC_API_KEY. Text PJ a sentence about your setup; if it's recognizable, you'll get an answer in minutes. If not, no obligation — just operator-to-operator.
Both are free. The choice is about what kind of answer you need.
Text PJ when: you've walked the layers and want a sanity-check before opening a ticket, you suspect a config issue specific to your dev setup (MCP, multi-account, corporate proxy), or you're running Claude Code in production and need a faster turnaround than Anthropic support's 24-48hr SLA.
Open an Anthropic support ticket when: the curl smoke-test returns 403 with no obvious cause, you suspect an account-level abuse flag, or you need an official answer about model availability / region support. Anthropic's the only one who can clear flags or grant model access.
"Request failed with status code 403" tells you nothing about which of five completely different problems you're hitting. The HTTP layer is honest — server says "no" — but the cause lives one layer up: in your account, your workspace, your region, your model access, or your usage pattern.
Most "Claude Code 403" Stack Overflow / GitHub answers chase the wrong layer. They assume API key (Layer 1) when the real cause is workspace permission (Layer 2) or model gate (Layer 4). The translation is: "403 means the request landed and the answer was no — figure out who said no, not how to retry."
This is the same pattern as Salesforce 401, Stripe 402, or Twilio 21610. The status code is a header on a deeper question: which layer of permission failed? Every API has a 5-ish-layer permission stack; the fix is always the same recipe — walk the layers in order, don't guess.
Claude Code didn't break.
Your permission to act got rejected.
Walk the layers in order — the fix is almost always layer 1 or 2.
If you've walked the 5 layers and the 403 is still firing, text the actual response body + which layers you've ruled out. Operator opinion, not Anthropic support — but I'll usually beat their SLA. Free either way.
Text PJ · 858-461-8054Different status code? Different stack?
Text PJ a sentence about what you're actually hitting — I'll build you a free custom troubleshooting shareable on the house. No email, no funnel, no SOW.
📲 Text PJ — free shareableI'm almost positive I can help. If I can't, you don't pay.
No signup. No seminar. No bullshit.