← Blog

Claude API HTTP Endpoint Setup Tutorial

2026-10-14 · 5 min read · SubToAPI Team

What "setting up the Claude API HTTP endpoint" actually means

If you're searching for this, you want to send a plain HTTP request to Claude and get a response back — no SDK, no wrapper, just an endpoint URL, some headers, and a JSON body. That's entirely possible: Claude is exposed as a standard REST-style HTTP API. You POST a JSON payload to a messages endpoint with an API key in the headers, and you get back a JSON response (or a stream of server-sent events if you ask for streaming).

This guide walks through the exact structure of that request — endpoint URL, required headers, request body shape, response format, and the common mistakes that cause 400s and 401s — so you can get a working call in minutes, whether you're hitting the endpoint directly or through a proxy like SubToAPI that turns it into a simpler key-based setup.

The anatomy of a Claude API HTTP request

Every request to a Claude-style messages endpoint has four parts:

  1. Method: POST
  2. URL: the base API URL plus a versioned path, e.g. /v1/messages
  3. Headers: authentication, content type, and (depending on provider) a version header
  4. Body: a JSON object with the model name, a messages array, and a max_tokens value

A minimal header set looks like this:

Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

And a minimal body:

{
  "model": "claude-sonnet-4",
  "max_tokens": 1024,
  "messages": [
    { "role": "user", "content": "Explain HTTP status codes in two sentences." }
  ]
}

That's the whole shape. Everything else — system prompts, tool definitions, streaming flags, temperature — is additive on top of this skeleton.

Step 1: Get an API key and confirm your base URL

You need a key before anything else. If you're setting this up through SubToAPI, you generate a sub_live_... key from the dashboard after signing up at /signup — no separate billing account or model access request needed, since it runs on top of your existing Claude access. The base URL in that case is https://api.subtoapi.app/v1/.

If you're hitting a provider endpoint directly, your base URL and key come from that provider's console instead. Either way, the request shape below is the same.

Step 2: Make your first raw HTTP call

Here's a full curl example against SubToAPI's endpoint:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 512,
    "messages": [
      { "role": "user", "content": "Write a one-line Docker healthcheck command." }
    ]
  }'

A successful response is a JSON object with the generated text, a stop_reason, and token usage:

{
  "id": "msg_01...",
  "role": "assistant",
  "content": [
    { "type": "text", "text": "HEALTHCHECK CMD curl -f http://localhost/ || exit 1" }
  ],
  "stop_reason": "end_turn",
  "usage": { "input_tokens": 18, "output_tokens": 14 }
}

If you're setting this up for the first time, keep the response printed to your terminal until you understand each field — stop_reason tells you why generation ended, and usage is what you'll later use for cost tracking.

Step 3: Wire it into JavaScript

Most endpoint setup problems aren't the API itself — they're environment variables, missing headers, or malformed JSON bodies in application code. Here's a clean fetch-based setup:

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-sonnet-4",
    max_tokens: 512,
    messages: [
      { role: "user", content: "Summarize this ticket in one sentence." }
    ]
  })
});

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

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

Full reference for request and response fields lives at /docs/messages. If you're doing this setup for the first time, /docs/quickstart covers key generation and your first call end to end.

Step 4: Add streaming if you need it

For chat UIs or anything latency-sensitive, you don't want to wait for the full response before rendering anything. Set "stream": true in the body and read the response as server-sent events instead of plain JSON:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 512,
    "stream": true,
    "messages": [{ "role": "user", "content": "Count to five." }]
  }'

Each event is a chunk prefixed with event: and data: lines. Parsing them correctly — especially handling partial tool-use blocks — is the part most people get wrong on a first setup. The full event sequence and a parsing example are documented at /docs/streaming.

Step 5: Handle errors deliberately

Don't let your endpoint setup silently swallow errors. The common ones:

A production-ready setup wraps the fetch/curl call in retry logic for 429/5xx and fails fast on 400/401, since those indicate a setup bug rather than a transient issue.

Step 6: Move beyond a single hardcoded key

Once the basic endpoint call works, the next problems are usually: separate keys per environment, per-team usage visibility, and not wanting to manage billing and rate limits yourself. That's the layer SubToAPI adds on top of the raw HTTP setup — scoped sub_live_... keys per app or environment, usage metadata on every response, and team seats, all through the same /v1/messages shape you just tested. Plans start at €9/month on Solo, with Team and Scale tiers for multi-seat setups — see /pricing for details, or start a free trial at /signup.

Questions

Do I need an SDK to call the Claude API endpoint? No. The endpoint is plain HTTPS with a JSON body, so curl, fetch, or any HTTP client in any language works. SDKs just wrap this same request.

Why am I getting a 401 after setting my API key correctly? Usually the key isn't actually reaching the request — check for trailing whitespace, a stale environment variable, or a missing Bearer prefix in the Authorization header.

Can I test the endpoint without writing code? Yes — curl from a terminal is the fastest way to confirm your key, headers, and body are correct before wiring anything into an application.

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 →