Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Production-ready Anthropic SDK patterns — client config, retries, timeouts, Use when working with sdk-patterns patterns. error handling, TypeScript types, and async patterns. Trigger with "anthropic sdk", "claude client setup", "anthropic typescript", "anthropic python patterns".
.claude/skills/jeremylongshore-clade-sdk-patterns/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 27% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 120% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 51% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 91% | 0% |
Production patterns for the @claude-ai/sdk (TypeScript) and anthropic (Python) SDKs.
typescriptimport Anthropic from '@claude-ai/sdk'; // Default — reads ANTHROPIC_API_KEY from env const client = new Anthropic(); // Full configuration const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY, // default: env var maxRetries: 3, // default: 2 timeout: 60_000, // default: 10 minutes baseURL: 'https://api.anthropic.com', // override for proxies defaultHeaders: { // custom headers 'claude-beta': 'prompt-caching-2024-07-31', }, });
pythonimport anthropic # Sync client client = anthropic.Anthropic() # Async client client = anthropic.AsyncAnthropic() # Full configuration client = anthropic.Anthropic( api_key=os.environ["ANTHROPIC_API_KEY"], max_retries=3, timeout=60.0, base_url="https://api.anthropic.com", default_headers={"claude-beta": "prompt-caching-2024-07-31"}, )
typescriptimport Anthropic from '@claude-ai/sdk'; try { const message = await client.messages.create({ ... }); } catch (err) { if (err instanceof Anthropic.AuthenticationError) { // 401 — bad API key } else if (err instanceof Anthropic.RateLimitError) { // 429 — back off and retry } else if (err instanceof Anthropic.APIError) { // All other API errors console.error(err.status, err.error?.type, err.message); } else if (err instanceof Anthropic.APIConnectionError) { // Network failure — DNS, timeout, etc. } }
pythontry: message = client.messages.create(...) except anthropic.AuthenticationError: ... # 401 except anthropic.RateLimitError: ... # 429 except anthropic.APIStatusError as e: print(e.status_code, e.message) except anthropic.APIConnectionError: ... # network failure
typescriptconst stream = client.messages.stream({ model: 'claude-sonnet-4-20250514', max_tokens: 2048, messages, }); stream.on('text', (text) => process.stdout.write(text)); stream.on('error', (err) => console.error('Stream error:', err)); stream.on('end', () => console.log('\nDone')); const finalMessage = await stream.finalMessage();
typescriptconst stream = await client.messages.create({ model: 'claude-sonnet-4-20250514', max_tokens: 2048, messages, stream: true, }); for await (const event of stream) { if (event.type === 'content_block_delta') { process.stdout.write(event.delta.text || ''); } }
pythonwith client.messages.stream( model="claude-sonnet-4-20250514", max_tokens=2048, messages=messages, ) as stream: for text in stream.text_stream: print(text, end="", flush=True) message = stream.get_final_message()
typescriptimport Anthropic from '@claude-ai/sdk'; // Message types type Message = Anthropic.Message; type MessageParam = Anthropic.MessageParam; type ContentBlock = Anthropic.ContentBlock; type TextBlock = Anthropic.TextBlock; type ToolUseBlock = Anthropic.ToolUseBlock; // Tool types type Tool = Anthropic.Tool; type ToolResultBlockParam = Anthropic.ToolResultBlockParam; // Request/response type MessageCreateParams = Anthropic.MessageCreateParams;
typescriptconst message = await client.messages.create({ model: 'claude-sonnet-4-20250514', max_tokens: 1024, system: [ { type: 'text', text: longSystemPrompt, // 1024+ tokens to be cacheable cache_control: { type: 'ephemeral' }, }, ], messages: [{ role: 'user', content: userQuestion }], }, { headers: { 'claude-beta': 'prompt-caching-2024-07-31' }, }); // Cache hit: 90% cheaper on input tokens // message.usage.cache_creation_input_tokens / cache_read_input_tokens
typescript// Submit up to 10,000 messages as a batch (50% cheaper, 24h SLA) const batch = await client.messages.batches.create({ requests: items.map((item, i) => ({ custom_id: `item-${i}`, params: { model: 'claude-sonnet-4-20250514', max_tokens: 1024, messages: [{ role: 'user', content: item.prompt }], }, })), }); // Poll for completion let status = await client.messages.batches.retrieve(batch.id); while (status.processing_status !== 'ended') { await new Promise(r => setTimeout(r, 30000)); status = await client.messages.batches.retrieve(batch.id); }
See Client Configuration, Error Handling, Streaming Patterns, TypeScript Types, Prompt Caching, and Message Batches sections above for complete code examples.
See clade-rate-limits for throughput optimization.
clade-install-auth| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 14,635 | 10,505 | -28% | 1 | 1 | 0% | 2,993 | 3,803 | +27% | 0 | 0 | — |
case-02 | fail→fail | 19,403 | 12,708 | -35% | 1 | 1 | 0% | 3,877 | 4,398 | +13% | 0 | 0 | — |
case-03 | fail→pass | 6,714 | 4,481 | -33% | 1 | 1 | 0% | 1,166 | 2,560 | +120% | 0 | 0 | — |
case-04 | pass→pass | 5,612 | 3,719 | -34% | 1 | 1 | 0% | 1,154 | 2,471 | +114% | 0 | 0 | — |
case-22 | pass→pass | 11,402 | 9,672 | -15% | 1 | 1 | 0% | 2,191 | 3,627 | +66% | 0 | 0 | — |
case-05 | pass→pass | 11,353 | 10,936 | -4% | 1 | 1 | 0% | 2,239 | 3,721 | +66% | 0 | 0 | — |
case-06 | pass→pass | 10,429 | 5,902 | -43% | 1 | 1 | 0% | 2,055 | 3,031 | +47% | 0 | 0 | — |
case-07 | pass→pass | 10,193 | 8,220 | -19% | 1 | 1 | 0% | 1,863 | 3,343 | +79% | 0 | 0 | — |
case-08 | pass→pass | 11,301 | 5,578 | -51% | 1 | 1 | 0% | 2,050 | 2,874 | +40% | 0 | 0 | — |
case-09 | pass→pass | 8,210 | 6,098 | -26% | 1 | 1 | 0% | 1,687 | 2,888 | +71% | 0 | 0 | — |
case-10 | fail→fail | 11,586 | 5,320 | -54% | 1 | 1 | 0% | 2,131 | 2,741 | +29% | 0 | 0 | — |
case-11 | fail→pass | 10,319 | 8,151 | -21% | 1 | 1 | 0% | 2,170 | 3,271 | +51% | 0 | 0 | — |
case-12 | fail→pass | 14,876 | 8,704 | -41% | 1 | 1 | 0% | 2,970 | 3,368 | +13% | 0 | 0 | — |
case-13 | fail→pass | 8,151 | 5,754 | -29% | 1 | 1 | 0% | 1,493 | 2,857 | +91% | 0 | 0 | — |
case-14 | fail→fail | 3,202 | 2,401 | -25% | 1 | 1 | 0% | 515 | 2,080 | +304% | 0 | 0 | — |
case-15 | pass→pass | 10,684 | 4,341 | -59% | 1 | 1 | 0% | 2,092 | 2,500 | +20% | 0 | 0 | — |
case-16 | pass→pass | 5,396 | 3,114 | -42% | 1 | 1 | 0% | 965 | 2,348 | +143% | 0 | 0 | — |
case-17 | pass→pass | 6,052 | 3,103 | -49% | 1 | 1 | 0% | 1,235 | 2,182 | +77% | 0 | 0 | — |
case-18 | pass→pass | 6,681 | 3,145 | -53% | 1 | 1 | 0% | 1,291 | 2,330 | +80% | 0 | 0 | — |
case-19 | pass→pass | 3,666 | 2,810 | -23% | 1 | 1 | 0% | 601 | 2,117 | +252% | 0 | 0 | — |
case-20 | fail→pass | 7,495 | 2,885 | -62% | 1 | 1 | 0% | 1,451 | 2,251 | +55% | 0 | 0 | — |
case-21 | pass→pass | 16,120 | 13,554 | -16% | 1 | 1 | 0% | 3,427 | 4,661 | +36% | 0 | 0 | — |
case-23 | pass→pass | 12,001 | 8,583 | -28% | 1 | 1 | 0% | 1,902 | 3,791 | +99% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +26 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.