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

modeWhat the user seesWhat comes back on submit
date_pickerA month calendar, optionally with quick-pick preset buttonsselected_date (YYYY-MM-DD)
slot_pickerA list of concrete time slotsselected_slot (or selected_slots with multi_select)
date_timeCalendly-style: pick a date, then a slot on that dateselected_slot (or selected_slots with multi_select)
rangeA start–end date range pickerselected_range ({start, end})

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, date_range, initial_month, and initial_year 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

The same fields appear in update_component patches; dates use YYYY-MM-DD.
FieldTypeRequiredDescription
titlestringHeading on the card. 1–120 characters.
timezonestringIANA timezone name (e.g. America/Los_Angeles) used to present times. 1–120 characters.
modestringdate_picker, slot_picker, date_time, or range. If omitted: slots present → slot_picker, otherwise date_picker.
multi_selectbooleanSlot-bearing modes only (slot_picker, date_time): let the user pick more than one slot. Defaults to false.
slotsarray✅ when mode is slot_picker or date_time1–24 entries. Each slot: id (required), start (required, ISO-8601), end (required, ISO-8601), label (optional display text).
presetsarrayUp to 6 quick-pick buttons for date_picker. Each: label (required, ≤40 chars) and date (required, YYYY-MM-DD).
initial_datestringPre-selected date, YYYY-MM-DD.
initial_monthstringMonth the calendar opens on, YYYY-MM.
initial_yearintegerYear the calendar opens on, 1–9999.
date_rangeobject{ "start", "end" }, both YYYY-MM-DD, inclusive. Limits which dates are selectable.
highlighted_datesarray of stringsUp to 62 YYYY-MM-DD dates to visually highlight.
allow_skipbooleanShows a skip button so the user can decline to pick. Defaults to false.
layoutobjectPlacement control available on every component action: { "preferred_slot": "safe-area-right" | "safe-area-left" }. Calendar cards default to safe-area-right.
display_modestring"inline" (the only supported value). Available on every component action.
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:
ModeSelection field
date_pickerselected_date, a YYYY-MM-DD string
slot_picker / date_timeselected_slot, one slot object
slot_picker / date_time with multi_selectselected_slots, an array of one or more slot objects
rangeselected_range, { "start", "end" }
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:
TypeMeaning
dismissThe user closed the card without answering.
clearThe card was removed (for example, the PAL called canvas_clear or replaced it).
errorThe renderer reported a problem with the card.
heartbeatA periodic liveness signal while the card is on screen.
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

Component idcanvas.calendar
Action namecanvas_show_calendar
Versionv1
Interaction classsubmit_capable
Interaction typessubmit, skip, dismiss, clear, error, heartbeat
Default placementsafe-area-right
Supports update_componentYes
PAL configOn by default with the magic_canvas skill attached; disable with config.components.calendar = { "enabled": false }