How to Set Up Claude API Authentication Headers
Setting up Claude API authentication headers correctly means sending three specific HTTP headers with every request: x-api-key for your credentials, anthropic-version to pin the API version, and content-type set to application/json. Miss any of these, or format them wrong, and you'll get a 401 or 400 error instead of a response.
This article walks through the exact header setup, shows working code examples, and covers the mistakes that trip up most developers the first time they wire up Claude authentication — whether you're calling Anthropic's API directly or going through a gateway like SubToAPI.
The Required Headers
Every request to Claude's Messages API needs these headers:
x-api-key: sk-ant-your-key-here
anthropic-version: 2023-06-01
content-type: application/json
Note that Claude does not use the Authorization: Bearer header the way many other APIs do. This is the single most common mistake developers make when porting code from OpenAI or other providers — Claude expects x-api-key, not Authorization.
Minimal curl 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-3-5-sonnet-20241022",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello"}
]
}'
If any of the three headers is missing, Anthropic's API returns an error describing exactly which one. If x-api-key is missing or invalid, you get a 401. If anthropic-version is missing, you get a 400 with a message asking you to specify a version.
Setting Headers in JavaScript
When you're building a server-side integration, you typically set headers once in a config object and reuse it across requests:
const headers = {
"x-api-key": process.env.ANTHROPIC_API_KEY,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
};
const response = await fetch("https://api.anthropic.com/v1/messages", {
method: "POST",
headers,
body: JSON.stringify({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello" }],
}),
});
A few practical notes:
- Never hardcode the key. Pull it from an environment variable or secrets manager, not a string literal in source code.
- Pin the
anthropic-versionheader explicitly. Relying on a default can break your app silently when Anthropic ships a new API version. - Keep
content-typeasapplication/jsonfor all standard Messages API calls, including streaming and tool use requests.
Why the Header Names Trip People Up
Most REST APIs developers have worked with — Stripe, GitHub, OpenAI — use Authorization: Bearer <token>. Claude's API deliberately uses a separate x-api-key header instead. This is a design choice from Anthropic, not a bug in your code, so don't waste time debugging a 401 by trying different Authorization formats. If you see:
{
"type": "error",
"error": {
"type": "authentication_error",
"message": "x-api-key header is required"
}
}
that confirms the header name itself, not the key value, is the problem.
Authenticating Through SubToAPI Instead
If your workflow is: you already pay for Claude through a Pro or Team subscription but don't have raw Anthropic API console access, SubToAPI turns that subscription into a standard HTTPS API with its own authentication model — one that follows the more familiar Authorization: Bearer pattern:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello"}
]
}'
Your SUBTOAPI_KEY is a sub_live_... key generated from your dashboard after signup. This removes the need to juggle x-api-key and anthropic-version headers manually — SubToAPI handles version pinning on its end, and you authenticate the same way you would with most other developer APIs.
This matters especially for teams: instead of sharing one Anthropic key across a codebase, you can issue separate sub_live_... keys per environment or per team member, see usage per key in the dashboard, and revoke access without rotating a shared secret everywhere it's used. Full setup details are in the quickstart guide and Messages API docs.
Common Authentication Errors and Fixes
401 — invalid x-api-key Your key is wrong, expired, or revoked. Double-check you copied the full key string with no trailing whitespace.
400 — missing anthropic-version Add the header explicitly; don't assume a default version applies.
403 — permission denied The key is valid but doesn't have access to the model or feature you're requesting (for example, a key scoped without tool-use access).
Headers work in curl but fail in your app Usually an environment variable isn't loading correctly — log the header object (with the key redacted) before the request fires to confirm it's populated.
Keeping Keys Secure
A few baseline practices regardless of which API you're authenticating against:
- Store keys in environment variables or a secrets manager, never in version control.
- Use separate keys for development, staging, and production.
- Rotate keys periodically and immediately if one is exposed in a log or client-side bundle.
- Never send API keys from browser-side JavaScript — proxy requests through a backend.
If you want per-key usage visibility and team-level key management without building that tooling yourself, that's exactly what SubToAPI's dashboard is built for, starting with a free trial at signup.
Questions
Do I need the Authorization header for Claude's API? No. Anthropic's native API uses x-api-key instead of Authorization: Bearer. If you're using a gateway like SubToAPI, it uses the more standard Authorization: Bearer format.
What happens if I omit the anthropic-version header? You'll get a 400 error. The API requires an explicit version string so your requests don't break when Anthropic updates the API.
Can I authenticate Claude API calls from client-side JavaScript? You shouldn't. API keys should never be exposed in browser code — proxy requests through your own backend or a service that issues scoped keys, and keep the actual credential server-side only.