# Alerts & escalation

Source: https://www.pingtower.com/docs/service/alerts/

An alert has three states and two verbs. Everything about paging follows from that.

<div class="docs-flow"><span class="st open">firing</span><span class="ar">→</span><span class="st ack">acked</span><span class="ar">→</span><span class="st res">resolved</span></div>


- **Firing** means nobody has claimed it. It re-pages on its rule's cadence and climbs its escalation ladder. In the app this is the Open filter.
- **Acked** means someone is on it. Paging stops. The count keeps climbing if lines keep matching, so you can watch whether your fix worked.
- **Resolved** means done. The alert leaves the open feed, stops counting toward the project's `open_alerts`, and stays in history for thirty days by default.

## What an alert carries

| Field | Meaning |
| --- | --- |
| `id` | Stable id, used by ack and resolve. |
| `project`, `rule` | Which rule opened it. |
| `state` | `firing`, `acked` or `resolved`. |
| `level` | The highest level seen among its lines. |
| `count` | Matching lines since it opened. |
| `escalation_level` | Which rung of the ladder it has reached. 0 is the rule's own recipients. |
| `template` | The recovered shape that matched. |
| `last_message` | The most recent raw line, so the notification says something useful. |
| `first_seen`, `last_seen` | When it opened and when the last line matched. |
| `identifiers` | The key values that split this alert from its siblings, when the rule uses `identifier_keys`. |
| `page_accounts` | Who the current escalation rung is paging, when it narrows the audience. |
| `investigate` | The rule asked the app to lead with the log tail. |

## Reading the feed

<span class="pill get">GET</span> `/v1/pull?cursor=N&wait=S` returns every alert changed since cursor `N` and the next cursor. `wait` parks the request for up to that many seconds if nothing has changed, which is how the app keeps a live feed without polling in a loop. `wait=0` returns immediately.

```sh
curl -s "$PT/v1/pull?cursor=0" -H "Authorization: Bearer ptk_…"
```

## Ack and resolve

<span class="pill post">POST</span> `/v1/alerts/{id}/ack` and <span class="pill post">POST</span> `/v1/alerts/{id}/resolve`. Both return the alert as it now stands. Acking an alert that is already acked, or resolving one already resolved, returns `200` with the unchanged alert; only an unknown id is a `404`. The app uses exactly these routes, so anything it can do a script can do.

Both are written to the [audit log](/docs/service/team/#audit-log) with who did it.

## Who gets paged

Every device of every member of the tenant gets a push for every alert event. An escalation rung that names schedules or accounts narrows that event's audience to those people, and that is also the only event delivered as a [critical alert](/docs/ios/critical/). Webhook, Slack and Telegram [integrations](/docs/service/integrations/) receive the same events, filtered however each integration was configured.

| Event | When |
| --- | --- |
| `alert.opened` | The rule fired and no matching alert was firing. |
| `alert.bumped` | Another line folded into a firing alert. |
| `alert.escalated` | A ladder rung's `after_minutes` passed without an ack, or a renotify fired. |
| `alert.acked` | Someone acked. |
| `alert.resolved` | Someone resolved, or quiet time ran out. |
