Docs/Dashboard/Breakdowns
DashboardUpdated Oct 19, 2026 · 3 min read

Breakdowns

The top values of one dimension, ranked by people or by how often they happen.

Ask your agent

The same prompt the Breakdown card hands out under How to add, with your own install command and your own dimension in it. Paste it into your coding agent.

Add an UpControl breakdown "page" to this app, folded by value. First read npx upcontrol skills breakdown. Then run npx upcontrol (it saves this project's key to a gitignored .env without printing it). Call value() at the moment the thing happens, with the value of the dimension. Normalise the value first so it is bounded: a path pattern rather than a full URL, a status class rather than a raw id. An unbounded value ranks a thousand rows of one and says nothing. Pass this app's stable person id as the second argument to value(): the card counts distinct people, and a value with nobody behind it is counted as nothing at all. When the app has run once, run npx upcontrol verify.

Build the card

  1. On the dashboard press Add widget, pick Breakdown, then Next.
  2. Pick the one event the dimension rides, then one of that event's own fields to fold it by.
  3. Pick the axis: People counts each person once, Events counts every occurrence.
  4. Name the card and press Add widget.
A breakdown card named Signups by country: US 1,842, DE 611, GB 498, SE 377, Other 310, FI 204
A breakdown: one event folded by one of its fields, largest first. Sample data.

Keep the values bounded

  • value() takes the value of the dimension at the moment the thing happens.
  • Normalise it first: a path pattern rather than a full URL with its query string, a status class rather than a raw id.
  • An unbounded value ranks a thousand rows of one and says nothing.
  • Pick Events for a dimension nobody is behind, such as a delivery outcome or an HTTP status: counted as people it reads 0, because every people read needs an actor.
import { breakdown } from '@upcontrol/sdk';
export const pages = breakdown('page');
// Counts occurrences:
pages.value('/pricing');
// Counts distinct people instead:
pages.value('/pricing', 'u_' + user.id);

Table

One event's values by one of its fields, with a column per number. Pick Table under Add widget, then the event, the field and, when the event carries money, a currency under Revenue in. Every header sorts the rows by its column.

  • The value: one of the picked field's values, the field's name over the column.
  • Events: how many times the event happened with that value. The rows are ranked by it until another header is pressed.
  • People: the distinct people behind those events.
  • Revenue: the money those events carried, in the one currency picked under Revenue in. Two currencies are never added together.
  • Share: the value's events as a part of all of them. A narrow card drops it first, then People.
  • Money rides the event as uc.amount, in minor units (cents for USD, whole yen for JPY), and uc.currency, its ISO code.
  • Send it from the server with the project's key, where the payment is confirmed. A browser holds only a public key, and the money a public key sends is dropped.
  • One event per successful payment; a refund is the same event with a negative amount.
  • Until an event carries money, Revenue in is not offered, and the card's How to add prompt also teaches your agent to send it.

The prompt the Revenue picks on a stat, a line or a bar hand out while no event carries money:

Add UpControl revenue tracking to this app. First read npx upcontrol skills wire. Then run npx upcontrol (it saves this project's key to a gitignored .env without printing it). Find where the backend confirms a payment: the payment provider's webhook or the checkout success handler. There, send track('payment', { 'uc.amount': <amount in minor units>, 'uc.currency': '<ISO code>', plan: <plan id> }) from the SERVER with this project's key, never from the browser: the money a public key sends is dropped. Send one event per successful payment, and a refund as the same event with a negative amount. When the app has run once, run npx upcontrol verify.