Intent in, payload out
The agent emits an intent — offer these six options, collect a date, take a payment, show this link with a preview — and the builder produces the real platform payload.The model never writes channel JSON. Every message schema rejects fields it does not recognise,
so a model improvising an attribute produces a validation failure rather than a malformed message
reaching your customer. The failure is caught before send, not after.
Choosing the cheapest sufficient primitive
The builder picks by the shape of the information, not by what looks impressive.
And some hard blocks, because the failure modes are worse than the inconvenience:
- No form for a single field. Asking a customer to open a form to type one thing is worse than asking.
- No payment request without a narration turn first. Money is never the first thing a customer sees.
- No authorization prompt unless an action genuinely needs the scope.
- No primitive at all for a purely informational answer. If the reply is an answer, it is text.
Degradation is the builder’s job
Channels disagree about what comes back when a customer taps something. Some return a stable identifier — the option you actually defined. Others return only the label text the customer saw. That distinction matters enormously the moment a reply drives a branch, because a label can be ambiguous and an identifier cannot.One turn, and what it costs
You can send prose and a primitive in the same turn — an explanation followed by the choices it refers to. It reads better than splitting them. On Apple Messages for Business it is not free. That channel allows one message in flight per conversation at a time, so two messages in a turn is genuinely two sends, and worst case that is a noticeable pause before the customer sees the second. The builder is deliberate about it rather than chatty.Richness is a per-inbox setting
Three presets, and per-primitive overrides on top:Minimal
Text wherever text will do. Use when you want the transcript to read like a person wrote it.
Balanced
The default. Rich primitives where they genuinely reduce effort, text everywhere else.
Rich
Prefer structured primitives. Use where taps beat typing — mobile-heavy audiences, long option
lists.
Your flows never name a channel
This is the rule that makes the whole layer worth having. A flow definition may not name a channel primitive. No “list picker” node, no “quick reply” node. It says ask the customer to choose one of these, and the rendering is decided at send time.So a flow you build on web chat today runs on Apple Messages for Business the day your brand is
approved, with no re-authoring. Platform onboarding takes four to six weeks of calendar time —
that is a queue you wait in, not work you do. Building your flows while you wait is the right use
of it, and the studio’s channel preview lets you see exactly what you are waiting for.
Next
Rich Feature Messages
What the primitives look like on Apple Messages for Business.
Channel nodes
The same idea in the flow builder.
Training studio
Channel preview, and publishing a version.
Channels
What each channel can actually carry.