The Messages API is the core interface for talking to Claude, and it is one of the few things that stays constant across every deployment surface. The platforms differ in authentication, client class, and sometimes model ID format — but the JSON body you send and the object you get back have the same shape. This article walks through both, field by field.
The request: what you send
A minimal request has three required pieces. model names the model you want — a bare ID like claude-sonnet-5 everywhere except Amazon Bedrock, which prefixes it as anthropic.claude-sonnet-5. messages is the conversation so far: an array of turns, each with a role (user or assistant) and content. max_tokens caps how many tokens the model may generate in this response — and note that when extended or adaptive thinking is active, thinking tokens count toward this same cap, so a low max_tokens can cut a reasoning-heavy answer short.
The common optional fields: system carries instructions that frame the whole conversation (covered in depth in the system prompts article); stop_sequences lets you supply custom strings that end generation early; stream switches the response to server-sent events; tools and tool_choice enable tool use; and thinking plus output_config control reasoning depth and output format.
temperature, top_p, and top_k are rejected with a 400 error at non-default values. Remove them entirely when migrating older code.from anthropic import AnthropicBedrockMantle
client = AnthropicBedrockMantle(aws_region="us-east-1")
response = client.messages.create(
model="anthropic.claude-sonnet-5",
max_tokens=1024,
system="You are a concise assistant for internal IT staff.",
messages=[{"role": "user",
"content": "Summarize our VPN policy in three bullets."}],
)
print(response.content[0].text)
print(response.usage.input_tokens, response.usage.output_tokens)
The response: what comes back
The response is a Message object. Its most important field is content: an array of typed blocks rather than a single string. A simple answer is one text block; a tool call arrives as a tool_use block; reasoning models may include thinking blocks. Your code should iterate the array rather than assume content[0] is text.
stop_reason tells you why generation ended: the normal end-of-turn value, or documented special cases such as tool_use (Claude wants you to run a tool), max_tokens (the cap was hit — the output may be incomplete), refusal (a declined request, still returned with HTTP 200), and on Claude 4.5+ models model_context_window_exceeded when input plus max_tokens overflows the context window. See the stop reasons article for the full treatment.
The usage block is your bill
Every response carries a usage object, and it is worth reading on every call because it is the ground truth for cost. The key fields:
| Field | Meaning |
|---|---|
input_tokens | Prompt tokens processed at full price (after the last cache breakpoint, if caching is used) |
output_tokens | All generated tokens, including thinking — the authoritative output total |
cache_creation_input_tokens | Tokens written to the prompt cache this request |
cache_read_input_tokens | Tokens served from cache at roughly a tenth of the input price |
Total input is the sum of the three input-side fields. On models with thinking, usage.output_tokens_details.thinking_tokens breaks out how much of the output was reasoning.
When things go wrong
Errors come back as JSON with a top-level "type": "error", an error object containing a type and message, and a request_id you should log for support. The request body itself is capped at 32 MB on the Messages API — large documents are better sent by reference where the platform supports it. And if a request will run long, use streaming or batching: official guidance is to avoid non-streaming requests that would exceed roughly ten minutes.
What differs across platforms
Very little, by design. You swap the client class (AnthropicBedrockMantle, AnthropicVertex, AnthropicFoundry, or AnthropicAWS), adjust the model ID format for Bedrock, and authenticate with your cloud's native credentials. The request and response objects described above are the portable part — which is exactly why teams that learn the Messages API once can move workloads between platforms with modest effort.
Where to go next
Follow the field trail: managing the messages array, streaming events, and prompt cache mechanics. Or start from the quickstart if you have not made a first call yet.