Account events
Webhooks for changes to keywords, your balance and things that need attention, which are not tied to a mention.
Some things that happen aren't posts. A keyword reaches its cap, the balance runs out, a keyword starts collecting again, or a spike needs a look. No alert rule sends these. Instead, a channel subscribes to them by name with events.
await rumoro.updateChannel({
path: { id: 'dest_...' },
body: { events: ['keyword.capped', 'keyword.paused_for_balance', 'keyword.resumed', 'wallet.low', 'wallet.paused', 'wallet.resumed'] },
});You can also send events on POST /v1/channels. On PATCH it replaces the whole list. The channel shows its list as config.events, which is empty when it subscribes to none. A channel only gets events that happen after it subscribes. Its rules keep working as before.
Slack, email and Telegram channels can subscribe to the four attention events only. Other names return 400. Instead of JSON, they get a one-line "Needs attention" message with an Open in Rumoro link.
The payload
Account events use the normal envelope with alert: null. Check the signature like for any delivery (signature verification).
{
"id": "dlv_...",
"event": "keyword.capped",
"createdAt": "2026-10-04T15:20:00.000Z",
"alert": null,
"data": {
"keyword": { "id": "kw_...", "term": "driftwood", "kind": "brand" },
"cap": { "mentions": 750 },
"thisMonth": 750,
"pausedAt": "2026-10-04T15:20:00.000Z",
"resumesAt": "2026-11-01T00:00:00.000Z"
}
}The events
| Event | Sent when | data |
|---|---|---|
keyword.capped | A keyword reached its monthly cap | keyword, cap.mentions, thisMonth (matches in the month of the pause), pausedAt, resumesAt (the first of next month in UTC, unless you raise or remove the cap before) |
keyword.paused_for_balance | This keyword stopped because the balance ran out | keyword, pausedAt, wallet |
keyword.resumed | The keyword is collecting again | keyword, reason, resumedAt |
wallet.low | The effective balance dropped to 20% of the last credit. Sent once per credit, and not while tracking is paused. | wallet, lastCreditCents, at |
wallet.paused | All keywords stopped for lack of balance | wallet, keywordsPaused, at |
wallet.resumed | A credit covered one day of all keywords | wallet, keywordsResumed, at |
mention.spike | A keyword got far more mentions in the last full hour than usual | attentionId, url, keyword, window, matches, relevant, baseline (meanPerHour, stddevPerHour, hours) |
sentiment.negative_spike | A keyword's share of negative mentions over 24 hours jumped compared with the week before | attentionId, url, keyword, window, negative, relevant, share, baseline (negative, relevant, share) |
keyword.noisy | Most of a keyword's scored matches are noise | attentionId, url, keyword, windowDays, scored, relevant, noiseShare |
channel.failing | A channel's last 5 deliveries in 24 hours all failed | attentionId, url, channel (id, kind, label), failures, lastError, since |
When the whole wallet pauses or restarts, you first get one keyword.paused_for_balance or keyword.resumed per keyword, then wallet.paused or wallet.resumed.
reason on keyword.resumed tells you why.
reason | Meaning |
|---|---|
balance_restored | A credit brought the balance back |
cap_raised | The cap was raised, including when the first top-up lifts the welcome cap |
cap_removed | The cap was removed |
month_turned | A new month started |
wallet is the balance right after the change, with balanceCents, effectiveCents, nextDayCents (one more day of the running keywords), resumeCostCents (one day of all keywords), activeKeywords and pausedKeywords. GET /v1/usage has the current numbers.
Muting or unmuting a keyword yourself sends no event.
Attention events (the last four) go out once, as an attention item opens. attentionId is that item, and GET /v1/attention lists all of them. Their keyword also has name, which is the term, or "term (Group)" for a keyword outside the default group, and groupId. url opens the matching page in the dashboard. See Needs attention.
Delivery
An event is recorded at the moment of the change, and the delivery run that follows, every minute, sends it. You get each event at least once, with the usual retries and the same id on every attempt. In the delivery log they have kind: "event" and the event name. Owners still get their emails about low balance, paused tracking and capped keywords.