Skip to main content
This guide walks through the full flow for letting your users keep the charts an Upsolve agent builds in chat:
  1. Call the chat endpoint from your own UI and capture the generated chart from the stream.
  2. Show a “Save and add to dashboard” button next to the rendered chart.
  3. On click, persist the chart with Save Chart from Chat, then pin it to a dashboard with Add Charts to Dashboard.
Charts the agent creates in chat are ephemeral — they exist only in the response stream and the agent’s session memory. Until you call Save Chart from Chat, nothing is stored, and the chart is gone when the conversation ends.

Prerequisites

  • A project user token for the end user, minted server-side via Get Project User Token — see Backend Setup. All three endpoints in this guide accept it.
  • An agent ID — the agent your users chat with.
  • A dashboard ID — the target dashboard. For a fixed (“hardcoded”) dashboard, copy its ID once from the hub, or look it up with List Workspace Dashboards.

Step 1: Chat and capture the chart

Call the chat endpoint and watch the stream for a tool-result event whose toolName is generateChart. Its payload.result.chartConfig is the chart — keep the whole object in state, untouched.
Pass chartConfig through exactly as received. It normally includes a sqlOverride field carrying the SQL the agent wrote — that is what the saved chart uses to load data on a dashboard. If your tool result carries the query on the sibling sql field instead of on the config, forward it on the request’s top-level sql field. Without SQL from either source, the save endpoint rejects the request.

Step 2: The “Save and add to dashboard” button

When a chart arrives, render it (using chartData) alongside a save button:

Step 3 (reference): the two calls, as cURL

Persist the chart:
Add it to the dashboard:
The chart appears appended below the dashboard’s existing charts, full width. Users can resize and reposition it from the dashboard UI afterwards.

How the pieces fit

Troubleshooting

You extracted a partial config (for example, re-built the object from the rendered chart) instead of forwarding toolResult.result.chartConfig verbatim, and no query was supplied on the top-level sql field. Forward the config as received, or pass the tool call’s sql on the request body.
The agentId belongs to a different organization than the token you are calling with, or the ID is not the agent’s ID (check the agent URL in the hub).
You passed both agentId and an explicit connectionId, but the connection lives in a different project than the agent. Pass a connectionId from the agent’s project, or omit it to use the agent’s own connection.
The chart needs a connection to run its SQL on a dashboard. Pass agentId (preferred — its data model supplies the connection) or an explicit connectionId. If you pass an agentId whose data model has no connection, attach a connection to the data model or pass connectionId directly.