Statboy agent guide

Statboy is an iPhone app that shows its user dashboards, and alerts that arrive as push notifications. It has no editing screens: everything in it is sent by agents like you. This page is for agents. It is also served as Markdown at /agents.md.

Connecting

The user gives you a connect code, such as STAT-7Q4K-92XM-H3TD, in the prompt they copied from the app. That code is your key: send it as a Bearer token on every request. The first request that uses it connects you. Call connect first, with a short name that says what you do for the user, such as finance-agent. Statboy shows that name next to everything you send. Until you have a name, only connect and whoami work.

The code connects one agent. If Statboy says it has expired or was already used, ask the user to copy a fresh prompt from the Statboy app.

The MCP server at https://statboy.ai/mcp is not available yet; requests to it return a JSON error pointing here. Use the HTTP API below.

HTTP quick start

Every action is POST https://statboy.ai/api/v1/<action> with a JSON object as the body and the connect code as a Bearer token.

curl -sS https://statboy.ai/api/v1/connect \
  -H "Authorization: Bearer STAT-XXXX-XXXX-XXXX" \
  -H "Content-Type: application/json" \
  -d '{"name": "finance-agent"}'

curl -sS https://statboy.ai/api/v1/send_alert \
  -H "Authorization: Bearer STAT-XXXX-XXXX-XXXX" \
  -H "Content-Type: application/json" \
  -d '{"title": "Statboy is connected", "summary": "Test alert from finance-agent."}'

curl -sS https://statboy.ai/api/v1/replace_dashboard \
  -H "Authorization: Bearer STAT-XXXX-XXXX-XXXX" \
  -H "Content-Type: application/json" \
  -d '{"dashboard_key": "revenue", "name": "Revenue", "cards": [
        {"card_key": "mrr", "type": "stat", "label": "MRR", "value": 48214,
         "format": {"style": "currency", "currency": "USD"},
         "change": {"direction": "up", "amount": "4.1%", "period": "in 30 days"}, "better_when": "higher"},
        {"card_key": "mrr-trend", "type": "line_chart", "title": "MRR", "caption": "30 days",
         "points": [{"at": "2026-10-14", "value": 46312}, {"at": "2026-11-13", "value": 48214}]}]}'

curl -sS https://statboy.ai/api/v1/whoami \
  -H "Authorization: Bearer STAT-XXXX-XXXX-XXXX" -d '{}'

Actions

connect

Finishes connecting by naming this agent. Call it first: until you have a name, only connect and whoami work. The name is shown to the user next to everything you send, so pick a short one that says what you do for them, such as "finance-agent". Lowercase letters, digits and hyphens, up to 32 characters. Calling it again with the same name is safe. A connection is named once; a different agent needs its own connect code from the Statboy app.

FieldRequiredRule
name Yes Your name, such as "finance-agent".

whoami

Tells you who you are in Statboy: your agent name, your organization, what you are allowed to do, and how much of each limit is left. Takes no input.

No input.

list_dashboards

Lists every dashboard in the order the Dashboards tab shows them, with its key, name, stale-after period, when its data was last updated and by which agent, whether it is stale now, and its card keys in order. Takes no input.

No input.

get_dashboard

Returns one dashboard with its cards and their current data, so you can see what is there before changing it. Each card is in the form you send it, plus `info` with updated_at, updated_by and, for a stat, history_points. The cards list can be edited and sent back to replace_dashboard as it is.

FieldRequiredRule
dashboard_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit

replace_dashboard

Sends a complete dashboard: the normal way to build or refresh one. It creates the dashboard if needed and makes its cards match `cards` exactly, in that order, in one step that applies completely or not at all. A card that is on the dashboard but missing from `cards` is deleted with its history, so send every card you want to keep (read them first with get_dashboard). Every card you send counts as freshly updated. Each card is an object with card_key, type (stat, line_chart, bar_chart or text) and that type's fields; the full rules are at https://statboy.ai/agents#cards. At most one stat may have headline true; it is the number shown on the Dashboards tab, and without one the first stat is used.

FieldRequiredRule
dashboard_key Yes The dashboard's key, such as "revenue". A new key creates a dashboard.
name No Up to 40 characters. Required when the dashboard is new.
stale_after_minutes No Minutes before the dashboard counts as stale: 5 to 129600 (90 days), or "never". A new dashboard gets 1440 (24 hours).
cards Yes 0 to 30 cards, in display order.

set_dashboard

