Files
nick-doc/03 - API Reference/Notification API.md
Siavash Sameni 9698ec5809 docs: align API reference and data model docs with code reality
API Reference (9 files updated):
- Marketplace API: corrected offer endpoints (scoped under /purchase-requests/:id/offers),
  marked phantom /search /stats /seller/:sellerId /withdraw routes as NOT IMPLEMENTED,
  documented PUT→PATCH mismatches, removed invalid SellerOffer 'active' status
- Dispute API: corrected resolve schema (action enum), categories (no 'fraud'),
  removed 'under_review' status, added security callouts (3 unguarded endpoints),
  route shadowing documented, all socket events marked as TODO stubs
- Notification API: corrected mark-all-read method+path, fixed broken GET /:id,
  added unread-count-update event, 90-day TTL documented
- Payment API: /create→/save, removed 10+ phantom endpoints, fixed release/refund
  paths (no /shkeeper/ segment), added 3 unauthenticated endpoint security warnings,
  stats undercounting documented, export privilege gap documented
- Authentication API: 8-digit→6-digit code, no-complexity warning on reset-with-code,
  rate limiter counts all attempts, passkey stub claims removed, deleteAccount bug noted
- Admin API: PUT→PATCH bug documented, wrong status values documented, hard vs soft
  delete clarified, scanner no-auth security bug, 3 NOT IMPLEMENTED endpoints
- Chat API: file upload wrong endpoint bug, archive PUT→PATCH bug, rate limits added
- Points API: corrected redeem schema, referral triggers on 'completed' only,
  leaderboard period ignored, removed 'refund' PointTransaction type
- Socket Events: removed request-cancelled, notification-read; added unread-count-update;
  dispute events all stubs; referral-signup is auth-domain not points-domain

Data Models (3 files updated):
- SellerOffer: removed 'active' from status enum, withdrawOffer() is dead code
- PurchaseRequest: added pending_payment/active statuses, added 'urgent' urgency,
  corrected description minimum (5 chars), removed finalized/archived
- Dispute: corrected action enum, categories (no fraud), removed under_review,
  security callout on unguarded status/resolve endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:57:47 +04:00

4.8 KiB

title, tags
title tags
Notification API
api
notification
reference

Notification API

Last updated: 2026-05-29 — aligned with code (see Doc vs Code Audit Report)

Endpoints live under /api/notifications/*. Two routers are mounted:

Both routers are mounted at /api, so the paths collide; the controller router wins for the shared paths (it is mounted first). The legacy router is still used by background scripts and admin tools that have no JWT context.

Model: Notification. Notifications are auto-deleted after 90 days. Real-time delivery is via new-notification and unread-count-update Socket.IO events on user-<userId>. See Socket Events.

List

GET /api/notifications

Description: Paginated notifications for the caller. Auth required: Bearer JWT (controller route); legacy variant takes ?userId=.... Query params:

  • page (default 1)
  • limit (default 20)
  • unreadOnly (true | false, default false) Response 200:
{
  "success": true,
  "data": {
    "notifications": [Notification, ...],
    "pagination": { "page": 1, "limit": 20, "total": 42, "hasMore": true }
  }
}

GET /api/notifications/unread-count

Description: Just the integer unread count. Auth required: Bearer JWT Response 200: { "success": true, "data": { "unreadCount": 5 } }

GET /api/notifications/:id

Description: Single notification by id. Available on the controller router. Auth required: Bearer JWT Errors: 404 not found, 403 not owner.

⚠️ KNOWN BUG: The controller fetches only the 1 most-recent notification for the user and does an in-memory ID match. Any notification that is not the user's single latest will return 404 even if it exists and belongs to the user. Do not rely on this endpoint for fetching arbitrary notifications by id.

Mutations

PATCH /api/notifications/:id/read

Description: Mark one notification as read. Auth required: Bearer JWT (controller); legacy variant requires { userId } in body. Response 200: { success: true, data: { /* updated notification */ } } Side effects: Emits unread-count-update to user-<userId>.

PATCH /api/notifications/mark-all-read

Description: Mark every notification for the caller as read. Auth required: Bearer JWT Response 200: { "success": true, "data": { "modifiedCount": 12 } }

Note: Earlier versions of this documentation incorrectly listed this as POST /api/notifications/read-all. The correct path and method are PATCH /notifications/mark-all-read.

PATCH /api/notifications/bulk/mark-read

Description: Mark a list of notifications as read. Auth required: Bearer JWT Request body: { ids: string[] } Response 200: { success, data: { modifiedCount } }

DELETE /api/notifications/:id

Description: Delete a notification. Auth required: Bearer JWT Errors: 404 not found.

DELETE /api/notifications/bulk/delete

Description: Bulk delete. Auth required: Bearer JWT Request body: { ids: string[] }

POST /api/notifications

Description: Create a notification. Primarily used by other services and admin tools. Auth required: Bearer JWT (controller); legacy variant is open. Request body:

{
  userId: string;
  type: string;                // e.g. "order_update", "chat_message", "payment_received"
  title: string;
  body?: string;
  data?: Record<string, unknown>;
  channel?: "in_app" | "email" | "push";
}

Response 201: { success, data: { notification } } Side effects: Emits new-notification to user-<userId>; also increments unread count via unread-count-update.

Real-time socket events

new-notification

Emitted to user-<userId> when a new notification is created for that user.

unread-count-update

Emitted to user-<userId> whenever the unread notification count changes (e.g. after marking one or all as read, or after a new notification arrives). This is the canonical cross-tab sync event.

Note: Earlier docs referenced a notification-read socket event for cross-tab sync. That event does not exist. The real event is unread-count-update.

Preferences

Notification preferences live on User (preferences.notifications.email | sms | push). They are read and written through the User API (GET /api/user/profile, PUT /api/user/profile).

Data retention

Notifications are automatically deleted after 90 days.