> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage & delivery anomaly alerts

> Self-serve alert rules on SMS delivery rate, outbound message volume, and spend — set a hard threshold or ask Devotel Orbit's learned baseline to spot the spike, and get an in-app notification the moment it fires.

# Usage & delivery anomaly alerts

Three signals tell you a CPaaS account is heading toward trouble before the invoice does: the **SMS delivery rate** collapsing (usually a carrier or route problem), **outbound message volume** surging (usually a compromised API key or a bot-driven SMS-pumping run), and **spend** climbing past what the account ever spends (bill shock in the making). This page covers the self-serve alert rules you point at those metrics — one rule per metric, either a hard threshold ("delivery below 95%") or an anomaly mode that learns your own baseline and reacts to a sharp deviation without you naming a number.

***

## 1. The three metrics

| Metric                      | What it measures                                                                                                                       | Alerts on       |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| **SMS delivery rate**       | Share of terminal outbound SMS that delivered, using the same dashboard-matching status counting as the Insights deliverability cards. | A sudden drop.  |
| **Outbound message volume** | Count of outbound messages sent.                                                                                                       | A sudden spike. |
| **Spend**                   | Wallet debits aggregated across the whole account, excluding operator adjustments applied to your balance.                             | A sudden spike. |

## 2. Two rule modes

A **threshold** rule compares a fixed numeric condition against the metric over a lookback window — "delivery rate below 95% over the last 3 days", "spend at or above \$500/day over the last 7 days". You name the comparator and the number.

An **anomaly** rule drops the numbers entirely: Orbit scores the metric against roughly four weeks of your own daily history and fires when the latest day deviates sharply from that learned baseline — a collapse for delivery, a surge for volume or spend. Pick anomaly when you don't know what "normal" looks like yet, or when a hard number would need a per-customer tuning pass. Threshold remains the right choice when you have an SLO in writing.

## 3. Create a rule

Rules are managed over `/api/v1/usage/alert-rules`. Threshold example:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/usage/alert-rules \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "SMS delivery below 95%",
    "metric": "sms_delivery_rate",
    "mode": "threshold",
    "comparator": "lt",
    "threshold": 95,
    "window_days": 3
  }'
```

Anomaly example (no comparator, no threshold):

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/usage/alert-rules \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Outbound volume surge",
    "metric": "outbound_message_volume",
    "mode": "anomaly"
  }'
```

Per-tenant limits and defaults: 50 rules per account, window 1–30 days (default 7), one notification channel today — the in-app notification feed with a direct link to the metric page. Writes need an owner, admin, or developer role; reads are available to any authenticated member.

| Field             | Notes                                                                                                              |
| ----------------- | ------------------------------------------------------------------------------------------------------------------ |
| `name`            | Free-text label, shown in the fired-notification subject.                                                          |
| `metric`          | `sms_delivery_rate`, `outbound_message_volume`, or `spend`.                                                        |
| `mode`            | `threshold` or `anomaly`. Threshold rules require both `comparator` and `threshold`.                               |
| `comparator`      | `gt` / `gte` (alert when the value goes over your line) or `lt` / `lte` (alert when it dips under).                |
| `threshold`       | The numeric condition, in the metric's native unit (percent / count / dollars).                                    |
| `window_days`     | Lookback the threshold value is aggregated over, 1–30 days.                                                        |
| `notify_channels` | `["in_app"]` today; the list shape exists so email or webhook delivery can plug in later without a payload change. |
| `cooldown_hours`  | How long the rule stays quiet after firing, 1–720 hours (default 24).                                              |
| `enabled`         | Toggle without deleting. Defaults on.                                                                              |

`PATCH /usage/alert-rules/:id` accepts the same fields minus `metric`/`mode` (those are fixed at creation), and `DELETE /usage/alert-rules/:id` removes it. A threshold rule can't be edited into a state with no comparator or no threshold.

## 4. What fires, and the smart-buffered throttle

Two things decide when the platform actually lands a notification on your feed instead of silently updating the rule status:

1. **Edge-triggered.** A rule notifies when it transitions from healthy into breach — not on every evaluation tick while it stays breached.
2. **Cooldown-gated re-fire.** If the breach persists past `cooldown_hours`, one fresh notification goes out (with the cooldown start re-stamped), keeping a stuck-at-the-line metric from ringing your feed every ten minutes.

The fired event lands in the account's notification feed with the rule name, the value at fire time (e.g. "Outbound message volume looks anomalous — the latest daily reading (4,832) deviates sharply from its recent baseline"), and a direct link to the metric — read them via `GET /usage/alert-rules/events` (newest first, 50 kept). The rule's own last evaluation result (`ok` / `breached` / `insufficient_data`) and the value are returned on `GET /usage/alert-rules`, so a dashboard card can render them without extra calls.

## 5. Evaluate now, and insufficient data

`POST /usage/alert-rules/evaluate` triggers your account's rules on demand — handy when wiring the rule into a dashboard widget or smoke-testing a new rule before leaving it armed. Evaluation is also run on a scheduled sweep against every account that defined at least one rule, so threshold and anomaly checks fire even while nobody has the dashboard open.

`insufficient_data` means exactly that: a metric with too little history (your first couple of days on the metric), zero observations in the lookback window, or a resolution hiccup. It never fires — a degraded signal reports "we couldn't judge", never "breached".

## 6. Recommended throttles and pairing

A breach tells you *where* to act. The durable pairing for the spike-shaped metrics (volume, spend surges) is to add a hard ceiling that stops the burn until a human can look: set a per-channel spend cap or a spend-percentage rule on **Billing → Alerts** alongside the anomaly rule, so the spike informs while the cap enforces. Delivery drops usually want the opposite — investigate the route and pause a campaign, not clamp it.
