List Alert Deliveries
GET/v1/alerts/:alert_id/deliveries
Every send this alert has ever made, newest first. Did it reach anyone?
The answer the product could not give. A fire and a test both hand back a
deliveryId and say "Watch delivery row N"; this is the route that
opens row N — and the whole history beside it. Nothing new is stored: the
rows have been written since the delivery slice shipped, with a
per-recipient outcome and the provider's own words on a failure, and
nothing read them back.
Read status first, and note that SEVEN values are possible, not two:
sent— every attempted recipient was reached.partial— some were, some were not. Derived from the per-recipient outcomes at write time, so "2 of 3" can never round up tosent.failed— nothing reached anybody;recipients[].reasoncarries the provider's words.skipped— there was nobody to send to. Not a failure and not a delivery.pending— claimed and never finished; interrupted mid-send.in_flight— the capture has not settled yet. Come back, do not conclude.not_recorded— the capture settled and no outcome was ever written. The send is UNACCOUNTED FOR: it may have landed, it may never have been attempted. Never read this asfailed.
reachedSomebody is a tri-state for the same reason: null means the
row cannot say, which is not the same as false.
WHEN DID THIS BREACH START? The newest row with kind: "fire". An
alert fires on ENTRY into a breach and stays deliberately quiet while it
persists (that is the hysteresis rule, and it is correct), so a
still-firing alert never mentions itself again — but the fire that opened
the breach is here, dated, with the value that tripped it in
condition. That is the one question GET /v1/alerts/{id} cannot
answer and this route can.
trigger says whether the SCHEDULE asked or a person did. unknown
means the row does not carry the evidence (alert rows written before
2026-09-20 do not) — it is never assumed to be a scheduled run.
VIEW on the alert's dashboard, and it still answers when that dashboard has been deleted: what an alert delivered is history, and history does not stop being true when its subject is removed.
Cursor-paginated. The wire query parameter is exclusiveStartKey (what the cURL tab and the parameter table show); the TypeScript SDK takes it as the exclusiveStartKey option and the Python SDK as the exclusive_start_key keyword — one parameter, spelled per language. Pass the previous page's nextKey and stop when it comes back null — or let iterAll() / iter_all() drive the cursor for you (see the SDKs page, "Pagination").
Request
Responses
- 200
- 404
- 422
Successful Response
Not found
Validation Error