Ask-your-data copilot: how a question becomes a governed answer
Two surfaces let you ask a plain-English question about your own metrics — “What’s my delivery rate?”, “How much did we spend on voice this quarter?”, “How many messages failed this month?” — and get an answer instead of a dashboard hunt. This page is the model behind both of them: how a question resolves to a metric, a window, and a chart, and why that resolution is bounded to a governed catalog rather than open-ended.1. Where this fits — two surfaces, one catalog
The copilot ships on two surfaces:- The Ask your data panel on Insights → Analytics (
/insights/analytics). The whole pipeline — parsing, answer composition, and chart rendering — runs in your browser. The panel detects the metric and window from the question text and reads the same tenant-scoped analytics snapshot the page’s KPI cards already loaded. No question text leaves the browser, no third-party model is called, and no new API endpoint is touched. POST /copilot/askon the Analytics API. You send aquestionstring; the resolver returns the id of the dashboard-widget-catalog widget that answers it plus resolvedwindowandchannelparameters. Your client then fetches that widget’s own read-only source endpoint for the actual numbers — the same composition pattern the no-code dashboard builder uses.
2. The governed widget catalog
Every answer resolves to an entry in the dashboard widget catalog — the same published catalog the dashboard builder composes layouts from. This constraint is what makes a copilot answer governed:- The resolver never synthesizes a query or an aggregate from the question text. It only routes to a widget that already exists.
- The widget’s
sourceis an existing, already-authenticated, already-tenant-scoped read-only endpoint. The front end fetches that endpoint for the numbers, so the copilot never computes a figure of its own. - Widgets that require an opaque path parameter (a queue id, an agent id) are excluded from matching, because free text has no way to supply one safely.
3. How question parsing works
Parsing resolves three things: a metric, a window, and (on the API surface) a channel. Metric detection. The question is matched against an answerable metric catalogue. On the panel surface that catalogue spans volume, delivery, voice, contacts, and cost — message volume, delivered count, failed count, delivery rate, calls, talk time, contacts, and spend. When nothing recognizable names a metric, the answer falls back to overall message volume and the surface tells you so: the panel shows an “I wasn’t sure which metric you meant” hint, andPOST /copilot/ask returns understood: false. Name a metric to get a specific answer.
Window detection. A question can name its own date window: today, yesterday, or the last 24 hours; this week or the last 7 days; this month or the last 30 days; this quarter or the last 90 days; this year, the last 12 months, and year to date. A custom day count the presets can’t express — “last 20 days”, “past 85 days” — clamps the page’s custom calendar range to that span instead. On the panel, a named window pivots the page’s date filter so the answer is computed over the period you asked about rather than the currently selected one. On the API surface, the resolver returns the window as a window parameter, defaulting to 30 days when the question names none.
Channel detection (API surface). Words like “whatsapp”, “email”, “voice calls”, or “sms” resolve to a channel parameter, applied only when the resolved widget declares one.
4. Chart rendering
An answer has up to two parts: a one-sentence headline and a chart.- The sentence carries the resolved number with its unit (count, percent, minutes, or your billing currency) and the human label for the window, followed by the “name a metric” hint when the question didn’t match one.
- The chart appears only when a daily series exists to chart. On the panel, that is the message-volume widget: a compact area chart of message volume by day, built from the same daily per-channel series as the page’s big chart, with an accessible text summary (the total across the days shown) underneath. Metrics with no daily series on the page — delivery rate, voice, contacts, and spend — stay text-only, so a chart never shows a number the rest of the dashboard doesn’t already show. On the API surface, the resolver returns the widget’s declared visualization and lets your client render it from the widget’s source endpoint.
5. Security and scoping
- Tenant and role scoping.
POST /copilot/askis gated to the analytics-read hierarchy — owner, admin, developer, and viewer roles within your organization — and shares the analytics rate-limit bucket with the sibling read endpoints. The panel inherits the page’s own session and tenant context. - Read-only posture. The endpoint is POST only because the question rides in the request body; it performs no write. The resolver layer is stateless and database-free — it maps text to a catalog widget and never touches tenant data.
- No third-party model. Parsing is deterministic phrase matching on both surfaces. On the panel path, question text never leaves your browser; on the API path, it is used for routing only and no tenant data is passed to any external model.
6. Worked examples
“Top delivery failures last week”- Parsing matches the failures phrasing to the delivery-failure widget and “last week” to a 7-day window.
- Resolution returns that widget’s id with
window: "7d";understood: true. - Your client fetches the widget’s source endpoint with the resolved window and renders the delivery-failure breakdown — the same numbers the deliverability page would show for that window.
- Parsing matches “llm spend” to the LLM-spend widget; “yesterday” resolves to the last-24-hours window.
- Resolution returns the LLM-spend widget id with
window: "24h". - Your client fetches the widget’s org-scoped spend ledger endpoint (the one public-scope store in the insights family, still returning only your organization’s rows — see the insights rollup model) and renders spend by feature, model, and channel.
See also
- Insights rollup model — the read-time derivation family both surfaces read from.
- Analytics pipeline — the background event spine behind the time-series endpoints the widgets fetch.
- Request metrics and analytics pipeline — how request metrics feed the analytics stores.
- Ask your data guide — the operator walkthrough of the panel surface.
- Analytics API reference — endpoint shapes for the widget source endpoints.