API reference menu
Getting started
OverviewAuthentication and rate limitExamplesSending
Send a notificationPriority and repeatLinks, images and buttonsSourcesScheduled sendsWebhook templatesReceipts and replies
Receipts and callbacksRepliesTeams
Teams, roles and endpointsChannels and escalationWebhooks and emailAlert email and timelineTeam formsPlans, audit log and transferCompany sign‑in and SCIMThe web consoleAccount
Identity and moving phonesDevices, keys and historyThe Upgrade PassCompatibility
ntfy's publish APIProwl's APIAppendix
Endpoint indexErrors and status codesLimitsPriorities and fieldsGlossaryReceipts and callbacks
/v1/receipts/{id}
GET /v1/receipts/{id} with an API key says what became of a notification the account sent:
{"id":"ntf_…","state":"sent","source":"media-01","acknowledged":true,"acknowledged_at":1789665612.4,
"read":false,"read_at":null,"delivered":2,"repeats":3,"repeating":false,"expired":false,"callback":"delivered"}
| Field | Means |
|---|---|
state |
scheduled (waiting), sent, or failed (accepted for later, refused when it fired; error says why) |
acknowledged |
Read, or acknowledged, on any device. acknowledged_at is the earlier of the two |
repeating |
Still alerting because nobody has opened it |
expired |
An Urgent notification whose repeating ran out unopened |
callback |
null if none was asked for, else pending, delivered or failed |
Any key on the account may ask, only for its own account's notifications; another account's id is
404, the same as one that does not exist.
callback_url is called once with POST and {"event":"acknowledged","id","source","acknowledged_at"}
when the notification is first read or acknowledged, by any route. It is a hint, not proof: confirm
with the receipt above, which needs your API key. Tried again after 30 s, 5 min, 30 min and 2 h on
anything but a 2xx, then given up on (callback: "failed"). Delivered within one scheduler tick.
Because Nowlark fetches a URL you chose, it is narrow on purpose: https only, no credentials in
the URL, no localhost, .local or .internal names, and every address the name resolves to must
be a public one (no loopback, private, link-local or cloud-metadata range; one private answer among
public ones refuses all). The request goes to that checked address under your host name, redirects
are not followed, the whole request (name lookup, connecting and the reply) has one 5 second deadline,
and the response body is never read. Callbacks and channel webhooks go out side by side, in their own loop,
so a slow receiver delays no one else's alerts. A literal
non-public address is a 400 when sent; a name that resolves privately later is simply never called.
Deleting the notification before it is seen means no callback.