Creates an empty dashboard, or changes a dashboard's name or stale-after period, without touching its cards. It does not make the dashboard's data count as fresh. A new dashboard goes to the end of the Dashboards tab.

FieldRequiredRule
dashboard_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit
name No Up to 40 characters. Required when the dashboard is new.
stale_after_minutes No Minutes before the dashboard counts as stale: 5 to 129600 (90 days), or "never". A new dashboard gets 1440 (24 hours).

reorder_dashboards

Sets the order of the Dashboards tab. List every dashboard key exactly once, first to last.

FieldRequiredRule
dashboard_keys Yes Every dashboard key, in the order to show them.

delete_dashboard

Deletes a dashboard, its cards and their history at once. It cannot be undone, and the app does not ask the user first.

FieldRequiredRule
dashboard_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit

set_card

Creates or replaces one card on a dashboard that already exists, leaving the other cards alone. A new card goes to the end unless before_card_key says where; an existing card keeps its place unless before_card_key is given. Replacing a stat with another type, or a number with text, deletes the stat's history. A stat sent with headline true becomes the dashboard's only headline. The card rules are at https://statboy.ai/agents#cards.

FieldRequiredRule
dashboard_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit
card Yes A card: card_key, type (stat, line_chart, bar_chart or text) and that type's fields. See https://statboy.ai/agents#cards.
before_card_key No Optional. Place the card just before this one.

update_stat

Replaces a stat card's value and change, and records the value in its history: the cheapest call for a script that tracks one number. `change` and `display` are cleared when you leave them out. A stat holding a number cannot be turned into text here, so its history is never lost by accident; use set_card for that.

FieldRequiredRule
dashboard_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit
card_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit
value Yes A JSON number, or text of up to 12 characters for a state such as "Healthy".
change No
display No one line of text that is not only spaces

reorder_cards

Sets the order of a dashboard's cards. List every card key on the dashboard exactly once, first to last.

FieldRequiredRule
dashboard_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit
card_keys Yes Every card key, in the order to show them.

delete_card

Deletes one card and its history. It cannot be undone, and the app does not ask the user first.

FieldRequiredRule
dashboard_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit
card_key Yes 1 to 40 lowercase letters, digits, hyphens and underscores, starting with a letter or digit

send_alert

Sends an alert to everyone in the organization. It arrives on their iPhone as a push notification and stays in the app's Alerts feed. It cannot be edited or deleted afterwards. Severity sets how it arrives: info is silent, warning makes a sound, critical is time-sensitive and gets through most Focus modes. Send only what the user would want to be interrupted for. To make a retried script safe, give a repeat_key: a second alert from you with the same repeat_key within 24 hours is not sent, and the first alert is returned with duplicate true. Limits: 6 alerts a minute per agent, and 30 an hour and 100 a day per organization.

FieldRequiredRule
title Yes Up to 60 characters. The notification's title.
summary Yes Up to 180 characters. The notification's text and the feed's summary.
severity No info (default, silent), warning (sound) or critical (time-sensitive).
repeat_key No Optional. A second alert from you with this key within 24 hours is ignored.

list_alerts

Lists alerts sent to the organization by any agent, newest first, so you can check what was already said before sending more. Pass next_before_alert_id from one page as before_alert_id to get the next.

FieldRequiredRule
limit No 1 to 50, default 20.
before_alert_id No Only alerts older than this one.

Cards

A dashboard is an ordered list of up to 30 cards; an organization has up to 50 dashboards. Every card has a card_key (unique on its dashboard) and a type. Keys are 1 to 40 lowercase letters, digits, hyphens and underscores. Sending content under an existing key updates it; a new key creates it, so a script can send the same keys every run. Statboy lays cards out itself: two stats side by side, everything else full width.

A dashboard is stale when no card data has arrived for stale_after_minutes (default 1440, or "never"); the app then shows it greyed with an amber badge. Sending the same values again keeps it fresh. Renaming, reordering and deleting do not.

Limits: 1,000 dashboard changes per organization per hour. Every successful dashboard or card action counts as one, so send whole dashboards with replace_dashboard rather than one card at a time when you can.

Responses

Limits

Errors

An error is a JSON object with a stable code and a message that says what to do. Fix what it says and try again.

{"error": {"code": "invalid", "message": "The `title` is 75 characters; the limit is 60.", "problems": [...]}}
CodeHTTP
unauthenticated401
connect_code_invalid401
revoked401
expired401
forbidden403
name_required409
name_taken409
already_connected409
not_found404
invalid422
limit_reached409
rate_limited429
unknown_action404
too_large413
internal500