question component (canvas.question) shows a multiple-choice question card during a conversation. The user taps an option (or types a free-text answer, when allowed) and the structured result goes to the PAL and your conversation webhook.
Triggering
The PAL shows the card by invokingcanvas_show_question when the user should answer a structured question. Steer the timing in the PAL’s system prompt.
- Renders in the
safe-area-rightslot by default. - A repeat
canvas_show_questioninvocation replaces the card currently on screen with a new instance and a newtool_call_id; in-progress input is lost and interactions arrive under the new id. - Only one canvas card is on screen at a time. A new
canvas_show_questioninvocation always replaces the current card; two cards never appear at once.
question has no component-specific settings beyond enabled. See Enabling and configuring components.
Arguments
The PAL passes these tocanvas_show_question:
Example invocation
Interactions
question is a submit-capable component emitting six interaction types: submit, skip, dismiss, clear, error, and heartbeat. Only submit and skip carry an answer value; the rest are lifecycle signals with no question payload. Each interaction reaches your conversation webhook as a canvas.interaction event with the answer in properties.value.
Value Shape (submit and skip)
Tavus rejects values with any other keys and enforces these rules before delivery:
skip: alwaysskipped: true, with no selections,custom_text, oroption_texts.submit: alwaysskipped: false, with at least one selected id or a non-emptycustom_text; never an empty answer.
The hosted card offers Skip only when
allow_skip is true. Tavus does not re-check an incoming skip against the original action arguments, so a custom renderer could post one regardless.Example Payload
properties always carries the same nine keys. interaction_id uniquely identifies the interaction; tool_call_id ties it to the originating canvas_show_question call. created_at is a naive ISO-8601 timestamp with microseconds and no timezone suffix (no trailing Z); treat it as UTC.
Submit
Webhook Handling
Branch ontype first, then read the value:

