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 fieldsGlossarySources
The source is the name your phone shows for the sender, and each distinct name becomes its own row in the app's Sources tab, where it can be muted, silenced, coloured or given its own tone. That only works if each name means one thing:
Choosing a source#
- Give every script or job its own name, and keep it the same on every run:
"Nightly backup","CI","Certificate renewal","Price watcher". - Do not use a machine or account name (
"home-server","MacBook","cron") for several jobs. They all land in one row, so muting the chatty one mutes the one you cannot miss. - Do not put changing details in it (a date, a count, a hostname per run). Every variant becomes
a new row. Put those in the
titleorbodyinstead. - Something that watches other jobs (a watchdog, a health check) should send under the name of the job it is reporting on, so its alert sits with that job's own notifications.
A name appears the first time it is used. A job that only sends when something breaks would then
be missing from Sources until the night it fails, so it can register its name first, sending
nothing (below). Renaming a sender starts a new row, and the old one can be removed with
DELETE /v1/sources/{id} or in the app.
POST /v1/sources#
List a source in the app before it has sent anything, so it can be muted, capped or given a tone
ahead of time. Same key as /v1/notify; free, and not counted against the hourly limit.
POST /v1/sources
X-Nowlark-Key: nlk_…
Content-Type: application/json
{"source": "Nightly backup"}
{"id": "src_…", "name": "Nightly backup", "created": true}
created: false means the name was already there; nothing changes, which makes it safe at the
top of every run. It does bring back a name removed in the app, so the Python client remembers what
it has registered (nowlark.register("Nightly backup")) and asks once per name per machine; from a
shell, nowlark --register "Nightly backup". 409 too_many_sources past 500 names on one account.