Claude API Developer Documentation: Best Examples
If you're searching for "claude api developer documentation best examples," you're probably trying to do one of two things: learn how to structure a Claude API integration correctly, or find reference code you can actually copy into a real project instead of a toy snippet that breaks the moment you add a system prompt or a tool call.
This article covers both. First, what separates good Claude API documentation from mediocre documentation — the patterns worth copying. Second, concrete, working examples for the four things almost every integration needs: a basic message request, streaming, tool use, and error handling. Where relevant, we'll also show how SubToAPI turns your existing Claude access into a standard HTTPS API, which simplifies several of these patterns.
What Makes Claude API Documentation Actually Useful
Most API docs fail in the same three ways: they show a request without showing the response shape, they skip error states entirely, and they never explain what happens across multiple turns of a conversation. Good documentation — and good example code — should always include:
- The full request and response, not just the request
- Realistic error cases, not just the happy path
- Multi-turn context, since almost no real app sends a single message and stops
- Streaming behavior, because most production UIs stream tokens rather than wait for a full response
Keep that checklist in mind as you read any Claude API reference, including this one.
Example 1: A Basic Message Request
The core unit of the Claude API is the "messages" request: a system prompt (optional), a list of role-tagged messages, and a model identifier.
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-3-7-sonnet",
"max_tokens": 1024,
"system": "You are a concise technical assistant.",
"messages": [
{ "role": "user", "content": "Explain idempotency keys in one paragraph." }
]
}'
The response includes the generated text, the stop reason, and token usage metadata:
{
"id": "msg_01A...",
"model": "claude-3-7-sonnet",
"role": "assistant",
"content": [
{ "type": "text", "text": "An idempotency key is..." }
],
"stop_reason": "end_turn",
"usage": { "input_tokens": 24, "output_tokens": 112 }
}
Good documentation always shows usage — it's what you need for cost tracking, rate-limit planning, and billing attribution per customer. The SubToAPI docs show the full response schema with every field explained, not just the text content.
Example 2: Streaming Responses
Streaming is where a lot of documentation gets thin, because it requires showing how to parse server-sent events, not just a single JSON blob.
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-3-7-sonnet",
max_tokens: 512,
stream: true,
messages: [{ role: "user", content: "Write a haiku about caching." }]
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
for (const line of chunk.split("\n")) {
if (line.startsWith("data:")) {
const payload = line.replace("data:", "").trim();
if (payload === "[DONE]") continue;
const event = JSON.parse(payload);
if (event.type === "content_block_delta") {
process.stdout.write(event.delta.text);
}
}
}
}
This is a pattern you'll reuse constantly: open a reader, decode chunks, split on newlines, filter for content_block_delta events. Full event types are documented at /docs/streaming.
Example 3: Tool Use (Function Calling)
Tool use examples in documentation are often incomplete — they show the model requesting a tool call but not the follow-up request that sends the result back. Both halves matter.
{
"model": "claude-3-7-sonnet",
"max_tokens": 1024,
"tools": [
{
"name": "get_order_status",
"description": "Look up the status of an order by ID",
"input_schema": {
"type": "object",
"properties": { "order_id": { "type": "string" } },
"required": ["order_id"]
}
}
],
"messages": [
{ "role": "user", "content": "What's the status of order 4521?" }
]
}
Claude responds with a tool_use block containing the tool name and structured input. Your application runs the actual lookup, then sends a second request with a tool_result message appended to the conversation history so Claude can finish answering. Documentation that only shows step one — the tool request — leaves developers to reverse-engineer step two. Full round-trip examples are in /docs/tools.
Example 4: Error Handling Worth Copying
The best example code treats errors as first-class, not an afterthought:
try {
const res = await fetch(url, options);
if (!res.ok) {
const err = await res.json();
if (res.status === 429) {
// back off and retry
} else if (res.status === 401) {
throw new Error("Invalid or expired API key");
} else {
throw new Error(`API error ${res.status}: ${err.message}`);
}
}
return await res.json();
} catch (e) {
console.error("Request failed:", e.message);
throw e;
}
Status codes to handle explicitly in any Claude integration: 400 (malformed request), 401 (auth failure), 429 (rate limit), and 5xx (upstream failure, usually retryable with backoff).
Where SubToAPI Fits
If you already have Claude access through a subscription and want a standard API key instead of juggling session tokens, SubToAPI issues sub_live_... keys that work with the exact request/response shapes shown above — streaming, tool use, and usage metadata included. You also get a dashboard for team seats and per-key usage, which is useful once you move past solo experimentation. Start with the quickstart, check pricing for Solo, Team, and Scale plans, or sign up for a free trial.
FAQs
What's the fastest way to test Claude API examples without writing a backend? Use curl against the messages endpoint directly from your terminal. It's the quickest way to confirm request shape, headers, and response fields before wiring up application code.
Do I need to handle streaming and non-streaming differently in my code? Yes. Non-streaming requests return one JSON object; streaming requests return server-sent events you must parse incrementally. Most production chat UIs use streaming for perceived responsiveness.
Why do tool-use examples need two API calls? The first call gets Claude's tool request; your code executes the actual function; the second call sends the result back so Claude can produce a final answer using real data instead of guessing.