Anthropic API Authentication Header Setup
Authenticating against the Anthropic API means sending three specific HTTP headers with every request: x-api-key, anthropic-version, and content-type. Unlike many APIs that use Authorization: Bearer <token>, Anthropic uses a custom x-api-key header, and this single difference is the source of most "401 Unauthorized" and "invalid header" errors developers run into.
This article walks through the exact header setup required, shows working curl and JavaScript examples, and covers the mistakes that cause authentication failures even when the API key itself is valid.
The three required headers
Every call to https://api.anthropic.com/v1/messages needs:
x-api-key— your Anthropic API key, sent as a plain value (noBearerprefix)anthropic-version— a date string like2023-06-01that pins the API version you're coding againstcontent-type— almost alwaysapplication/jsonfor standard requests
Here's the minimal working example:
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-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello, Claude"}]
}'
Miss any one of these three headers and you'll get an error — but the error message isn't always obvious about which header is missing, which is why this trips people up repeatedly.
Why x-api-key instead of Authorization: Bearer
Most REST APIs you've worked with — Stripe, OpenAI, GitHub — use the standard Authorization: Bearer <token> header. Anthropic doesn't. It uses a custom header named x-api-key, with the raw key as the value and no prefix at all.
If you copy-paste boilerplate from another API integration, the most common bug is something like:
Authorization: Bearer sk-ant-api03-xxxxx ❌ wrong — Anthropic ignores this
instead of:
x-api-key: sk-ant-api03-xxxxx ✅ correct
Sending Authorization: Bearer alone to Anthropic's endpoint does nothing useful — the request will be rejected as unauthenticated because Anthropic looks specifically for x-api-key.
The anthropic-version header is not optional
A lot of developers assume anthropic-version is cosmetic or only needed for beta features. It isn't. Omitting it, or sending a malformed date string, returns a 400-level error unrelated to your credentials — which is confusing because it looks like an auth problem when it's actually a versioning problem.
Pin a specific version string (e.g. 2023-06-01) rather than guessing or leaving it blank. Check Anthropic's docs for the current recommended value before shipping to production, and keep it consistent across your codebase so behavior doesn't silently shift between requests.
Setting headers in Node.js
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-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Claude" }],
}),
});
const data = await response.json();
console.log(data);
Note the casing: HTTP headers are case-insensitive on the wire, but keep them lowercase in your code to match Anthropic's own documentation and avoid confusing diffs when debugging with curl's -v flag.
Common authentication header mistakes
- Using
Authorization: Bearerinstead ofx-api-key— the single most frequent mistake. - Leaving out
anthropic-version— causes an error that looks unrelated to auth. - Wrapping the key in quotes inside the header value — e.g.
x-api-key: "sk-ant-..."includes the quote characters literally and breaks the key. - Trailing whitespace or newlines in environment variables — especially common when keys are copied from a
.envfile or a CI secret manager that appends a newline. - Using a key from the wrong workspace or project — the header syntax is correct but the key itself doesn't have access to the resource you're calling.
- Sending the key in the request body instead of a header — the API only reads credentials from headers, never from the JSON payload.
If you're getting a 401 and the header name, casing, and format all look correct, regenerate the key and double-check for stray whitespace before assuming it's a code bug.
When you need more than raw header management
Setting headers correctly is step one. Once you're running this in production, you'll likely also need to handle streaming responses, retries, team-wide key rotation, usage tracking per application, and rate limit backoff — none of which the raw header setup addresses on its own.
This is the gap SubToAPI fills. Instead of managing x-api-key and anthropic-version headers yourself across every service, you generate a sub_live_... key from your SubToAPI dashboard and authenticate with a standard Authorization: Bearer $SUBTOAPI_KEY header against https://api.subtoapi.app/v1/messages. The underlying Claude authentication, versioning, and streaming details are handled for you, and you get per-key usage metadata and team seats out of the box.
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}]
}'
If you'd rather issue separate keys per application or teammate instead of sharing one raw Anthropic key, see the quickstart guide or start a free trial at /signup. Full request and response formats are in the Messages API docs, and pricing details are on the pricing page.
questions
Do I need to send Authorization: Bearer for Anthropic's API? No. Anthropic's native API uses x-api-key with the raw key value, not an Authorization: Bearer header. Sending only Authorization will result in an authentication failure.
Why am I getting an error even though my API key is correct? Usually it's a missing or malformed anthropic-version header, stray whitespace in the key string, or quotes accidentally included in the header value — all of which produce errors that look auth-related but aren't caused by the key itself.
Can I use a standard Bearer token format with Anthropic-based tools? Not with Anthropic's raw API, but services built on top of it can. For example, SubToAPI issues sub_live_... keys that authenticate via a standard Authorization: Bearer header, which is more familiar if you're integrating with existing HTTP client libraries and tooling.