Chapter 03 · 5 min read
Set up and make your first call
Install the SDK, sign in without pasting keys into code, and send the first request.
The examples in this guide use Python and the official Anthropic SDK. The same calls exist in the TypeScript, Java, Go, Ruby, C# and PHP SDKs.
Install
pip install anthropic
Sign in without putting a key in your code
The SDK finds credentials on its own, in this order: the ANTHROPIC_API_KEY environment variable, then ANTHROPIC_AUTH_TOKEN, then a profile saved by the ant command-line tool. For your own machine, signing in once is the cleanest option:
ant auth login
On a server, set ANTHROPIC_API_KEY in the environment (in your service's settings file, never in the repository). Create keys in the Claude Console and give each worker its own key, so you can see its usage and revoke it without touching anything else.
The first request
import anthropic
client = anthropic.Anthropic() # picks up the key or profile automatically
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=16000,
messages=[{"role": "user", "content": "In one sentence: what does a forward deployed engineer do?"}],
)
for block in response.content:
if block.type == "text":
print(block.text)
Three things to notice:
response.contentis a list of blocks, not a string. Text, thinking and tool calls each arrive as their own block, so always checkblock.type.- Do not set
max_tokenstoo low. If the answer hits the limit it stops mid-sentence. Around 16,000 is a sensible default for normal requests; use streaming for very long outputs. - The API keeps no memory between calls. To hold a conversation, send the earlier messages again each time (later chapters show how to keep that cheap).
The same in TypeScript
npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // picks up the key or profile automatically
const response = await client.messages.create({
model: "claude-opus-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: "In one sentence: what does a forward deployed engineer do?" }],
});
for (const block of response.content) {
if (block.type === "text") console.log(block.text);
}
The rest of this guide uses Python. Every feature shown (tools, the tool runner, caching, effort, MCP) works the same way in TypeScript: method names are camelCase (toolRunner), while request fields keep their API names (max_tokens).
Check why it stopped
Every response has a stop_reason. A worker must read it before trusting the content:
stop_reason | Meaning |
|---|---|
end_turn | Finished normally |
tool_use | It wants to call a tool (the loop handles this) |
max_tokens | Cut off by your limit: raise it, or stream |
pause_turn | A long server-side step paused; send the turn back to continue |
refusal | Declined for safety reasons; covered in the guardrails chapter |
Errors
The SDK already retries rate limits (429), server errors and dropped connections twice with back-off. Catch the specific error classes rather than one broad one, so you can tell a retryable problem from a bug in your request:
try:
response = client.messages.create(...)
except anthropic.RateLimitError:
... # slow down, try again later
except anthropic.BadRequestError as e:
... # your request is wrong: log e.message and fix it
except anthropic.APIConnectionError:
... # network problem