Notifications and watches
Notifications are personal: every call on this page reads or changes the rows of the person the key belongs to. Nobody, including admins, can read another person’s inbox. Marking items read, changing preferences and watching need write scope.
| Method and path | Purpose |
|---|---|
GET /notifications |
Your inbox |
GET /notifications/unread-count |
Unread badge count |
POST /notifications/read |
Mark read |
POST /notifications/seen |
Clear the badge without marking read |
GET /notifications/prefs, PUT /notifications/prefs |
Mute or unmute reasons |
GET /entries/{entry_id}/watch, PUT, DELETE |
Your watch state on one entry |
GET /watches |
Everything you explicitly watch or muted |
Reasons
Section titled “Reasons”| Reason | You get it when |
|---|---|
review.requested |
You were added as a reviewer on a review request. |
review.responded |
A reviewer responded to your review request. |
review.assigned |
A requested change was assigned to you. |
review.mention |
Someone mentioned you in a review request or response note. |
comment.mention |
Someone mentioned you in a comment. |
comment.reply |
Someone replied in your thread. |
comment.new |
Someone commented on an entry you watch. |
comment.resolved |
Your thread was resolved. |
You are never notified of your own actions, and one action produces at most one notification per person (the most specific reason wins, in the order above). The list may grow; ignore reasons you do not recognize.
GET /notifications
Section titled “GET /notifications”| Parameter | Type | Description |
|---|---|---|
unread |
boolean | Only unread items. |
cursor |
integer | Id cursor: pass the previous next_cursor to get older items. |
limit |
integer | 1 to 200, default 50. |
{ "notifications": [ { "id": 802, "reason": "comment.mention", "actor": { "id": 12, "name": "<user>", "display_name": "Lee Lead" }, "entry_id": 412, "lineage_id": "guid:6F9619FF8B86D011B42D00C04FC964FF", "object_id": 1880, "comment_id": 91, "request_id": null, "payload": {}, "seen_at": null, "read_at": null, "created_at": "2026-07-25T12:00:00Z" } ], "next_cursor": null}GET /notifications/unread-count
Section titled “GET /notifications/unread-count”{"unread": 3}. Cheap enough to poll.
POST /notifications/read
Section titled “POST /notifications/read”Send exactly one of:
{ "ids": [802, 801] }{ "all": true, "before_id": 802 }ids takes up to 500 of your notification ids (others are ignored). all marks everything read; add before_id (the newest id you displayed) so an item that arrived meanwhile stays unread. Returns {"updated", "unread"}.
POST /notifications/seen
Section titled “POST /notifications/seen”{"before_id"?}. Marks items as seen (clears a badge) without marking them read. Returns {"updated"}.
Preferences
Section titled “Preferences”GET /notifications/prefs returns your overrides and the full list of reasons:
{ "prefs": [{ "reason": "comment.new", "enabled": false }], "reasons": ["review.requested", "review.responded", "review.assigned", "review.mention", "comment.mention", "comment.reply", "comment.new", "comment.resolved"]}PUT /notifications/prefs replaces all your overrides with {"prefs": [{"reason", "enabled"}]} (up to 32). Reasons not listed are enabled. {"reason": "*", "enabled": false} mutes everything. Unknown reasons are 422. Returns the same shape as GET.
Watches
Section titled “Watches”Watching an entry sends you comment.new notifications for it. The person who created an entry watches it automatically, and commenting on or reviewing an entry also starts watching it, unless you muted it.
| Endpoint | Body | Response |
|---|---|---|
GET /entries/{entry_id}/watch |
Watch state | |
PUT /entries/{entry_id}/watch |
{"state": "watching" or "muted"} (default watching) |
Watch state |
DELETE /entries/{entry_id}/watch |
Watch state after returning to the default | |
GET /watches |
{"watches": [{entry_id, name, state, reason, created_at}]}, newest first |
Watch state:
{ "entry_id": 412, "watching": true, "state": "watching", "reason": "manual", "implicit": false }implicit: true means you watch it only because you created it (no explicit row). A muted state sticks: commenting or reviewing does not undo it.
