The chart component renders a bar, line, or pie chart on the canvas. It is display-only.
| |
|---|
| Component id | canvas.chart |
| Version | v1 |
| Action name | canvas_show_chart |
| Interaction class | Lifecycle-only (no submit or skip) |
| Default placement | Side rail (safe-area-right), rendered inline |
| Live updates | Yes, the PAL can update a visible chart in place |
chart is enabled on any PAL with the Magic Canvas skill attached; see Enabling and configuring components. Its only config key is enabled (default true):
Behavior
The PAL decides when to draw a chart; there is no developer-triggered path. Its system prompt directs it to chart small numeric comparisons or trends, with short labels and numeric values.
The PAL revises a visible chart in place by calling update_component with new data.
Arguments
| Field | Type | Required | Description |
|---|
chart_type | "bar" | "line" | "pie" | ❌ | Which chart to draw (default bar). |
data | array of {label, value} | ✅ | The data points. At least 1; the renderer accepts at most 12. |
data[].label | string | ✅ | Label for the point (renderer limit: 1–80 characters). |
data[].value | number | ✅ | Numeric value for the point. |
title | string | ❌ | Heading above the chart (renderer limit: 1–120 characters). |
x_label | string | ❌ | X-axis label (renderer limit: 1–80 characters). |
y_label | string | ❌ | Y-axis label (renderer limit: 1–80 characters). |
No other arguments are accepted. Tavus also injects two runtime controls shared by every Canvas action: layout (preferred slot, one of safe-area-right or safe-area-left) and display_mode (enum [inline], always inline).
Arguments exceeding the limits above produce a load error card instead of a
chart.
Example invocation
Interaction Types
chart is lifecycle-only: sending submit or skip returns a 400 (canvas.chart does not support this interaction type.). The interactions endpoint accepts four types:
| Type | What it means |
|---|
dismiss | The user closed the card |
clear | The canvas was cleared while the chart was on screen |
error | The client failed to display the chart |
heartbeat | A custom client’s periodic status ping |
Expect canvas.chart interactions only from clients you build yourself. The
stock Tavus SDK and hosted embed currently POST none of these: the card has
no dismiss control, render failures surface only via the local onError
callback, clearing the canvas removes instances locally without an
interaction, and renderer heartbeats use a separate model-context
channel that never reaches the interactions endpoint or your webhook.
Custom clients POST interactions to POST https://tavusapi.com/v2/conversations/{conversation_id}/canvas/interactions (validation rules).
Each recorded interaction fires your conversation webhook once as a canvas.interaction event (message_type: "canvas") and is available via GET https://tavusapi.com/v2/conversations/{conversation_id}/canvas/interactions (API key required).
Example Webhook Event
A dismiss POSTed by a custom client:
created_at is a Python isoformat() timestamp: UTC but timezone-naive,
with microseconds and no trailing Z or offset. The same shape appears
in the GET response.
For lifecycle types, Tavus validates the envelope (ids, component, type) but
only enforces that value is an object under 16 KB; don’t depend on
specific keys inside it.