Notifications
The inbox, already resolved.
Each notification arrives with its actor and with path, where it
points. Working that out used to be the reader's job: eleven chained
reads, because a reply's address is the address of what it answers
plus an anchor. It is a join, and it happens where the joins are.
The system's own notices, moderation's and Arcade's, arrive with
actor null: they never say which member of staff acted.
path comes without the language prefix (that belongs to the reader),
and comes back null when there is nowhere left to go.
/api/ v1/ notificationsThe inbox, newest first, with the preferences alongside. Each item carries path: where it points, without the language prefix, which belongs to the reader rather than to the notification. It comes back null when there is nowhere left to go (the post is gone, or the reader may no longer see it) and the words then stand without a link, rather than pointing at a page that would refuse them. actor is null on the system's own notices, moderation's and Arcade's: they never say which member of staff acted.
Query
| Field | Type | Notes |
|---|---|---|
limit | integer | How many to bring, 1 to 100. The default is 40. |
Example response
{
"data": [
{
"id": "...",
"kind": "post_comment",
"created_at": "2026-09-05T18:00:00.000Z",
"read_at": null,
"target_title": "Hollow Knight",
"actor": { "username": "ada", "display_name": "Ada", "avatar_url": null },
"path": "review/aB3xY#comment-9kQ2",
"is_reply": true
}
],
"preferences": { "follows_enabled": true, "comments_enabled": true }
}/api/ v1/ notificationsMarks everything unread as read.
/api/ v1/ notifications/ {id}Marks one as read. Doing it twice does not move the time: the second call answers with what the first one wrote.
/api/ v1/ notifications/ preferencesTurns on and off what is worth being told about. Send only what changes.
Body
| Field | Type | Notes |
|---|---|---|
follows_enabled | boolean | True to be told, false not to be. |
review_likes_enabled | boolean | True to be told, false not to be. |
list_likes_enabled | boolean | True to be told, false not to be. |
comments_enabled | boolean | True to be told, false not to be. |
screenshots_enabled | boolean | True to be told, false not to be. |
journal_likes_enabled | boolean | True to be told, false not to be. |
/api/ v1/ notifications/ devicesThe browsers registered to be pushed to, newest first.
/api/ v1/ notifications/ devicesRegisters a browser. Re-subscribing in the same browser returns the same endpoint, so repeating updates the registration rather than making a second one; an endpoint that already belongs to another account answers 409.
Body
| Field | Type | Notes |
|---|---|---|
endpointrequired | string | The address the push service gave this browser. |
p256dhrequired | string | The subscription's public key. |
authrequired | string | The subscription's authentication secret. |
device_label | string | A short name, only so the device can be recognised in the list. |
/api/ v1/ notifications/ devices/ {id}Forgets a device. Its browser stays subscribed with the push service until it unsubscribes, which only it can do.