The Anthropic client is the primary interface for interacting with the Anthropic API. It handles authentication, configuration, and provides access to all API resource endpoints.
import Anthropic from '@anthropic-ai/sdk';CommonJS:
const Anthropic = require('@anthropic-ai/sdk');class Anthropic extends BaseAnthropic {
constructor(options?: ClientOptions);
// Resource endpoints
completions: Completions;
messages: Messages;
models: Models;
beta: Beta;
// Instance methods
withOptions(options: Partial<ClientOptions>): this;
// Static constants
static HUMAN_PROMPT: string;
static AI_PROMPT: string;
static DEFAULT_TIMEOUT: number;
}Complete configuration options for the Anthropic client.
interface ClientOptions {
/**
* API key for authentication.
* Can be a static string or async function for dynamic credentials.
* Defaults to process.env['ANTHROPIC_API_KEY']
*/
apiKey?: string | ApiKeySetter | null;
/**
* Alternative authentication token.
* Defaults to process.env['ANTHROPIC_AUTH_TOKEN']
*/
authToken?: string | null;
/**
* Custom API base URL.
* Defaults to process.env['ANTHROPIC_BASE_URL'] or 'https://api.anthropic.com'
*/
baseURL?: string | null;
/**
* Request timeout in milliseconds.
* Default: 600000 (10 minutes)
*
* For non-streaming requests with large max_tokens, timeout is dynamically
* calculated: min(10 minutes, (60 * max_tokens) / 128000 hours)
*/
timeout?: number;
/**
* Maximum number of retry attempts for failed requests.
* Default: 2
*
* Retries occur for:
* - Network errors (connection failures)
* - 408 Request Timeout
* - 409 Conflict
* - 429 Rate Limit
* - 5xx Server errors
*/
maxRetries?: number;
/**
* Additional fetch options passed to all requests.
* Can include headers, signal, credentials, etc.
*/
fetchOptions?: RequestInit;
/**
* Custom fetch implementation.
* If not provided, uses global fetch.
*/
fetch?: typeof fetch;
/**
* Default headers included with every request.
* Can be overridden per-request by setting header to null.
*/
defaultHeaders?: HeadersLike;
/**
* Default query parameters included with every request.
* Can be removed per-request by setting param to undefined.
*/
defaultQuery?: Record<string, string | undefined>;
/**
* Enable client-side usage (browser environments).
* Default: false
*
* WARNING: Enabling this in browsers exposes API credentials.
* Only use with appropriate security mitigations.
*/
dangerouslyAllowBrowser?: boolean;
/**
* Logging level for SDK operations.
* Defaults to process.env['ANTHROPIC_LOG'] or 'warn'
*/
logLevel?: LogLevel;
/**
* Custom logger instance.
* Defaults to globalThis.console
*/
logger?: Logger;
}// Dynamic API key function
type ApiKeySetter = () => Promise<string>;
// Log levels (most to least verbose)
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'off';
// Logger interface (compatible with console, pino, winston, etc.)
interface Logger {
debug(...args: any[]): void;
info(...args: any[]): void;
warn(...args: any[]): void;
error(...args: any[]): void;
}
// Header types
type HeadersLike = Record<string, string | string[] | undefined> | Headers;Uses environment variables for authentication:
const client = new Anthropic();
// Uses process.env.ANTHROPIC_API_KEYconst client = new Anthropic({
apiKey: 'your-api-key-here',
});For rotating credentials or runtime key fetching:
const client = new Anthropic({
apiKey: async () => {
// Fetch key from secure storage
const key = await fetchKeyFromVault();
return key;
},
});The function is called before each request, allowing for:
const client = new Anthropic({
timeout: 30 * 1000, // 30 seconds
});const client = new Anthropic({
maxRetries: 0,
});For proxies or custom endpoints:
const client = new Anthropic({
baseURL: 'https://proxy.example.com/anthropic',
});Add headers to all requests:
const client = new Anthropic({
defaultHeaders: {
'X-Custom-Header': 'value',
'User-Agent': 'MyApp/1.0',
},
});const client = new Anthropic({
apiKey: 'your-api-key',
dangerouslyAllowBrowser: true, // SECURITY WARNING
});WARNING: This exposes your API key in client-side code. Only use for:
// Set log level via environment
// export ANTHROPIC_LOG=debug
// Or via options
const client = new Anthropic({
logLevel: 'debug', // Shows all HTTP requests/responses
});
// Custom logger (pino example)
import pino from 'pino';
const logger = pino();
const client = new Anthropic({
logger: logger.child({ component: 'anthropic-sdk' }),
logLevel: 'debug',
});Log levels:
debug: All requests/responses with headers and bodies (may expose sensitive data)info: General informational messageswarn: Warnings and errors (default)error: Only errorsoff: No loggingFor Node.js proxies or custom network handling:
// Node.js with undici proxy
import * as undici from 'undici';
const proxyAgent = new undici.ProxyAgent('http://proxy.example.com:8080');
const client = new Anthropic({
fetchOptions: {
dispatcher: proxyAgent, // undici-specific
},
});
// Bun with built-in proxy support
const client = new Anthropic({
fetchOptions: {
proxy: 'http://proxy.example.com:8080',
},
});
// Deno with HTTP client
const httpClient = Deno.createHttpClient({
proxy: { url: 'http://proxy.example.com:8080' },
});
const client = new Anthropic({
fetchOptions: {
client: httpClient,
},
});
// Custom fetch function
const client = new Anthropic({
fetch: async (url, init) => {
// Add custom logic
console.log('Fetching:', url);
return fetch(url, init);
},
});Create a new client with modified options while preserving existing configuration:
withOptions(options: Partial<ClientOptions>): Anthropic;Example:
const originalClient = new Anthropic({
apiKey: 'key-1',
timeout: 60000,
});
// Create new client with different timeout
const timeoutClient = originalClient.withOptions({
timeout: 120000,
});
// Create new client with different API key
const secondClient = originalClient.withOptions({
apiKey: 'key-2',
});
// Original client unchanged
console.log(originalClient.timeout); // 60000
console.log(timeoutClient.timeout); // 120000Use cases:
The client provides access to all API resources:
client.messages // Messages API (primary conversational interface)
client.completions // Legacy completions API
client.models // Model information
client.beta // Beta features namespaceconst message = await client.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
});See messages.md
const models = await client.models.list();
const model = await client.models.retrieve('claude-sonnet-4-5-20250929');See models.md
const message = await client.beta.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
betas: ['code-execution-2025-05-22'],
tools: [{ name: 'code_execution', type: 'code_execution_20250522' }],
});See beta-features.md
Legacy prompt delimiters for the old text completions API:
Anthropic.HUMAN_PROMPT: string // '\n\nHuman:'
Anthropic.AI_PROMPT: string // '\n\nAssistant:'
Anthropic.DEFAULT_TIMEOUT: number // 600000 (10 minutes)Example:
import Anthropic from '@anthropic-ai/sdk';
const prompt = `${Anthropic.HUMAN_PROMPT} What is 2+2?${Anthropic.AI_PROMPT}`;
// Used with legacy completions API
const completion = await client.completions.create({
model: 'claude-2.1',
prompt,
max_tokens_to_sample: 100,
});Note: These are for the legacy completions API. The modern Messages API uses structured message objects instead.
Override client configuration for individual requests:
interface RequestOptions {
timeout?: number;
maxRetries?: number;
headers?: HeadersLike;
query?: Record<string, string | undefined>;
signal?: AbortSignal;
idempotencyKey?: string;
}Example:
// Shorter timeout for this request
const message = await client.messages.create(
{
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Quick question' }],
},
{
timeout: 10000, // 10 seconds
maxRetries: 0,
headers: {
'X-Request-ID': 'custom-id',
},
}
);
// Manual cancellation with AbortController
const controller = new AbortController();
const promise = client.messages.create(
{ /* params */ },
{ signal: controller.signal }
);
// Cancel request after 5 seconds
setTimeout(() => controller.abort(), 5000);The SDK reads configuration from environment variables:
# Authentication
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_AUTH_TOKEN=...
# Configuration
ANTHROPIC_BASE_URL=https://custom-endpoint.example.com
ANTHROPIC_LOG=debug
# Runtime-specific variables are also supported
NODE_ENV=productionPriority order:
The client will throw errors when:
// No API key provided
try {
const client = new Anthropic(); // No apiKey, env var not set
} catch (error) {
// AnthropicError: Missing API Key
}
// Browser usage without explicit permission
try {
const client = new Anthropic({ apiKey: 'key' }); // In browser
} catch (error) {
// AnthropicError: Browser usage not allowed
}
// Invalid configuration
try {
const client = new Anthropic({
maxRetries: -1, // Invalid
});
} catch (error) {
// Configuration validation error
}See errors.md for complete error handling documentation.
The client is fully typed with TypeScript:
import Anthropic from '@anthropic-ai/sdk';
// All types are exported
import type {
ClientOptions,
Message,
MessageParam,
MessageCreateParams,
} from '@anthropic-ai/sdk';
const client: Anthropic = new Anthropic();
// Type inference works automatically
const message = await client.messages.create({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Hello' }],
});
// message is typed as Anthropic.Message
console.log(message.content[0].type); // TypeScript knows the shapeThe SDK supports multiple JavaScript runtimes:
// Node.js 20+ (LTS or later)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();// Deno v1.28.0+
import Anthropic from 'npm:@anthropic-ai/sdk';
const client = new Anthropic();// Bun 1.0+
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();// Cloudflare Workers
export default {
async fetch(request) {
const client = new Anthropic({
apiKey: env.ANTHROPIC_API_KEY,
});
// ...
},
};
// Vercel Edge Functions
import Anthropic from '@anthropic-ai/sdk';
export const config = { runtime: 'edge' };
export default async function handler(req) {
const client = new Anthropic();
// ...
}// NOT recommended - exposes API key
const client = new Anthropic({
apiKey: 'your-key', // Will be visible in browser
dangerouslyAllowBrowser: true,
});For production browser apps: Use a backend proxy to keep credentials secure.
All responses include a request ID for debugging:
const message = await client.messages.create({ /* ... */ });
console.log(message._request_id); // 'req_018EeWyXxfu5pfWkrYcMdjWG'
// Or access via withResponse()
const { data, response, request_id } = await client.messages
.create({ /* ... */ })
.withResponse();
console.log(request_id); // Same ID
console.log(response.headers.get('request-id'));Access underlying HTTP response:
// Get response before body is parsed
const response = await client.messages.create({ /* ... */ }).asResponse();
console.log(response.status);
console.log(response.headers.get('x-ratelimit-remaining'));
// Get both parsed data and response
const { data, response, request_id } = await client.messages
.create({ /* ... */ })
.withResponse();
console.log(data.content); // Parsed message
console.log(response.status); // 200For long-running connections, TCP keep-alive is automatically configured when supported by the fetch implementation. This reduces idle connection timeouts on some networks.
Override via custom fetch options if needed.
// ✅ Good: Use environment variables
const client = new Anthropic(); // Reads from ANTHROPIC_API_KEY
// ✅ Good: Use credential manager
const client = new Anthropic({
apiKey: async () => await credentialManager.getKey(),
});
// ❌ Bad: Hardcode keys
const client = new Anthropic({
apiKey: 'sk-ant-...', // Don't commit this!
});// ✅ Good: Set reasonable timeouts
const client = new Anthropic({
timeout: 120000, // 2 minutes for typical requests
});
// ✅ Good: Use streaming for long operations
const stream = await client.messages.stream({
model: 'claude-sonnet-4-5-20250929',
max_tokens: 4000,
messages: [{ role: 'user', content: 'Long task...' }],
});
// ❌ Bad: Very short timeout without streaming
const client = new Anthropic({
timeout: 5000, // Too short for API processing
});// ✅ Good: Handle specific errors
try {
const message = await client.messages.create({ /* ... */ });
} catch (error) {
if (error instanceof Anthropic.APIError) {
console.error('API error:', error.status, error.message);
console.error('Request ID:', error.requestID);
} else if (error instanceof Anthropic.APIConnectionError) {
console.error('Network error:', error.message);
} else {
throw error;
}
}// ✅ Good: Reuse client instance
const client = new Anthropic();
async function processMany(inputs) {
return Promise.all(
inputs.map(input =>
client.messages.create({ /* ... */ })
)
);
}
// ❌ Bad: Create new client per request
async function processBad(input) {
const client = new Anthropic(); // Wasteful
return client.messages.create({ /* ... */ });
}