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 fieldsGlossaryAccount endpoints
Used by the iOS app. Every one takes an account key, and every one is scoped to that account's own data. An id belonging to someone else returns 404, never their row.
Identity#
| Method | Path | Notes |
|---|---|---|
POST |
/v1/enroll |
Creates an account, returns account_key once. No credentials required; capped per IP address. |
GET |
/v1/me |
Account summary: device count, key count, unread count, features (what the Upgrade Pass has unlocked), history_days (the length in force) and history_choices (the lengths on offer, first one free) |
PUT |
/v1/me/history |
{"days": 90}. One of history_choices: 30 for everyone, 90, 180 or 365 with the Upgrade Pass (402 upgrade_required without it, 400 for a length not on offer). Answers with the history_days now in force. Shortening deletes what is older than the new length at the next hourly purge, and it does not come back. |
PUT |
/v1/me/sounds |
{"normal": "chime",: the tone per priority, from sound_choices (in /v1/me, with sounds, the current choices). A level left out is unchanged; null goes back to the system sound and needs no pass. Choosing a tone is part of the Upgrade Pass (402 upgrade_required); a name not on offer is 400. Priorities -2 and -1 stay silent whatever is chosen. |
PUT |
/v1/me/repeat |
{"every": 300,, in seconds, either one optional. every is one of repeat_every_choices (0 is off), for one of repeat_for_choices; anything else is 400. Answers with the repeat_every and repeat_for now in force, which /v1/me also returns. |
PATCH |
/v1/me |
{"display_name": "…"} |
DELETE |
/v1/me |
Erases the account and everything in it. Not a flag: the rows are gone. 409 plan_active while a team it owns has a live subscription with the merchant (the team would go and the charges would not): cancel that first. |
POST |
/ |
{"label": "…",. Replaces this device's key; revoke_others is the lost-iPhone case. |
GET |
/v1/access |
The credentials that can open this account, with current: true on the one in use |
DELETE |
/v1/access/{id} |
Signs one other credential out. Refuses to revoke the caller's own. |
Moving to a phone on another Apple Account#
Normally unnecessary: the account key lives in the iCloud Keychain and in the user's CloudKit private database, so any device on the same Apple Account already has it. This is for the case where the new phone is signed into a different one.
| Method | Path | Notes |
|---|---|---|
POST |
/ |
Returns a code like K4M2-P7QX, valid 10 minutes, single use |
POST |
/ |
{"code": "…"} → a new account key for the same account. The issuing device keeps working. |