# Budget & loop notifications (/docs/rules/notifications)



When a rule notifies you — or a spending limit is crossed, or a loop trips — TokenPolice needs
somewhere to send the alert. One thing always happens for free, and the rest you wire up once.

## The in-app inbox (always on) [#the-in-app-inbox-always-on]

Every alert lands in the in-app inbox at
[app.tokenpolice.ai/dashboard/notifications](https://app.tokenpolice.ai/dashboard/notifications),
whether or not you've set up any channels. **It cannot be turned off**, and no throttle ever
suppresses it — it is the complete record of everything that fired. See
[Notifications in the dashboard](/docs/dashboard/notifications).

## Channels [#channels]

To get alerts *outside* the app, add a channel at
[app.tokenpolice.ai/channels](https://app.tokenpolice.ai/channels). Channels are **shared across
every project in your workspace**. Five types are supported:

| Channel      | You supply                       | How it's verified                                             |
| ------------ | -------------------------------- | ------------------------------------------------------------- |
| **Email**    | An email address                 | We email a 6-digit code; you enter it.                        |
| **Webhook**  | An HTTPS, publicly reachable URL | We POST a challenge; your endpoint echoes it back with a 2xx. |
| **Slack**    | Nothing — one-click OAuth        | Verified when you authorize.                                  |
| **Discord**  | A Discord channel webhook URL    | We check the webhook and post a test message.                 |
| **Telegram** | Nothing — we show a link code    | You message the bot with the code.                            |

Add one with **Add Channel**, name it, then verify it — **Send OTP** for email, **Verify** for
webhook and Discord, **Connect to Slack** for Slack. It moves from **Pending Verification** to
**Active** and gains a **Send test** button.

<Callout type="warn">
  **Only verified channels receive anything.** An unverified channel silently delivers nothing,
  and the rule's alert still lands in your inbox.
</Callout>

Webhook deliveries are signed. Each request carries an `X-TokenPolice-Event-Id` header and an
`X-TokenPolice-Signature` header of the form `t=<unix seconds>,v1=<hex>`, where `v1` is
`HMAC_SHA256(signing secret, "<t>.<raw body>")`. Verify it over the **raw** body with a
constant-time compare. The signing secret is shown once when you create the channel and cannot be
rotated — delete and recreate the channel to change it.

## Choosing what goes where [#choosing-what-goes-where]

Each project has a routing matrix at its **Notification Settings** — a grid of alert categories
against your verified channels. Tick a cell and it saves immediately.

| Category        | Fires on                                                                                                                                                             |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Budget**      | A rule's spending limit being crossed, plus spend-quality alerts (calls we couldn't price, calls with no plan set, plan values that differ only by case or spacing). |
| **Enforcement** | Blocks, reroutes, and entities being armed or released.                                                                                                              |
| **Loops**       | Loop and runaway detection.                                                                                                                                          |

<Callout type="info">
  A channel picked directly on a Notify rule always delivers for that rule, regardless of this
  matrix — the matrix is the default routing for everything else.
</Callout>

## Throttles you'll notice [#throttles-youll-notice]

Alerts are deliberately noisy-proof. None of these ever suppress the in-app inbox, and every one
of them fails open — an infrastructure problem delivers rather than drops.

| Guard                                | Default                                                                          | Applies to         |
| ------------------------------------ | -------------------------------------------------------------------------------- | ------------------ |
| Cooldown between alerts for one rule | 300 seconds (settable, 0 turns it off)                                           | External channels  |
| Maximum alerts per hour for one rule | 20 (settable, 1–100)                                                             | External channels  |
| Identical alerts within 5 minutes    | Grouped into one row with an occurrence count, and the channels are not re-fired | Inbox and channels |
| Alert emails per workspace per day   | 100, plus a 20-email reserve for critical alerts                                 | Email only         |
| Inbox retention                      | 90 days                                                                          | Inbox              |

A failed delivery is retried up to four times in total, backing off 1s, 5s and 25s. The inbox
detail view shows every attempt and its status per channel.

## Next [#next]

<Cards>
  <Card title="Actions" href="/docs/rules/actions" description="Notify rules, and the per-rule cooldown and hourly cap." />

  <Card title="Notifications inbox" href="/docs/dashboard/notifications" description="Read alerts, see per-channel delivery, and manage email preferences." />

  <Card title="Monitor without blocking" href="/docs/recipes/monitor-without-blocking" description="A watch-only setup that alerts you and never stops a call." />
</Cards>
