Fictional shop — Claude API triage workshop.

Workshop · the Messages API

The Messages API, in the open

Every feature of Claude's API is an option on one endpoint, POST /v1/messages. Set the options, watch the exact request leave, see what can and cannot be observed before the first token, then read the answer three ways: the raw bytes, the content blocks they build, and the message they add up to. Nothing here is simulated. Live runs go through this site's server to the real API, and recorded runs are saved copies of live ones.

Start from

Watch for: One text block. Watch message_start carry the input tokens before a word is written, then text_delta frames, then message_delta with the final output count.

1 · Compose

Model and limits
Prompt
messagesmessages
messages[0]
Thinking and effort
Tools
Caching
Output and transport

What the API will say

Omitted thinking on Opus 5 means adaptive: it may think before answering.

2 · On the wire

POST /v1/messages HTTP/1.1

host: api.anthropic.com
x-api-key: sk-ant-…•••• (added on the server)
anthropic-version: 2023-06-01
content-type: application/json
accept: text/event-stream
content-length: 219

Draft body: hover an option to find it

{
"model": "claude-opus-5",
"max_tokens": 1024,
"stream": true,
"messages": [
{
"role": "user",
"content": "In two sentences: what does a three-layer shell jacket do that a two-layer one doesn't?"
}
],
"output_config": {
"effort": "low"
}
}

Send the request, or replay a recorded run, and everything below fills in as the bytes arrive.

3 · What happened between here and the model

Nothing sent yet.

4 · What came back

The stream appears here.

Four things to take from this page

The API is stateless.

Turn 2 carries turn 1 in messages. Nothing is remembered server-side except a cache, and a cache only matches a byte-identical prefix.

Usage arrives first.

message_start reports input and cache tokens before a word is written. That is how a stream cut off halfway can still be billed correctly.

Parse at the block's end.

Tool input streams as JSON fragments that do not parse until content_block_stop. Accumulate, then parse once.

A 400 is documentation.

It arrives before generation, costs nothing and names the rule. Streaming errors are different: they arrive after a 200, as an error event. Lab 4 covers both.