selection part with a short title and 1 to 25 options. Each option has a readable label and a stable value. The app draws the selection as one card that opens a sheet holding the whole option list, and the person checks several options there and submits them in one reply.
Send a selection
This request contains an optionaltext part followed by a selection part. The text shows as a normal message above the card. The selection’s title is the card’s title and the sheet’s title; a second line reads “Pick options”, and a chevron marks the card as something to open. Open the prompt below, check options in the sheet, then press Send; this demo stays in your browser and sends no request.
- Preview
- JSON
Rules for the prompt
- Only an agent can send a selection.
- A Message carries at most one
selectionpart. Atextpart is optional; when present it shows as a normal message above the card. titleis required: 1 to 60 characters after surrounding whitespace is trimmed, a few words such as “Pizza toppings”. It is the card’s title and the sheet’s title.- A selection cannot share a Message with a
buttonspart. optionsholds 1 to 25 options.- Each
valueis 1 to 100 characters, matches^[A-Za-z0-9][A-Za-z0-9._:-]*$, is case-sensitive, and is unique within the selection. Your application keys on it, so keep it stable. - Each
labelis 1 to 80 characters after surrounding whitespace is trimmed. The app shows labels verbatim. - An option has only
valueandlabel; any other field is rejected.
202 after storing the message. Keep the returned message ID so your application can associate responses with this question. Reuse the same request and idempotency key after an uncertain send.
Receive stable values
The user’s submission contains exactly two ordered parts: readable text, then structured metadata. Itsreply_to identifies the source message and selection part.
- Preview
- What you receive
• + each selected source label joined with \n, in source-option order. It supplies portable bubble, notification, and copy text; iOS may draw a checkmark in place of each bullet, and repeat the selection’s title above the lines, as presentation only. The selection_response part carries metadata only.
A person answers a given selection once. Opening the answered prompt again, or opening the reply, presents the same sheet read only: the chosen rows are checked, no row is tappable, and the sheet carries no Send. Try it in the preview above.
Read whether someone answered
When you read a Message back, itsselection part carries has_responded and selected_values, and its reactions is always null:
has_responded is true once that person has answered this selection, and selected_values holds the values they chose, in option order, so every one of their devices shows the same answer even when it has not loaded the answer Message. selected_values is null until they answer, and also if their answer Message no longer exists. For an agent, has_responded is always false and selected_values always null, so an agent learns about answers from the selection_response Messages it receives, not from these fields. When a person answers, their own devices receive a message.upserted for the prompt with both fields set.
A selection_response part you read back has no reactions key, and neither selection part can receive a reaction.
Your existing signed webhook or WebSocket handler receives the ordinary message.received event. The SDK’s default event types expose the metadata:
Application handler
Send from a runtime
Selections use the runtime’s existing send path: a backend includes aselection part, with optional text before it, in parts; a runtime with a send tool takes a selection argument; and a runtime that answers in text ends its answer with a fenced code block tagged selection containing the selection’s title and options. Responses carry selected_values and reply_to alongside the readable text. Each integration describes its send and receive format.
When it fails
The server checks an answer against the prompt it names: the reply must come from a person who can see that prompt in the same chat, its text must match the chosen labels exactly, and its values must be known and in the prompt’s option order. For compatibility it also accepts the exact selected source labels joined with, ; new clients send bullet lines. Dispatch on selected_values and reply_to, never by parsing the text.
Keep the original body and idempotency key when retrying an uncertain submission.

