How to Use the Claude API: A Practical Setup Guide
Using the Claude API means sending HTTP requests to Anthropic's Messages endpoint with an API key, a model name, and a list of messages, then handling the JSON (or streamed) response in your application. That's the whole mechanic — the rest of this guide covers authentication, request structure, streaming, tool use, and the mistakes that trip up most people on their first integration.
If you already have API access, you can skip straight to the code below. If you're using a Claude.ai subscription (Pro or Team) instead of a developer account, note that the console API and the consumer app are separate products with separate billing — more on that in the FAQ.
Step 1: Get an API key
Anthropic issues keys through the Anthropic Console, tied to a billing account with usage-based pricing. If you'd rather not set up separate console billing, tools like SubToAPI let you generate an application key (sub_live_...) that proxies requests through your existing Claude access, with usage tracking and team seats built in. Either way, the request format below is the same.
Step 2: Make your first request
The core endpoint is /v1/messages. It takes a model, a max_tokens limit, and an array of messages with role and content.
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-sonnet-4-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Explain what a race condition is in one paragraph."}
]
}'
If you're using SubToAPI, the shape is nearly identical, just pointed at a different host with a Bearer token:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Explain what a race condition is in one paragraph."}
]
}'
The response includes a content array (usually one text block), a stop_reason, and usage with input/output token counts. Read the quickstart or messages docs for the full parameter list.
Step 3: Manage conversation state
Claude's API is stateless — it doesn't remember previous turns automatically. You maintain the conversation by appending each user and assistant turn to the messages array and resending the whole history with every call.
const messages = [
{ role: "user", content: "What's the capital of Portugal?" }
];
const res1 = await callClaude(messages);
messages.push({ role: "assistant", content: res1.content[0].text });
messages.push({ role: "user", content: "What's its population?" });
const res2 = await callClaude(messages);
This is the single most common source of confusion for people moving from ChatGPT-style chat UIs: there is no server-side session, so token usage grows with conversation length unless you truncate or summarize older turns.
Step 4: Add a system prompt
System instructions go in a top-level system field, not as a message with role: "system":
{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"system": "You are a terse code reviewer. Answer only with the diff and a one-line explanation.",
"messages": [
{ "role": "user", "content": "Review this function..." }
]
}
Step 5: Stream responses for UI use cases
For chat interfaces, streaming avoids making users wait for the full response. Set "stream": true and read the response as server-sent events:
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-5",
max_tokens: 1024,
stream: true,
messages: [{ role: "user", content: "Write a haiku about deployment pipelines." }]
})
});
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 event carries a chunk of the response as it's generated. See the streaming docs for event types and reconnection handling.
Step 6: Use tools for structured actions
Tool use (also called function calling) lets Claude request that your application execute a function — a database lookup, a calculator, an API call — and return the result before continuing. You define tools with a JSON schema:
{
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
],
"messages": [{ "role": "user", "content": "Is it raining in Lisbon?" }]
}
When Claude decides to use a tool, the response contains a tool_use block with the function name and arguments. Your code runs the function, then sends the result back as a tool_result message so Claude can produce a final answer. Full details are in the tools docs.
Step 7: Handle errors and rate limits
Production integrations need to handle:
- 429 rate limit errors — back off and retry with exponential delay
- overloaded_error — Anthropic occasionally returns this during high load; retry after a short wait
- max_tokens truncation — check
stop_reason; if it's"max_tokens", your response was cut off - invalid request errors — usually a malformed message array or missing required field
Log usage.input_tokens and usage.output_tokens on every call. Token counts are how you'll catch runaway costs before they show up on an invoice, and if you're on a team, per-key usage metadata (available in the SubToAPI dashboard) makes it easy to see which feature or teammate is driving spend.
Choosing a model
Anthropic offers multiple Claude models with different speed/cost/capability tradeoffs — lighter models for high-volume simple tasks, larger ones for complex reasoning or long documents. Start with a mid-tier model during development, benchmark against your actual prompts, and only move to the most expensive model if quality genuinely requires it. Pricing and plan comparisons are on the pricing page.
Getting started faster
If you want a working integration in minutes rather than setting up console billing and key rotation yourself, sign up for a free trial, generate a sub_live_... key, and swap the host in the examples above — the request and response format matches the standard Messages API, so existing code needs minimal changes.
FAQs
Do I need a separate account from Claude.ai to use the API? Yes, in the standard setup. The Anthropic Console (developer API) and Claude.ai (consumer app) are billed separately. SubToAPI is built specifically to bridge that gap by turning existing Claude access into API keys.
What's the difference between the Messages API and streaming? They're the same endpoint (/v1/messages) with stream set to true or false. Streaming returns the response incrementally over server-sent events; non-streaming waits for the full response before returning JSON.
Can I use the Claude API without writing backend code? You still need to make an HTTP request from somewhere — a serverless function, a backend server, or a script — since API keys should never be exposed in client-side JavaScript. A minimal backend proxy or edge function is sufficient for most projects.