Skip to content

Commit b3a2829

Browse files
committed
docs: expand README quickstarts and error handling
1 parent 089fe05 commit b3a2829

File tree

2 files changed

+199
-3
lines changed

2 files changed

+199
-3
lines changed

README.md

Lines changed: 174 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ Full documentation is available at **[platform.claude.com/docs/en/api/sdks/types
1414
npm install @anthropic-ai/sdk
1515
```
1616

17+
### Runtime quickstart
18+
19+
The SDK uses the standard Web Fetch API, so the same package works across common server-side JavaScript runtimes:
20+
21+
| Runtime | Install / import | API key source | Minimal client setup |
22+
| ------------- | ------------------------------------------------------------------------------------ | ----------------------------------- | ------------------------------------------------------------------------------ |
23+
| Node.js | `npm install @anthropic-ai/sdk` + `import Anthropic from '@anthropic-ai/sdk';` | `process.env.ANTHROPIC_API_KEY` | `const client = new Anthropic();` |
24+
| Bun | `bun add @anthropic-ai/sdk` + `import Anthropic from '@anthropic-ai/sdk';` | `process.env.ANTHROPIC_API_KEY` | `const client = new Anthropic();` |
25+
| Deno | `deno add npm:@anthropic-ai/sdk` or `import Anthropic from 'npm:@anthropic-ai/sdk';` | `Deno.env.get('ANTHROPIC_API_KEY')` | `const client = new Anthropic({ apiKey: Deno.env.get('ANTHROPIC_API_KEY') });` |
26+
| Edge runtimes | `npm install @anthropic-ai/sdk` + `import Anthropic from '@anthropic-ai/sdk';` | `env.ANTHROPIC_API_KEY` | `const client = new Anthropic({ apiKey: env.ANTHROPIC_API_KEY });` |
27+
28+
These are all server-side runtimes. In browsers, keep `dangerouslyAllowBrowser` disabled unless you understand the security tradeoffs.
29+
1730
## Getting started
1831

1932
```js
@@ -23,18 +36,176 @@ const client = new Anthropic({
2336
apiKey: process.env['ANTHROPIC_API_KEY'], // This is the default and can be omitted
2437
});
2538

39+
async function main() {
40+
const message = await client.messages.create({
41+
max_tokens: 1024,
42+
messages: [{ role: 'user', content: 'Hello, Claude' }],
43+
model: 'claude-opus-4-6',
44+
});
45+
46+
console.log(message.content);
47+
}
48+
49+
main().catch(console.error);
50+
```
51+
52+
### Tool use examples
53+
54+
If you want runnable tool use examples, start here:
55+
56+
- [Manual tool use round-trip](examples/tools.ts)
57+
- [Streaming tool use events](examples/tools-streaming.ts)
58+
- [Tool runner with Zod helpers](examples/tools-helpers-zod.ts)
59+
- [Tool runner with JSON Schema helpers](examples/tools-helpers-json-schema.ts)
60+
- [Advanced helper with parallel tool use](examples/tools-helpers-advanced.ts)
61+
62+
### Migrating older API patterns
63+
64+
If you're still using the legacy Text Completions API, migrate new work to the Messages API.
65+
66+
| Older pattern | Messages API equivalent |
67+
| ------------------------------------------------------------- | -------------------------------------------------- |
68+
| `client.completions.create({ prompt, max_tokens_to_sample })` | `client.messages.create({ messages, max_tokens })` |
69+
| `prompt: "\n\nHuman: ...\n\nAssistant:"` | `messages: [{ role: 'user', content: '...' }]` |
70+
| A single completion string | `message.content` blocks |
71+
72+
Future models and newer features target the Messages API. For API-pattern changes, see the [Text Completions migration guide](https://docs.claude.com/en/api/migrating-from-text-completions-to-messages). For SDK-level changes, see [MIGRATION.md](MIGRATION.md).
73+
74+
## Webhook verification
75+
76+
If you're receiving Anthropic webhooks, keep the endpoint server-side, read the raw request body, verify it with your webhook secret, and only then parse the JSON. The SDK does not currently provide a webhook verification helper, so use your framework or a small helper that follows the [webhooks docs](https://platform.claude.com/docs/en/api/webhooks).
77+
78+
Before you verify a webhook:
79+
80+
- Store your secret in `ANTHROPIC_WEBHOOK_SECRET`.
81+
- Read the raw body with `request.text()`, not `request.json()`.
82+
- Verify the signature before calling `JSON.parse(body)`.
83+
- Reject the request immediately if verification fails.
84+
85+
```ts
86+
declare function verifyAnthropicWebhook(body: string, headers: Headers, secret: string): boolean;
87+
88+
export async function POST(request: Request) {
89+
const secret = process.env['ANTHROPIC_WEBHOOK_SECRET'];
90+
if (!secret) {
91+
return new Response('Missing webhook secret', { status: 500 });
92+
}
93+
94+
const body = await request.text();
95+
96+
if (!verifyAnthropicWebhook(body, request.headers, secret)) {
97+
return new Response('Invalid signature', { status: 400 });
98+
}
99+
100+
const event = JSON.parse(body);
101+
console.log('Verified event:', event.type);
102+
103+
return new Response('ok');
104+
}
105+
```
106+
107+
## Handling errors
108+
109+
When the SDK cannot connect to the API, or if the API returns a non-success status code, it throws a subclass of `APIError`:
110+
111+
```ts
112+
import Anthropic from '@anthropic-ai/sdk';
113+
114+
const client = new Anthropic();
115+
116+
async function main() {
117+
try {
118+
const message = await client.messages.create({
119+
model: 'claude-opus-4-6',
120+
max_tokens: 1024,
121+
messages: [{ role: 'user', content: 'Hello, Claude' }],
122+
});
123+
124+
console.log(message.content);
125+
} catch (err) {
126+
if (err instanceof Anthropic.APIError) {
127+
console.error(err.requestID);
128+
console.error(err.status); // 400
129+
console.error(err.name); // BadRequestError
130+
console.error(err.type);
131+
console.error(err.headers);
132+
} else {
133+
throw err;
134+
}
135+
}
136+
}
137+
138+
main().catch(console.error);
139+
```
140+
141+
For a runnable version of this pattern, see [examples/errors.ts](examples/errors.ts).
142+
143+
## Request IDs
144+
145+
All object responses in the SDK provide a `_request_id` property from the `request-id` response header so that you can quickly log failing requests and report them back to Anthropic.
146+
147+
```ts
26148
const message = await client.messages.create({
149+
model: 'claude-opus-4-6',
27150
max_tokens: 1024,
28151
messages: [{ role: 'user', content: 'Hello, Claude' }],
29-
model: 'claude-opus-4-6',
30152
});
31153

32-
console.log(message.content);
154+
console.log(message._request_id);
155+
```
156+
157+
You can also access the request ID with `.withResponse()`:
158+
159+
```ts
160+
const { data, request_id } = await client.messages
161+
.create({
162+
model: 'claude-opus-4-6',
163+
max_tokens: 1024,
164+
messages: [{ role: 'user', content: 'Hello, Claude' }],
165+
})
166+
.withResponse();
167+
168+
console.log(data.content);
169+
console.log(request_id);
170+
```
171+
172+
## Retries
173+
174+
Connection errors, 408, 409, 429, and >=500 responses are retried twice by default. You can override that with `maxRetries`:
175+
176+
```ts
177+
const client = new Anthropic({
178+
maxRetries: 0, // default is 2
179+
});
180+
```
181+
182+
## Timeouts
183+
184+
Requests time out after 10 minutes by default. You can configure this with `timeout`:
185+
186+
```ts
187+
const client = new Anthropic({
188+
timeout: 20 * 1000, // 20 seconds
189+
});
33190
```
34191

35192
## Requirements
36193

37-
Node.js 18+
194+
TypeScript >= 4.5 is supported.
195+
196+
The following runtimes are supported:
197+
198+
- Node.js 18 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions.
199+
- Deno v1.28.0 or higher, using `import Anthropic from 'npm:@anthropic-ai/sdk'`.
200+
- Bun 1.0 or later.
201+
- Cloudflare Workers.
202+
- Vercel Edge Runtime.
203+
- Jest 28 or greater with the `"node"` environment (`"jsdom"` is not supported at this time).
204+
- Nitro v2.6 or greater.
205+
206+
Note that React Native is not supported at this time.
207+
208+
If you are interested in other runtime environments, please open or upvote an issue on GitHub.
38209

39210
## Contributing
40211

examples/errors.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env -S npm run tsn -T
2+
3+
import Anthropic from '@anthropic-ai/sdk';
4+
5+
const client = new Anthropic(); // gets API key from environment variable ANTHROPIC_API_KEY
6+
7+
async function main() {
8+
try {
9+
await client.models.retrieve('model-does-not-exist');
10+
} catch (err) {
11+
if (err instanceof Anthropic.APIError) {
12+
console.log('Caught APIError!');
13+
console.log('requestID:', err.requestID);
14+
console.log('status:', err.status);
15+
console.log('name:', err.name);
16+
console.log('type:', err.type);
17+
console.log('message:', err.message);
18+
console.log('headers:', err.headers);
19+
} else {
20+
throw err;
21+
}
22+
}
23+
}
24+
25+
main().catch(console.error);

0 commit comments

Comments
 (0)