Lesson 2.2
SDKs, Authentication and Environment Setup
Installing the official SDKs, how credentials are resolved, which headers raw HTTP needs, and the client options that govern retries, timeouts and alternative platforms.
Before any prompt engineering happens, a request has to reach the API with the right credentials and headers. The exam checks that you know where the API key comes from, what the SDKs do on your behalf, and how to configure a client for production rather than a notebook.
Installing a client
Anthropic publishes official SDKs for Python, TypeScript/JavaScript, Java, Go, Ruby, C# and PHP. The two you will see most:
pip install anthropic
npm install @anthropic-ai/sdk
Both expose the same mental model: construct a client, then call client.messages.create(...). Supporting namespaces follow the REST structure: client.messages.batches, client.messages.count_tokens / countTokens, client.files, client.models.
Where the key comes from
Create keys in the Console under your organisation and, where relevant, a specific workspace. The SDKs resolve credentials automatically from the environment, so the recommended constructor takes no arguments:
import anthropic
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // reads ANTHROPIC_API_KEY
Passing api_key= / apiKey: explicitly is for cases where you inject the key from a secret manager at runtime. Never paste a literal key into source code. The SDKs also honour ANTHROPIC_AUTH_TOKEN for bearer-token auth and ANTHROPIC_BASE_URL for proxies or gateways.
Headers on the wire
If you call the REST API directly you must set three headers:
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-opus-5-5","max_tokens":256,
"messages":[{"role":"user","content":"ping"}]}'
anthropic-version pins the API behaviour you coded against. Beta features are opted into with an anthropic-beta header carrying one or more comma-separated flags; in the SDKs the same thing is betas=[...] on client.beta.messages.create(...). An unknown or unavailable beta flag returns a 400.
Client options that matter in production
| Option | Default | Notes |
|---|---|---|
max_retries / maxRetries | 2 | Automatic retries with backoff on 408, 409, 429, 5xx and connection errors |
timeout | 10 minutes | Python and Ruby use seconds; TypeScript uses milliseconds |
base_url | api.anthropic.com | Point at a gateway or a cloud platform endpoint |
default_headers | none | Add tracing or beta headers globally |
client = anthropic.Anthropic(max_retries=4, timeout=60.0)
resp = client.with_options(timeout=15.0).messages.create(...) # per-request override
const client = new Anthropic({ maxRetries: 4, timeout: 60_000 });
await client.messages.create({ ... }, { timeout: 15_000 });
Because retries are automatic, the wall-clock time of a call can reach timeout × (max_retries + 1). Long outputs should stream rather than rely on a huge timeout.
Async and streaming clients
Python ships AsyncAnthropic with identical method names you await. TypeScript is promise-based throughout. Both provide client.messages.stream(...) as a helper that yields events and accumulates the final message, covered in lesson 2-4.
Typed errors
Every SDK raises typed exceptions that map to HTTP status codes, so you branch on class rather than parsing strings:
try:
client.messages.create(...)
except anthropic.AuthenticationError: # 401: bad or missing key
...
except anthropic.RateLimitError as e: # 429: inspect e.response.headers["retry-after"]
...
except anthropic.APIStatusError as e: # anything else with a status_code
...
In TypeScript the equivalents are Anthropic.AuthenticationError, Anthropic.RateLimitError and Anthropic.APIError with a status field.
Alternative platforms
Claude is also available through Amazon Bedrock, Google Cloud Vertex AI and Microsoft Foundry. Each has a dedicated client class (for example AnthropicBedrock / AnthropicVertex in Python, @anthropic-ai/bedrock-sdk and @anthropic-ai/vertex-sdk in TypeScript) that uses the platform's own identity system instead of an Anthropic API key, exposes the same messages.create surface, and may use platform-specific model identifiers. Feature availability and pricing differ by platform; check the platform pages on docs.anthropic.com before assuming parity.
Environment hygiene checklist
- Store the key in an environment variable or secret manager; load it with a zero-argument client.
- Add
.envfiles to.gitignoreand scan commits for leaked keys. - Use separate keys (and ideally workspaces) for development, staging and production so you can rotate and set limits independently.
- Set an explicit
timeoutandmax_retriesthat match your service's latency budget. - Pin the SDK version in your lockfile and read the changelog before upgrading across a major version.
Exam focus
- The SDKs read
ANTHROPIC_API_KEYautomatically; a zero-argument constructor is the recommended pattern. - Raw HTTP requires
x-api-key,anthropic-versionandcontent-typeheaders; beta features useanthropic-beta. max_retriesdefaults to 2 and covers 429 and 5xx errors with exponential backoff.- Timeout units differ: seconds in Python, milliseconds in TypeScript.
- Bedrock, Vertex AI and Foundry use platform credentials and dedicated client classes, not an Anthropic key.
- Typed exception classes (
AuthenticationError,RateLimitError,APIStatusError) are the correct way to handle failures.
Check yourself
5 questions
1.A TypeScript file contains: import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic(); No apiKey argument is passed. Where does the SDK get credentials by default?
2.A Python service contains: client = anthropic.Anthropic(api_key="sk-ant-api03-Q1w2e3...") and this file is committed to the repository. What is the recommended fix?
3.A request fails with: {"type": "error", "error": {"type": "not_found_error", "message": "model: claude-sonnet-4.6"}} What is the most likely cause and the quickest way to resolve it?
4.During a traffic spike a developer sees in their logs that a call to client.messages.create() succeeded even though the API briefly returned a 529 overloaded_error. They wrote no retry logic. What explains this?
5.A Node developer configures: const client = new Anthropic({ timeout: 30 }); Every request now fails with a timeout error almost instantly. Why?
