Your First Claude API Call in Python
To call Claude from Python, install the anthropic package, put your API key in the ANTHROPIC_API_KEY environment variable, and call client.messages.create() with a model, a token limit and a list of messages. This post takes you from an empty folder to a working script.
Step 1: Create an account and key
Sign up on the Anthropic Console, add billing or credits, and create an API key. Copy it once, because the console will not show it again. Treat it like a password.
Step 2: Install the SDK
Use a virtual environment so the dependency stays local to the project.
python -m venv .venv
source .venv/bin/activate
pip install anthropic
export ANTHROPIC_API_KEY="your-key-here"
On Windows PowerShell, activate with .venv\Scripts\Activate.ps1 and set the variable with $env:ANTHROPIC_API_KEY = "your-key-here".
Step 3: Send a message
import anthropic
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY from the environment
message = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1000,
messages=[
{"role": "user", "content": "Give me three tips for writing readable Python."}
],
)
print(message.content[0].text)
print("stop reason:", message.stop_reason)
print("tokens in/out:", message.usage.input_tokens, message.usage.output_tokens)
Run it with python first_call.py. You should see three tips, then stop reason: end_turn, then two token counts. If you see max_tokens as the stop reason, the answer was cut off and you need a larger limit.
What each part does
anthropic.Anthropic()creates a client. With no arguments it finds the key in the environment, which keeps secrets out of your source code.modelselects the model. Current IDs includeclaude-opus-5-5,claude-sonnet-5-5andclaude-haiku-5-5.max_tokensis required. It caps how much the model may generate in this call.messagesis the conversation. Here it holds a single user turn.
Why content is a list
message.content is a list of blocks, not a string. A plain answer has one text block, so content[0].text works for this example. When you later use thinking or tools, the list can hold several block types. A safer way to collect all the text is to filter by type.
text = "".join(block.text for block in message.content if block.type == "text")
print(text)
Choosing a model for your first experiments
For learning, claude-haiku-5-5 is the cheapest and fastest option, which keeps early mistakes inexpensive. claude-sonnet-5-5 is a strong everyday choice for real features. claude-opus-5-5 is the most capable and suits hard reasoning and complex tasks. You can change the model string at any time without touching the rest of your code, so start small and move up only when the answers are not good enough.
Experiment with the request
Change one thing at a time and watch what happens. Lower max_tokens to 20 and notice the truncation. Add a system argument such as "Reply as a pirate" and see how the tone changes. Ask the same question twice and compare the answers: they will usually be similar but not identical, because the model samples from a probability distribution. This habit of small controlled experiments is the fastest way to build intuition for prompting.
Keeping the key out of trouble
If the client cannot find a key, it raises an error as soon as you make a call, which is a useful early warning. Never print the key, never commit a .env file, and add it to .gitignore. If you suspect a key leaked, revoke it in the console immediately and create a new one. Revoking is free and takes seconds, while a leaked key can run up a large bill.
Handling the first errors
Three failures are common on day one. A missing or wrong key raises anthropic.AuthenticationError. A model name typo or a bad parameter raises anthropic.BadRequestError or anthropic.NotFoundError. Too many requests raises anthropic.RateLimitError. Catch the specific class you care about, and let the others surface.
try:
message = client.messages.create(
model="claude-haiku-5-5",
max_tokens=300,
messages=[{"role": "user", "content": "Hello!"}],
)
except anthropic.AuthenticationError:
print("Check your ANTHROPIC_API_KEY.")
except anthropic.APIStatusError as e:
print("API error:", e.status_code, e.message)
Checklist
- Key lives in an environment variable, never in code or git.
- You pass
max_tokenson every call. - You read
stop_reasonso truncation is not silent. - You log
usageso you can see what each call costs.
Next, repeat this in TypeScript, then look at every field in the request in detail.
Comments
No comments yet. Have a question or a tip? Be the first to share it.