A real inbox, produced for free.
Every follow, reaction, comment, reply, and vote produces a notification on the recipient's inbox automatically. Self-actions and blocked-pair actions are filtered out at write time, so every row in the read endpoints is already worth showing.
1
Read the inbox
Cursor-paginated, newest first. Pass ?unread_only=true to filter to read_at IS NULL.
curl -H "Authorization: Bearer pcft_live_..." \
"https://agora.productcraft.co/v1/communities/<c>/actors/<carol>/notifications?limit=20"
# unread only
curl -H "Authorization: Bearer pcft_live_..." \
"https://agora.productcraft.co/v1/communities/<c>/actors/<carol>/notifications?unread_only=true&limit=20"{
"data": [
{
"id": "2069ce7e-...",
"kind": "vote",
"actor_id": "<bob>", // who triggered
"recipient_actor_id": "<carol>",
"target_kind": "post",
"target_id": "<carol-poll-post>",
"payload": { "option_index": 2 },
"read_at": null,
"created_at": "2026-05-02T19:35:24.010Z"
},
{ "kind": "follow", "payload": {}, ... },
{ "kind": "reaction", "payload": { "type": "love" }, ... },
{ "kind": "comment_on_post", "payload": { "comment_id": "<comment-uuid>" }, ... },
{ "kind": "reply_to_comment","payload": { "comment_id": "<reply-uuid>" }, ... }
],
"pagination": { "next_cursor": null, "has_more": false }
}Five kinds ship today: follow, reaction, comment_on_post, reply_to_comment, and vote. The mention kind is reserved for a future commit; no producer fires it yet.
2
Unread badge
For the "3" pip on a navbar bell icon, hit the dedicated count endpoint — it's a single SELECT and doesn't pull rows.
curl -H "Authorization: Bearer pcft_live_..." \
https://agora.productcraft.co/v1/communities/<c>/actors/<carol>/notifications/unread-count
# response: { "count": 10 }3
Mark as read
# One notification (PATCH; 204)
curl -X PATCH -H "Authorization: Bearer pcft_live_..." \
-H "content-type: application/json" \
-d '{ "read": true }' \
https://agora.productcraft.co/v1/communities/<c>/actors/<carol>/notifications/<notif-uuid>
# All at once — useful for "mark all as read" controls
curl -X POST -H "Authorization: Bearer pcft_live_..." \
-H "content-type: application/json" \
-d '{}' \
https://agora.productcraft.co/v1/communities/<c>/actors/<carol>/notifications/read-all
# response: { "updated": 9 }
# Pass an optional ?before= timestamp to mark only older ones:
curl -X POST -H "Authorization: Bearer pcft_live_..." \
-H "content-type: application/json" \
-d '{ "before": "2026-05-02T12:00:00Z" }' \
https://agora.productcraft.co/v1/communities/<c>/actors/<carol>/notifications/read-allSuppression
What you don't see
Three classes of notification are never written:
- Self actions — an actor reacting to their own post doesn't notify them.
- Blocked pairs — if Alice blocks Bob, no follow / reaction / comment from Bob shows up on Alice's inbox.
- Story views — views are tracked for the author's viewer list, but they don't spam the inbox. Votes do.
Roadmap
Out of scope (today)
Real-time delivery (SSE / WebSocket), aggregation ("Bob and 3 others reacted"), per-kind preferences, and inbox-side mention parsing are not in v1. The shape leaves room for them — when they ship, existing clients keep working.