A rendered analysis document in PushMetrics with an overview section and a bar chart of car sales by make

When the agent finishes an investigation, the result usually doesn't belong inside a chat thread. The numbers, charts, and the prose that explains them deserve a stable URL that a teammate can open later without having to re-run anything.

That's what an analysis document is. It's a markdown report with embedded charts, inline numbers backed by SQL, and footnotes that link every claim back to the query that produced it. The agent writes it. You and your stakeholders read it.


Where analysis documents live

Open Content in the top nav. Analysis documents sit on the same page as knowledge entries and metrics views. Each one has an "Analysis" tag so you can pick them out from the rest.

Each card shows the title, how many sources and charts it contains, and how long ago it was last refreshed. Click into one to see the full rendered document.


Creating an analysis document

There are two ways one gets created.

The agent writes it

Most analysis documents start as a chat. You ask a question like "what drove the March revenue spike", the agent runs queries, sketches some charts, and at the end calls its save_analysis tool. The conversation closes with a link to the saved document.

This is the path you'll use most often. The agent already has the queries, the results, and the narrative ready. Saving it as a document just freezes that work into something you can share.

You start a blank one

If you'd rather draft the structure yourself and let the agent fill in the details, or write the whole thing by hand, open Content → Create New → New Analysis Document.

The Create New menu open on the Content page, showing options for New Knowledge Article, New Analysis Document, New Metrics View, Upload .md Files, and Upload Metrics .yaml

You can also drop a .md file in via Upload .md Files. That's useful if you're moving an analysis between workspaces or pulling in a draft from somewhere else.


What's inside one

The edit view of an analysis document showing the markdown body in a code editor at the top and a Sources panel below listing the cached SQL queries that back the document

The edit view splits cleanly in two. The top is the markdown body with the prose, charts, and inline query() calls. The bottom is the Sources panel, which lists every SQL query the document relies on. You can run a single source, refresh them all, or open one to edit its SQL.

An analysis document is markdown plus a few extras:

  • Narrative text. Sections, headings, lists, anything markdown supports.
  • Sources. The SQL queries that ran against your database. Their results are cached so the document loads instantly without hitting the warehouse again.
  • Inline values. Numbers in the prose that come from the cached data, not hardcoded. They look like {{ query("SELECT user_count FROM signups WHERE month = '2026-03-01'") }}.
  • Charts. Code blocks tagged chart that compile into Plotly visualisations.
  • Footnotes. Every quantitative claim links back to the source query, the filter, and the column it came from.

Here's a small example:

# March User Growth

We added **{{ query("SELECT user_count FROM signups
WHERE month = '2026-03-01'") }}** new users in March[^count],
a **{{ query("SELECT pct_change FROM mom_growth
WHERE month = '2026-03-01'") }}%** lift on February.

[^count]: source: `signups` | filter: `month = '2026-03-01'` | column: `user_count`

```chart
source: signups
type: line
x: month
y: user_count
title: Monthly Signups
```

When the document opens, the cached source data loads, the query() calls run client-side, and the chart and inline numbers render together.


How rendering works

Analysis documents are static snapshots, but interactive ones. Each source query runs against your real database once, and PushMetrics keeps the result around as a Parquet file. When someone opens the document, the cached Parquet is loaded into a small SQL engine that runs inside the browser, and the chart blocks and inline query() calls run against that. The document never reaches back into your warehouse on page load.

SOURCE QUERY runs against your database PARQUET CACHE full result saved per source DUCKDB IN BROWSER renders charts and numbers

A few things worth knowing about how this plays out:

  • Loading is fast. The cached Parquet file is small and DuckDB inside the browser is quick. Most documents are interactive within a second.
  • The data is only as fresh as the last refresh. If the source query ran yesterday, the numbers in the document are yesterday's numbers. There's a Refresh Data button at the top of the document when you need to pull new data.
  • Failed sources don't kill the document. If one source can't load, that section shows an error card and everything else renders normally.

Why every number has a footnote

Every quantitative claim in an analysis document is followed by a footnote. Click it and you see the source SQL, the filter that was applied, the column the value came from, and a link to the full cached results.

This is the part that makes the document trustworthy. Without footnotes, a number is just a number. There's no way to check if it's right, no way to reproduce it, no way to argue with it productively. With footnotes, anyone reading can follow the chain from the claim to the query to the data.

The agent is trained to add a footnote for every number it writes. If you spot one without a citation, push back.


Refreshing the data

Analysis documents are snapshots, not live dashboards. When the underlying numbers move, you refresh.

Click Refresh Data at the top of the document. Every source query re-runs against the database, the new results get cached, and the document re-renders. If a document goes stale and hasn't been refreshed in a while, you'll see a banner suggesting it.

You can also schedule refreshes the same way you schedule a report. Point a workflow at the document and have it refresh on a cadence.


Sharing

Every analysis document has a stable URL. Anyone with workspace access can open it. In Slack or email you can share the link directly, or have the agent post a summary with a link back to the full interactive version.

🔗
One link, one source of truth. Stop pasting screenshots of charts into Slack. Send the analysis URL instead. Readers get the live document, the footnotes, and the option to refresh the data themselves if the numbers feel stale.

When to save vs. leave it in chat

Not every chat needs to become a document. Save one when:

  • You'll share it. Stakeholders, leadership, the rest of the team. Anyone who wasn't in the conversation.
  • You'll come back to it. Quarterly reviews, recurring deep-dives, anything you'll want to compare against next time.
  • The reasoning matters. Cases where the how is as important as the what. Assumptions, methodology, edge cases the agent had to handle.
  • The numbers will change. A document you can refresh beats a snapshot that goes stale and gets re-asked.

Leave it in chat when the question was a one-off lookup, or when the answer is obvious enough that prose and footnotes would be overkill.

📊
Pair with metrics views. When the analysis references a metrics view, the document and the canonical definition stay tied together. Update the view and every analysis built on it picks up the new definition on the next refresh.