It is one HTTP request
Everything you build sits on a single POST. There is no session, no connection held open, no magic. JSON goes out, JSON comes back.
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-sonnet-4-5",
"max_tokens": 300,
"messages": [{"role": "user", "content": "Summarise this email in one line: ..."}]
}'The SDK is a thin wrapper over exactly that request.
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
r = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=300,
messages=[{"role": "user", "content": f"Summarise this email in one line:\n\n{email}"}],
)
print(r.content[0].text)
print(r.usage) # Usage(input_tokens=812, output_tokens=41)
print(r.stop_reason) # 'end_turn' — or 'max_tokens' if it was cut offOther providers use different field names and the same shape: a model id, a list of messages, a cap on output length. Learn one properly and the rest take an hour.
The key is a password with a bill attached
An API key is a credential that spends money. Three rules, and people break all three:
- Read it from an environment variable or a secret store. Never a literal in the source.
- Never ship it to a browser or a mobile app. Anyone can open devtools and read it. If your frontend needs the model, put your own server in between.
- Assume it will leak eventually. Know how to rotate it, and set a spend limit in the provider console today, not after the incident.
The model has no memory
This surprises people more than anything else. The API is stateless. It does not remember your last call. A conversation exists only because you resend the whole thing:
messages = []
messages.append({"role": "user", "content": "My order is late."})
reply = call(messages)
messages.append({"role": "assistant", "content": reply})
messages.append({"role": "user", "content": "How late?"})
reply = call(messages) # the whole transcript goes over the wire againSo turn 40 of a chat costs far more than turn 2. That is not a bug, it is the billing model, and it is why long chats need trimming or summarising.
What you actually pay for
You pay per token, separately for input and output, with output usually several times the price of input. A token is roughly three quarters of an English word.
One detail that matters if your users are not writing English: tokenizers are trained mostly on English text, so the same sentence in Hindi, Telugu, Amharic or Thai can cost two to five times the tokens of its English translation. A cost model built on English test data will be wrong in production in Chennai or Addis Ababa.
Do the arithmetic before you build. Say a support-reply feature sends 1,200 input tokens and gets 300 output tokens back, 5,000 times a day. That is 6M input and 1.5M output tokens daily. At a rate of $3 per million input and $15 per million output, that is $18 + $22.50 = $40.50 a day, about $1,215 a month. Now you know whether this feature is worth building, and you knew before writing it.
Two settings to always pass
max_tokens caps the reply. Without a sane value you can pay for a 4,000-token essay when you wanted a label. A timeout caps the wait. Model calls can take 30 seconds; a request with no timeout will hold a worker until something else gives up.
r = client.messages.create(model=MODEL, max_tokens=64, timeout=20.0, messages=msgs)That is the whole foundation. Everything else in this course is what you put in messages, and what you do with what comes back.
Before you move on