selection part with a short title and 1 to 25 options, flat or grouped into sections. Each option has a readable label and a stable id or legacy value. The user opens the picker and submits their choices in one reply.
Send a selection
This flat example keeps the existingvalue format. Its optional text appears above the card; title heads the card and picker. Open the prompt below, check options, then press Send; this demo stays in your browser and sends no request.
- Preview
- JSON
multiple defaults to true; set it to false for one choice. Older Relay app versions ignore multiple: false and can send several choices, which Relay refuses with a 422, so prefer multiple: true until the new app ships. Send exactly one of flat options or titled sections. Selection fields covers limits, aliases, and returned fields.
Use an Agent Token and an existing chat ID to send the same request:
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.
Group options and set the answered text
Usesections to group rows, subtitle for the card’s second line, and reply_message for the answered bubble. Row subtitles and images belong inside the picker. This example requests one delivery choice.
options as well as the supplied sections. Options return both id and an equal value alias, so existing readers can keep using value.
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
selected_ids even when the user submitted only selected_values. Both arrays name the same options in source order.
When the prompt supplies reply_message, Relay copies it into the answer metadata for the answered bubble, independently of the source Message. Without it, the reply uses the source title and chosen labels, as in the preview. This presentation does not replace the portable text.
New text equals literal • + 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 user 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, selected_values, and selected_ids, and its reactions is always null:
has_responded becomes true after that user answers; both arrays hold their choices in source order and are null before an answer or when the answer Message no longer exists. For an agent, has_responded is always false and both arrays are always null, so read answers from received selection_response Messages.
The user’s devices receive a message.upserted for the prompt with the updated viewer fields.
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 each runtime’s existing send path. The flattitle and options examples remain valid; each integration describes its accepted input. Preserve selected_values, selected_ids, and reply_to beside the readable text when forwarding a reply.
When it fails
The server checks an answer against its source: the user must see the prompt in the same chat, text must match the chosen labels, and identifiers must be known and in source order.selected_values remains required; optional selected_ids must match it exactly, and multiple: false requires one choice. For compatibility it also accepts the exact selected source labels joined with , ; new clients send bullet lines.
Dispatch on the identifiers and reply_to, never by parsing text. The field reference separates client reply inputs from server-owned metadata.
Keep the original body and idempotency key when retrying an uncertain submission.

