← Blog

Claude API Authentication Header Setup Guide

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

Setting up Claude API authentication means sending the right HTTP headers with every request: an API key header, a version header, and a content-type header. Get any one of these wrong and you'll hit a 401 or 400 error before your prompt even reaches the model. This guide walks through the exact headers required, how to generate and store keys safely, and how to debug the most common authentication mistakes.

If you just want the short version: Claude's API expects an x-api-key header carrying your secret key, an anthropic-version header pinning the API version you're coding against, and a content-type: application/json header on POST requests. Miss the version header and you'll get inconsistent behavior across API updates; miss the key header and you'll get a flat 401.

The three headers you need

Every authenticated request to Claude's Messages API requires:

A minimal curl request looks like this:

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

Forget any one of those three headers and the request fails — usually with a 401 (missing/invalid key), a 400 (missing version or malformed body), or occasionally a vague error if the version string itself is wrong.

Generating and storing the key correctly

Your API key should never be hardcoded into source files, committed to git, or embedded in frontend JavaScript. Treat it exactly like a database password:

  1. Generate the key in your provider's console.
  2. Store it as an environment variable (ANTHROPIC_API_KEY or similar) in your deployment platform's secret manager.
  3. Load it at runtime with process.env.ANTHROPIC_API_KEY (Node) or os.environ["ANTHROPIC_API_KEY"] (Python) — never as a literal string.
  4. Rotate it immediately if it's ever exposed in a log, screenshot, or client-side bundle.

A common mistake is putting the raw key into a .env file and then forgetting to add .env to .gitignore. Check this before your first commit, not after a leak.

JavaScript example with proper header setup

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-opus-4",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Summarize this ticket." }],
  }),
});

if (!response.ok) {
  const err = await response.json();
  console.error("Auth or request error:", err);
}

Always check response.ok and log the error body — Claude's error responses include a type field (authentication_error, invalid_request_error, etc.) that tells you exactly what went wrong instead of guessing from the status code alone.

Common authentication mistakes

Using Authorization: Bearer instead of x-api-key. This is the single most common error for developers migrating from other LLM APIs. Claude's native API does not accept a Bearer token in the standard OpenAI format — it wants the raw key in x-api-key.

Forgetting the version header entirely. Requests without anthropic-version may be rejected outright or behave unpredictably depending on the endpoint.

Leading/trailing whitespace in the key. If you're loading the key from a .env file or a CI secret, a stray newline character will cause a silent 401 that looks identical to a wrong key. Trim the string before using it.

Key scoped to the wrong organization or project. If you have multiple API keys across different projects, double-check which one is active in your environment variables, especially in staging vs. production.

Exposing keys in frontend code. Never call the Messages API directly from browser JavaScript — the key would be visible in the network tab to anyone. Proxy all calls through a backend you control.

Managing keys across teams and environments

Once you move past a single personal project, authentication setup gets harder: you need separate keys per environment (dev/staging/prod), per team member, and ideally per application, so you can revoke access without breaking everything else. Rolling your own key management means building rotation, per-key usage tracking, and rate limiting from scratch.

This is the exact problem SubToAPI solves. Instead of managing raw provider keys across every service, you generate scoped sub_live_... application keys from one dashboard, each with its own usage metadata and seat-level access control. Authentication setup becomes a single Authorization: Bearer sub_live_... header — no x-api-key vs Authorization confusion, no separate version header to track:

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

You can spin up a key per project, revoke it independently, and see exactly which key is driving usage, without touching your underlying provider credentials. Check the quickstart for the full setup, or the messages docs for request/response details. Plans start at €9/month with a free trial at signup; see pricing for team and scale tiers.

Questions

Do I use Authorization: Bearer or x-api-key for Claude's native API? Claude's native API requires x-api-key with your raw secret key, not the Authorization: Bearer format common to other providers. If you're using SubToAPI, it's the reverse — Authorization: Bearer sub_live_... — since it abstracts the underlying provider format.

What does a 401 error from Claude usually mean? Almost always an invalid, missing, trimmed-wrong, or revoked API key. Check for whitespace in your environment variable and confirm the key belongs to the right project.

Why do I need the anthropic-version header? It pins your request to a specific API contract so that provider-side updates don't silently change response formats or behavior under your code. Always set it explicitly rather than relying on a default.

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 →