The JSON Payload, Live
Two pages ago Milo turned his laptop around and Tessa saw a block of labelled text she could not yet read. She can read it now, and she has been able to since Chapter 5 — she just did not know that was what she was learning.
The body of the request is JSON: labelled data, curly braces around one thing, square brackets around a list, a label in quotes then a colon then its value. That page called itself the on-ramp. This is the road.
One honest note before the first block. Providers do not all spell these labels identically — one calls a field by one name, another by a slightly different one — so the exact spellings on this page are neutral stand-ins, and anywhere a provider's own name would go you will see an obvious placeholder like model-name-here. Placement varies a little too: something one provider carries inside the list, as drawn here, another hands over in a field of its own beside it. The shape is what transfers, and the shape is the same everywhere: which model, the conversation as a list, some settings, and a reply with a receipt attached.
The Request Body, Annotated
Here is a real turn of Tessa's welcome-email conversation, as it left her browser.
{
"model": "model-name-here",
"messages": [
{"role": "system", "content": "You are Waymark's assistant. Be brief and warm."},
{"role": "user", "content": "Draft a welcome email for the Lakeland tour."},
{"role": "assistant", "content": "Welcome aboard. We are delighted you are joining us..."},
{"role": "user", "content": "Shorter, and mention the lake in the first line."}
],
"temperature": 0.7,
"max_output_tokens": 500
}
Read it as four parts. The first is model: which model to use. Providers offer several, larger and smaller, and the name is a choice off a menu — one that will matter a great deal when the bill arrives.
The second is messages, and it is the important one. It is a list, in square brackets, oldest first. Each item in the list is one message with two labels: role, saying who said it, and content, the actual text.
There are three roles. user is Tessa. assistant is the model's own earlier replies, handed back to it so it knows what it already said. And system is a standing instruction — a note about how to behave, sitting at the top of the list, addressed to the model rather than spoken by anyone in the conversation. Tessa never typed that line. Something else put it there, which is a story Chapter 8 tells properly.
Now look at what that list actually is. Four messages, on a turn where Tessa typed exactly one sentence. The rest is the conversation so far, sent again. Everything the previous page claimed about re-sent history is not a description of the mechanism — it is the mechanism, and it is a list that grows by two items every time she presses Enter. The context window is the limit on how long that list may get.
The third and fourth parts are the two settings at the bottom. One is a dial that controls how much the wording varies from one run to the next — Chapter 1's "why do I get a different answer each time", exposed as a number somebody chose. The other is a cap on how long the reply may be. The chat box has been picking both on her behalf since her first day. Chapter 8 gives them a page.
The Response Body, Annotated
And here is what came back.
{
"id": "response-id-here",
"model": "model-name-here",
"message": {"role": "assistant", "content": "The lake is waiting. Your Lakeland tour begins..."},
"stop_reason": "finished",
"usage": {"input_tokens": 96, "output_tokens": 128}
}
The reply itself is one message, in exactly the format of the messages that went out, with the role assistant. That symmetry is not decoration: it is why the reply can be appended straight onto the list and sent back next turn. The conversation is built out of one repeated shape.
Then stop_reason, which says why the model stopped writing. There are two answers worth knowing. It finished — it reached a natural end. Or it ran out of room, because the length cap in the request cut it off mid-thought. That distinction is the difference between an answer and a truncated answer, and a program that ignores it will happily file half a sentence as a result.
Last, usage: a count of the tokens that went in and the tokens that came out. Tokens are Chapter 1's unit — the pieces text is chopped into before the model reads it — and here they are, counted exactly, on every single call. Not an estimate on Tessa's side. A measurement reported by the provider, per request.
Those two numbers are the meter. Every call has them, they are priced separately, and adding them all up for a month gives you the invoice — which is precisely how the last page of this chapter reconciles Waymark's first bill line by line. Cost stops being a monthly surprise and becomes something observable one request at a time.
For years Tessa spoke her order across a counter and a plate arrived. What she is looking at now is the ticket the waiter actually writes and clips to the rail: table number, items, modifiers, in a fixed shorthand — plus the slip that comes back saying what was made and what it rang up as. Same meal. But she can read the ticket now, and the till roll too.
Read One Yourself
Here is a complete pair with no annotations. It is one of the 2,300 reviews being classified, in the shape Milo's program will send in Chapter 8: one review, one request.
{
"model": "model-name-here",
"messages": [
{"role": "system", "content": "Classify each review as praise, complaint, mixed or question. Reply with JSON only."},
{"role": "user", "content": "Review 1207, Lakeland tour: The guide was superb, though the coach was forty minutes late."}
],
"max_output_tokens": 100
}
{
"id": "response-id-here",
"model": "model-name-here",
"message": {"role": "assistant", "content": "{\"review_id\": 1207, \"tour\": \"Lakeland\", \"category\": \"mixed\", \"refund_mentioned\": false}"},
"stop_reason": "finished",
"usage": {"input_tokens": 71, "output_tokens": 44}
}
One wrinkle in the response, and it is worth naming so it does not look like a typo. The model's output is text, and this time the text is itself labelled data — Tessa asked for JSON, so JSON is what the reply says. When a quotation mark belongs inside a value rather than ending it, JSON marks it with a backslash. That is all the backslashes are doing: holding the inner braces and labels safely inside the outer ones.
Now four questions. How many messages went out, and in which roles? Which part of the response is the model's actual answer, as opposed to bookkeeping about it? Did the reply get cut off, and how can you tell? And which numbers on this page will turn up on Waymark's invoice?
The answers, in order. Two messages went out — a system instruction and one user message — and no assistant message at all, because there is no earlier turn to re-send: this program sends one review per request and starts fresh each time, which is exactly why classification is cheap and a long chat is not. The model's answer is the content of the assistant message, and everything else is bookkeeping. It was not cut off: the stop reason says finished, and had the cap bitten, it would have said so. And both usage numbers reach the invoice, priced separately, at rates that are not the same.
Read those two blocks once more and notice what is no longer mysterious. There is no hidden layer left between Tessa and the model — no secret protocol, no programmer's dialect. There is a list of messages, a couple of settings, a reply and a receipt. She can read the wire.
- "The request is code, and the model runs it." It is labelled data, exactly as Chapter 5 described: who said what, plus a few settings. Nothing in it executes. The model reads the list and continues it.
- "The system message is the model's own thinking." It is a standing instruction supplied by whoever sent the request — the chat box today, a product tomorrow. It is written by the sender and read by the model, never the other way round.
- "Token counts are something I have to estimate myself." The response reports them exactly, per call, in and out. The meter is in the payload, which is why cost in this world is measurable rather than guessed at.
- "The response sends the whole conversation back." It sends one new message. Keeping the transcript and re-sending it next turn is the sender's job, which is the whole reason the chat box exists.
- Every AI product Tessa will ever be shown sends this. Being able to read it collapses the distance between her and the vendor across the table, and turns "how does it work?" into questions with checkable answers.
- The usage block makes cost observable one request at a time, which is the foundation the bill page is built on — and the reason Waymark's first invoice will be explainable rather than merely payable.
Knowledge Check
What are the three roles a message in the list can have?
- System, user and assistant
- Sender, receiver and reply
- Question, answer and setting
- User, model and provider
Where does a conversation's history live in the request?
- In an identifier that points the provider at the earlier turns it has stored
- Inside the system message, which is where the earlier turns are summarized
- In the message list itself, which carries every earlier turn in order
- In the usage block, which records what has been sent across the conversation
The response says the stop reason was that the model ran out of room. What happened?
- The account went over its allowed rate, so the provider cut the answer short
- The length cap in the request stopped the reply before it was finished
- Something failed inside the provider, so only part of the reply survived
- The conversation grew too long for the model to read all of it
What does the usage block in the response report?
- How much of the model's capacity this one request happened to occupy
- An estimate of the request's likely cost, calculated by the sending program
- A score for how well the model handled the instructions it was given
- The exact tokens that went in and came back on this one call
You got correct