← Blog

Claude API Authentication Headers Example (Full Guide)

2026-09-23 · 4 min read · SubToAPI Team

Every request to a Claude-compatible API needs a specific set of HTTP headers to authenticate and format correctly. Get one wrong — a missing header, a bad version string, the wrong auth scheme — and you get a 401 or 400 before your prompt ever reaches the model. This article shows exactly which headers to send, with working examples, plus the mistakes that cause most authentication failures.

The short answer: Anthropic's native API expects an x-api-key header plus an anthropic-version header and a JSON content-type. If you're calling through SubToAPI instead, authentication is simpler — a single standard Authorization: Bearer header, the same pattern used by most modern REST APIs. Below we cover both, so you know exactly what to send depending on which API you're integrating.

The Core Headers You Need

Regardless of which backend you're calling, a Claude request almost always needs three things:

  1. An authentication header — proves who's calling.
  2. A content-type header — tells the server you're sending JSON.
  3. A version or API identifier — some backends require this to pick the correct request/response schema.

Here's what that looks like against Anthropic's native endpoint:

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-opus-4-20250514",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello, Claude"}]
  }'

Three details trip people up here:

The Same Request via SubToAPI

If you're using SubToAPI to turn Claude into a standard HTTPS API for your app, authentication is simplified to the pattern most developers already know from Stripe, OpenAI, and similar APIs:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-4-20250514",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello, Claude"}]
  }'

No x-api-key, no version header to remember, no separate account-level credentials to manage per environment. You create an application key (sub_live_...) in the dashboard, put it in your server-side environment, and send it as a standard Bearer token on every request. That's the whole authentication model. See the quickstart for the full setup and messages docs for request/response details.

Setting Headers in JavaScript

Here's the same call from Node.js using fetch, which is how most backend integrations actually look in production:

const response = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    model: "claude-opus-4-20250514",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello, Claude" }],
  }),
});

if (!response.ok) {
  throw new Error(`Auth or request failed: ${response.status}`);
}

const data = await response.json();
console.log(data);

Two habits worth adopting from day one:

Common Authentication Header Mistakes

Most "it doesn't work" reports trace back to one of these:

Verifying Your Headers Are Correct

Before wiring authentication into application code, test it in isolation with curl -v to see the raw request and response:

curl -v https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "content-type: application/json" \
  -d '{"model":"claude-opus-4-20250514","max_tokens":10,"messages":[{"role":"user","content":"ping"}]}'

A 200 with a valid JSON body confirms your headers are correct. A 401 means the auth header itself is wrong — check the key value and scheme. A 400 usually means the headers are fine but the request body is malformed.

If you're evaluating providers, SubToAPI gives every application its own sub_live_... key, tracks usage per key on the dashboard, and supports streaming and tool use with the same header pattern shown above — see streaming and tool use docs for those request shapes. Plans start at €9/month for solo use, with team pricing at /pricing, and a free trial at /signup.

Questions

Which header does Claude's API use for authentication — Bearer or API key? Anthropic's native API uses x-api-key with your raw API key value, not the Authorization: Bearer scheme. If you're calling through a proxy or wrapper API like SubToAPI, check its docs — many use the more common Bearer token pattern instead.

Why am I getting a 401 even though my API key looks correct? The most common causes are a copy-pasted key with hidden whitespace, using the wrong header name for your target API, or a key that's been revoked or belongs to the wrong environment (test vs. live).

Do I need to send a version header with every request? Anthropic's native API requires anthropic-version on every call. APIs built on top of it, like SubToAPI, may abstract this away entirely so you only manage a single auth header — check the relevant docs to confirm.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →