Skip to main content
The calendar component displays a date or time picker mid-conversation. The user’s selection is delivered to your webhook as structured data: a YYYY-MM-DD string or an ISO-8601 slot.
The calendar shows only the dates and slots in the invocation; it does not fetch availability. For live booking against a Calendly scheduling page, use scheduling_embed.
calendar is enabled whenever the Magic Canvas skill is attached and has no component-specific configuration; see Enabling and configuring components.

Modes

PAL Behavior

The PAL is prompted to invoke canvas_show_calendar when the user should pick a date or time slot, inferring mode, multi_select, and date_range from the conversation. You don’t trigger the action directly. Slot times come from the PAL’s context. Provide availability through your system prompt, conversational context, or a tool from your Tools library.

Arguments

Dates use YYYY-MM-DD.
Example invocation

Interactions

calendar produces six interaction types: submit, skip, dismiss, clear, error, and heartbeat. Each is delivered to your conversation webhook as a canvas.interaction event and is also available from GET https://tavusapi.com/v2/conversations/{conversation_id}/canvas/interactions.
Webhook delivery

submit

Exactly one selection field is present and non-null, and skipped is false. The field depends on the card’s mode: Slot objects echo back exactly what the PAL offered: id, start, and end always; label when the invocation included one. Selection fields for other modes are null.

skip

Sent when allow_skip is on and the user taps the skip button: skipped is true and no selection field carries a value. The PAL sees the skip too.

dismiss, clear, error, heartbeat

Lifecycle events about the card itself, not answers: Their value has no fixed schema (a free-form object, often {}); don’t build logic on its contents.
Don’t count a conversation as scheduled until you see a submit; users also dismiss, skip, or let the conversation move on.

Webhook Handling

Branch on type first, then on whichever selection field is non-null:
Tavus records each interaction once: a retried POST with the same interaction_id and identical payload never fires your webhook twice. Key non-reversible handlers on properties.interaction_id anyway.

Reference