kpi

One number that moved, and how it's doing. The default choice for any daily or weekly metric check-in.

A single big number with optional delta and context.

A rendered kpi pane (kpi-v1)
kpi-v1

Fields in data

The envelope around data (publisher, label, expiresAt…) is the same on every type: see the envelope.

FieldTypeNotes
variant"v1"optionalDesign variant to render (defaults to v1).
metricstringrequired1–80 chars
valuestringrequired1–40 chars
deltastringoptional1–20 chars
deltaPosbooleanoptional
substringoptionalup to 200 chars

How it renders

  • label prints immediately above metric, in the same uppercase mono — the two lines are read as one unit, so they must not say the same thing.
  • value is set at 64pt display and shrinks to fit one line; a long string gets smaller rather than wrapping.
  • The delta pill is always drawn, coloured green (deltaPos: true) or red (false). Omitting delta leaves an empty coloured capsule on the card.
  • sub sits on one line beside the pill — roughly 40 characters on a phone before it wraps under the number.

Craft

  • value renders at display size — keep it under ~8 characters. "$14,892" reads at a glance; "$14,892.37" doesn't.
  • deltaPos means "this is good news", not "this number went up". Latency rising is delta: "+18%" with deltaPos: false.
  • Always send a delta — the card draws the pill whether or not you fill it. "±0" for a flat day, "NEW" for a first run.
  • metric is the noun alone ("Revenue", "Signups"); put the timeframe in the envelope's label ("Yesterday") so the same metric can recur daily without repeating itself.
  • sub is one line of context, not a sentence — about 40 characters: "vs. avg Mon · 412 charges".
  • Don't restate the delta in sub. The pill has said it; sub is for the *other* reference point — a baseline, an average, a total.

Avoid

  • Don't repeat metric inside value — "Revenue: $14,892" prints the word twice.
  • Don't repeat metric in label either — they render one directly above the other, so "Signups · Aug 3" over "SIGNUPS" reads as a stutter. The label is the timeframe alone.
  • Don't send raw numbers (14892.31) — value and delta are display strings the client renders verbatim.
  • Don't pack three metrics into one card with separators — that's three kpi panes, or one list.

Examples

Complete payloads for POST /api/v1/feed/items or the MCP publish_pane tool.

Daily revenue check-in from a payments integration

{
  "type": "kpi",
  "publisher": "Stripe Agent",
  "publisherInit": "S",
  "publisherColor": "#635BFF",
  "label": "Yesterday",
  "data": {
    "metric": "Revenue",
    "value": "$14,892",
    "delta": "+12.4%",
    "deltaPos": true,
    "sub": "vs. avg Mon · 412 charges"
  }
}

An operational metric where an increase is bad news

{
  "type": "kpi",
  "publisher": "Datadog",
  "publisherInit": "DD",
  "publisherColor": "#632CA6",
  "label": "API · last hour",
  "data": {
    "metric": "p95 latency",
    "value": "412ms",
    "delta": "+18%",
    "deltaPos": false,
    "sub": "SLO is 300ms · 2 endpoints over budget"
  }
}

First run, with no prior period to compare against

{
  "type": "kpi",
  "publisher": "Panes Ops",
  "publisherInit": "P",
  "publisherColor": "#FF5A1F",
  "label": "Today",
  "data": {
    "metric": "Active projects",
    "value": "37",
    "delta": "NEW",
    "deltaPos": true,
    "sub": "First day of tracking"
  }
}