← Blog

How to Use a Claude AI API Key in Your Code

2026-09-04 · 5 min read · SubToAPI Team

Once you have a Claude AI API key, the actual job is wiring it into your application so requests authenticate correctly, responses parse cleanly, and errors don't take down your app in production. This guide covers exactly that: where the key goes, how to structure a request, how to handle streaming and tool calls, and what commonly trips people up.

The short version: a Claude API key is passed as a header on every HTTPS request to the Messages endpoint, never in the URL or request body. You send a JSON payload with a model name, a messages array, and a max_tokens limit, and you get back a JSON response (or a stream of events) containing the model's reply plus token usage data.

Where the API key actually goes

Anthropic's API expects the key in an x-anthropic-api-key-style header (check current docs for the exact header name, since providers vary). If you're using SubToAPI's API instead — which wraps Claude access behind a standard key format — the pattern is simpler and consistent with most REST APIs:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Summarize this in one sentence: ..."}
    ]
  }'

The key rule regardless of provider: never hardcode the key in client-side code. Keys belong in environment variables, secret managers, or server-side config — not in a frontend bundle, not in a mobile app binary, not committed to git.

// server.js — key stays server-side
const apiKey = process.env.SUBTOAPI_KEY;

const response = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "claude-sonnet-4",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Explain closures in JavaScript." }]
  })
});

const data = await response.json();
console.log(data.content[0].text);

Structuring a request correctly

Three fields are required in almost every request: model, max_tokens, and messages. Get these wrong and you'll get a 4xx error before the model even runs.

Optional but useful: system for instructions that apply across the whole conversation, temperature for controlling randomness, and stop_sequences if you need the model to halt on a specific string.

Full parameter reference: /docs/messages.

Handling streaming responses

For anything user-facing — a chatbot, a live code assistant — streaming avoids the dead air of waiting for the full response. Set "stream": true and read server-sent events instead of a single JSON blob:

const response = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "claude-sonnet-4",
    max_tokens: 1024,
    stream: true,
    messages: [{ role: "user", content: "Write a haiku about deadlines." }]
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  process.stdout.write(decoder.decode(value));
}

Each chunk arrives as a discrete event (content_block_delta, message_stop, etc.), so your parser needs to handle partial JSON gracefully rather than assuming one event per network read. Details at /docs/streaming.

Using tools (function calling)

If your app needs Claude to call external functions — a database lookup, a calculator, a search API — you define tools in the request with a name, description, and JSON schema for the input:

{
  "tools": [
    {
      "name": "get_weather",
      "description": "Get current weather for a location",
      "input_schema": {
        "type": "object",
        "properties": {
          "location": { "type": "string" }
        },
        "required": ["location"]
      }
    }
  ]
}

Claude returns a tool_use block instead of plain text when it decides to invoke a tool. Your code runs the actual function, then sends the result back as a tool_result message to continue the conversation. See /docs/tools for the full round-trip pattern.

Handling errors and rate limits

Production code needs to handle at minimum three response categories:

if (response.status === 429) {
  const retryAfter = response.headers.get("retry-after") || 2;
  await new Promise(r => setTimeout(r, retryAfter * 1000));
  // retry request
}

Every response also includes token usage data (input_tokens, output_tokens), which you should log if you're tracking cost per request or per user.

A simpler path for teams

If you already have Claude access through a Pro or Team subscription and want to expose it as an API without managing separate direct billing, SubToAPI turns that access into a standard HTTPS API with sub_live_... keys, streaming, tool support, and per-key usage metadata — useful when you want multiple apps or team members hitting the same underlying access with clean separation. Plans start at €9/month (Solo), with Team and Scale tiers for shared seats, and a free trial at /signup. Get started with /docs/quickstart or check /pricing for plan details.

Questions

Do I need a different API key for each app I build? Not necessarily — one key can serve multiple applications. Many teams do split keys per app or environment (staging vs. production) so they can revoke or rate-limit one without affecting others.

Why does my request return a 401 even though I copied the key correctly? Usually it's a stray space, a missing Bearer prefix in the Authorization header, or the key being loaded from the wrong environment variable. Print the header value in a test request to confirm it's exactly what you expect.

Can I use the same key on the frontend and backend? No — API keys should only ever be used server-side. If a browser or mobile app needs to trigger a Claude request, route it through your own backend endpoint that holds the key.

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 →