Anatomy of a Messages API Request

A
Author
26 Oct, 2026 3 min read 0 views

A Messages API request has three required fields: model, max_tokens and messages. Everything else is optional tuning. Knowing what each field does helps you debug unexpected output, control cost and avoid 400 errors.

The full picture

import anthropic

client = anthropic.Anthropic()

message = client.messages.create(
    model="claude-sonnet-5-5",          # which model answers
    max_tokens=800,                      # hard cap on generated tokens
    system="You are a concise technical writer.",  # standing instructions
    messages=[                           # the conversation so far
        {"role": "user", "content": "Describe a hash map."},
    ],
    stop_sequences=["END"],              # optional: stop when this text appears
)
print(message.content[0].text)

model

The model ID is an exact string. A typo returns a not-found error. IDs for the current Claude family are claude-opus-5-5, claude-sonnet-5-5 and claude-haiku-5-5. Bigger models reason better; smaller ones are faster and cheaper. Choose per task, not per project.

max_tokens

This is the maximum number of output tokens for this call. It is a ceiling, not a target. The model does not try to fill it, and it is not aware of the limit while writing. If the limit is reached the answer stops mid-sentence and stop_reason becomes max_tokens. Set it high enough for your longest expected answer, and use a low value for tasks like classification where a few tokens suffice.

messages

A list of turns. Each turn has a role of user or assistant, and content that is either a string or a list of content blocks. The first message must be from the user. Content blocks let you mix text with images or documents in one turn, which later posts cover.

system

Standing instructions that apply to the whole conversation. It is a separate top-level field, not a message with a system role in the list. Put role, tone, rules and output format here. It can be a plain string or a list of text blocks, which you need when you add caching.

Optional fields worth knowing

  • stop_sequences: a list of strings that end generation when produced. The matched text is not included in the output.
  • stream: send true to receive tokens as they are produced. The SDK offers a friendlier client.messages.stream() helper.
  • tools and tool_choice: let the model request function calls. This is covered in the agent topics.
  • thinking and output_config: control reasoning depth and structured output on models that support them.
  • metadata: an optional user identifier you can attach for abuse tracking.

Sampling parameters

Older Claude models accept temperature, top_p and top_k. Some newer models reject non-default values for these and expect you to steer behaviour through the prompt instead. Check the current model documentation before relying on them, and see the post on sampling for how they work.

Choosing values: a practical starting point

Start with the simplest request that could work: a model, a generous max_tokens, a short system string and one user message. Add fields only when you have a reason. Many production bugs come from copying an elaborate configuration without knowing what each part does, so the extra parameters hide the cause of a problem. When something looks wrong, strip the request back to the minimum, confirm it works, and then add the fields back one at a time.

Also log the exact request body for failed calls, with the key removed. A 400 error is almost always fixed by comparing the logged body to the documentation.

What the request does not contain

There is no session ID and no memory. Whatever the model should know must be in system or messages on every call. There is also no separate "assistant prefill" you can count on: newer Claude models reject a request whose last message is an assistant turn, so ask for a format in the prompt or use structured output instead.

Debugging checklist

  1. A 400 error: read the message. It names the field that is invalid.
  2. Cut-off answers: raise max_tokens and check stop_reason.
  3. Wrong tone or format: move rules into system and be explicit.
  4. Model ignores earlier facts: confirm they are actually in the messages you sent.
Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.