Claude API Node.js Example (2026)
Anthropic ships a first-party TypeScript SDK that handles authentication, streaming,
and retry logic. The recipes below take you from npm install to a
working tool-using agent in under 50 lines. Same code works against
api.anthropic.com or any compatible proxy by changing one constructor option.
The minimum is 4 lines: new Anthropic({ apiKey }),
then await client.messages.create({ model, max_tokens, messages }).
Install
npm install @anthropic-ai/sdk
# or
pnpm add @anthropic-ai/sdk
Requires Node.js 18+. The SDK is pure ESM with TypeScript types built in.
1. Basic call
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY!,
// baseURL: "https://tokenprovider.store", // uncomment to use a proxy
});
const msg = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 256,
messages: [{ role: "user", content: "What is the capital of Japan?" }],
});
console.log(msg.content[0].type === "text" ? msg.content[0].text : "");
2. Streaming tokens as they arrive
const stream = client.messages.stream({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a haiku about TypeScript." }],
});
for await (const event of stream) {
if (
event.type === "content_block_delta" &&
event.delta.type === "text_delta"
) {
process.stdout.write(event.delta.text);
}
}
const final = await stream.finalMessage();
console.log("\nUsage:", final.usage);
The SDK also exposes higher-level helpers like stream.on("text", ...) if
you prefer event emitters.
3. Tool use (function calling)
const tools: Anthropic.Tool[] = [{
name: "get_weather",
description: "Get current weather for a city",
input_schema: {
type: "object",
properties: {
city: { type: "string" },
unit: { type: "string", enum: ["c", "f"] },
},
required: ["city"],
},
}];
const result = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 512,
tools,
messages: [{ role: "user", content: "Weather in Tokyo today?" }],
});
const toolBlock = result.content.find(
(b): b is Anthropic.ToolUseBlock => b.type === "tool_use",
);
if (toolBlock) {
console.log("Tool:", toolBlock.name, "Args:", toolBlock.input);
// …call your real weather function, then send a follow-up:
// role: "user", content: [{ type: "tool_result", tool_use_id, content }]
}
4. Vision (image input)
import { readFileSync } from "node:fs";
const imageData = readFileSync("./screenshot.png").toString("base64");
const result = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 512,
messages: [{
role: "user",
content: [
{ type: "image", source: { type: "base64", media_type: "image/png", data: imageData } },
{ type: "text", text: "What does this UI mockup show?" },
],
}],
});
5. Error handling and retries
try {
const msg = await client.messages.create({ /* … */ });
} catch (err) {
if (err instanceof Anthropic.APIError) {
console.error(err.status, err.message);
// err.status: 401 / 429 / 500 etc.
} else {
throw err;
}
}
// SDK already retries idempotent failures up to 2x with backoff.
// Configure: new Anthropic({ apiKey, maxRetries: 3 })
6. Streaming + tools combined
Real agents stream the assistant's reasoning text and detect tool calls as they
appear in the stream. The SDK's stream.on("contentBlock", ...) event fires
for each completed block, so you can process tool calls without buffering the entire
response.
Switching to a proxy
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY!,
baseURL: "https://tokenprovider.store", // only line to change
});
The proxy implements the full Messages API contract — same SDK methods, same response shapes, same streaming events. Use the same key for Claude Code, Cursor, and your scripts.
Same SDK, ~50% off the bill
Switch baseURL and you're on pay-as-you-go. $1 minimum top-up.