← Blog

How to Set Up Claude API Authentication Headers

2026-10-25 · 4 min read · SubToAPI Team

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:

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:

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.

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 →