Anthropic Claude API Authentication Setup Guide
Setting up authentication for the Anthropic Claude API comes down to three things: generating an API key in the Anthropic Console, sending it in the x-api-key header on every request, and including the anthropic-version header so the API knows which request/response format to use. Get those three right and you're authenticated — everything else (models, streaming, tool use) builds on top of that.
This guide walks through the full setup from account creation to your first authenticated request, plus the mistakes that cause most 401/403 errors and how to handle keys safely once you're past the "it works on my machine" stage.
Step 1: Create an Anthropic account and generate an API key
- Go to the Anthropic Console and sign up or log in.
- Navigate to API Keys in the dashboard.
- Click Create Key, give it a name (e.g.
production-backend,local-dev), and copy it immediately — Anthropic only shows the full key once. - Make sure billing is set up; the API won't accept requests on an account without a valid payment method or active credits.
Keys look like sk-ant-api03-.... Treat them exactly like a password — anyone with the key can make billed requests on your account.
Step 2: Store the key as an environment variable
Never hardcode the key in source files. Use an environment variable and load it at runtime:
export ANTHROPIC_API_KEY="sk-ant-api03-xxxxxxxx"
In a .env file (and make sure .env is in .gitignore):
ANTHROPIC_API_KEY=sk-ant-api03-xxxxxxxx
In Node.js:
import 'dotenv/config';
const apiKey = process.env.ANTHROPIC_API_KEY;
Step 3: Send the required authentication headers
Every request to the Claude API needs two headers:
x-api-key: your API keyanthropic-version: the API version string, e.g.2023-06-01
A minimal authenticated request with curl:
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello, Claude"}
]
}'
If this returns a 200 with a content array in the response, authentication is working. If it doesn't, check the error-handling section below before debugging anything else.
Step 4: Verify in code
A quick Node.js check that your environment is wired correctly:
const response = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers: {
"x-api-key": process.env.ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-4-20250514",
max_tokens": 100,
messages: [{ role: "user", content: "Say hi in one word." }],
}),
});
const data = await response.json();
console.log(data);
If data contains an error object instead of content, read the type field — it tells you exactly what went wrong (see below).
Common authentication errors and fixes
- 401 — authentication_error: the key is missing, malformed, or revoked. Double-check you're sending
x-api-key, notAuthorization: Bearer. Anthropic's native API uses the former, which trips people up coming from OpenAI's API. - 403 — permission_error: the key is valid but doesn't have access to the requested model or feature. Check your console for model access.
- 400 with "anthropic-version" missing: you forgot the version header. It's required on every request, not optional.
- 429 — rate_limit_error: you've hit your organization's rate or usage limit, not an auth problem — but it looks similar if you're not reading the error type carefully.
- Billing errors: no active payment method or exhausted credits. Authentication can succeed and the request still fail downstream.
Securing keys across environments and teams
Once you move past a single local script, a few practices save real pain:
- Separate keys per environment. Don't reuse a production key in staging or local dev. If one leaks, you only need to rotate one scope.
- Rotate keys periodically and immediately after any key appears in a log, screenshot, or committed file by accident.
- Don't pass keys through the browser. The raw Anthropic key should never reach client-side JavaScript — proxy requests through your own backend.
- Centralize key management for teams. If multiple developers or services need Claude access, giving everyone the raw org-level key is a liability — one leaked key affects everything.
This last point is where a lot of teams end up adding a layer in front of the raw Anthropic key: each app or developer gets its own scoped key, with its own usage visibility, instead of sharing one secret everywhere.
That's effectively what SubToAPI does — it sits between your apps and Claude and issues application-specific keys (sub_live_...) per project or team member, each with its own request logs and usage metadata, while still ultimately running on your Claude access. Setup follows the same pattern as above: generate a key from the dashboard, send it as a Bearer token, call the API. See the quickstart for the exact request shape.
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}]
}'
Plans start at €9/month on the pricing page, with team seats for shared key management and a free trial at signup. Streaming and tool use work the same way as direct Claude integration — see /docs/streaming and /docs/tools if you're building beyond basic chat completions.
Checklist before you ship
- [ ] API key generated and stored as an environment variable, never in source
- [ ]
x-api-keyandanthropic-versionheaders sent on every request - [ ]
.envadded to.gitignore - [ ] Separate keys for dev/staging/production
- [ ] Error handling that reads the
error.typefield, not just the status code - [ ] No raw API key reachable from client-side code
Questions
Do I use Authorization: Bearer or x-api-key for the Claude API? The native Anthropic API uses the x-api-key header plus an anthropic-version header. Authorization: Bearer is an OpenAI convention and won't authenticate against Anthropic's endpoint directly — though some gateway services, including SubToAPI, do accept Bearer tokens for their own keys.
Why am I getting a 401 even though my key looks correct? Usually a copy-paste issue (trailing whitespace or truncated key), a revoked key, or missing the anthropic-version header entirely. Re-copy the key from the console and confirm both required headers are present.
Can I use the same API key for multiple apps or team members? You can, but it's not recommended past a small side project — one shared key means no per-app usage visibility and a single leak compromises everything. Scoped keys per app or developer, whether through separate Anthropic console keys or a layer like SubToAPI's application keys, make auditing and revocation much easier.