Skip to main content

Notification System API

Ring Platform's comprehensive notification system provides multi-channel delivery with smart targeting and user preferences.

Overview​

The notification system supports:

  • Multi-Channel Delivery: In-app, email, SMS, and push notifications
  • Smart Targeting: Role-based and preference-driven notifications
  • User Preferences: Granular control over notification types and channels
  • Analytics Ready: Built-in tracking and delivery monitoring
  • Internationalized: Full Ukrainian/English notification support
  • Event-Driven: Automatic triggers for all platform activities

Base URL​

Development: http://localhost:3000/api
Production: https://ring.ck.ua/api

Authentication​

All notification endpoints require authentication via NextAuth.js session:

headers: {
'Cookie': 'next-auth.session-token=<token>'
}

API Endpoints​

Get User Notifications​

Retrieve a paginated list of notifications for the authenticated user.

Endpoint: GET /api/notifications

Query Parameters:

  • limit (number, optional): Maximum number of notifications to return (default: 20)
  • startAfter (string, optional): Document ID to start pagination after
  • unreadOnly (boolean, optional): Only return unread notifications
  • stats (boolean, optional): Return notification statistics instead of list
  • types (string, optional): Comma-separated list of notification types to filter

Response:

interface NotificationListResponse {
notifications: Notification[];
unreadCount: number;
totalCount: number;
hasMore: boolean;
lastVisible?: string;
}

interface Notification {
id: string;
userId: string;
type: NotificationType;
priority: NotificationPriority;
status: NotificationStatus;
trigger: NotificationTrigger;
title: string;
body: string;
actionText?: string;
actionUrl?: string;
data: NotificationData;
channels: NotificationChannel[];
deliveries: NotificationDelivery[];
createdAt: Date;
readAt?: Date;
scheduledFor?: Date;
expiresAt?: Date;
templateId?: string;
locale: string;
}

Example Request:

curl -X GET "http://localhost:3000/api/notifications?limit=10&unreadOnly=true" \
-H "Cookie: next-auth.session-token=<token>"

Example Response:

{
"notifications": [
{
"id": "notif_123",
"userId": "user_456",
"type": "SYSTEM_ANNOUNCEMENT",
"priority": "HIGH",
"status": "DELIVERED",
"trigger": "ADMIN_ACTION",
"title": "New Feature Available",
"body": "Check out our new notification system!",
"actionText": "Learn More",
"actionUrl": "/features/notifications",
"data": {
"featureId": "notifications"
},
"channels": ["IN_APP", "EMAIL"],
"deliveries": [
{
"channel": "IN_APP",
"status": "DELIVERED",
"retryCount": 0,
"deliveredAt": "2024-01-15T10:30:00Z"
}
],
"createdAt": "2024-01-15T10:30:00Z",
"scheduledFor": null,
"expiresAt": null,
"templateId": "system_announcement",
"locale": "en"
}
],
"unreadCount": 5,
"totalCount": 42,
"hasMore": true,
"lastVisible": "notif_123"
}

Get Notification Statistics​

Get notification statistics for the authenticated user.

Endpoint: GET /api/notifications?stats=true

Response:

interface NotificationStatsResponse {
unreadCount: number;
totalCount: number;
typeBreakdown: Record<NotificationType, number>;
channelBreakdown: Record<NotificationChannel, number>;
recentActivity: {
last7Days: number;
last30Days: number;
};
}

Example Response:

{
"unreadCount": 5,
"totalCount": 42,
"typeBreakdown": {
"SYSTEM_ANNOUNCEMENT": 10,
"ENTITY_VERIFICATION": 8,
"OPPORTUNITY_UPDATE": 15,
"WALLET_TRANSACTION": 9
},
"channelBreakdown": {
"IN_APP": 42,
"EMAIL": 35,
"SMS": 12,
"PUSH": 28
},
"recentActivity": {
"last7Days": 12,
"last30Days": 35
}
}

Create Notification (Admin Only)​

Create a new notification. Only administrators can create manual notifications via API.

Endpoint: POST /api/notifications

Request Body:

interface CreateNotificationRequest {
userId?: string; // Single user target
userIds?: string[]; // Multiple user targets
type: NotificationType;
priority?: NotificationPriority;
title: string;
body: string;
data?: NotificationData;
channels?: NotificationChannel[];
scheduledFor?: Date;
expiresAt?: Date;
actionText?: string;
actionUrl?: string;
templateId?: string;
}

Example Request:

curl -X POST "http://localhost:3000/api/notifications" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=<admin-token>" \
-d '{
"userIds": ["user_123", "user_456"],
"type": "SYSTEM_ANNOUNCEMENT",
"priority": "HIGH",
"title": "Maintenance Scheduled",
"body": "The platform will be under maintenance tonight from 2-4 AM UTC.",
"actionText": "View Details",
"actionUrl": "/maintenance",
"channels": ["IN_APP", "EMAIL"],
"scheduledFor": "2024-01-15T20:00:00Z",
"expiresAt": "2024-01-16T04:00:00Z"
}'

Mark Notification as Read​

Mark a specific notification as read for the authenticated user.

Endpoint: POST /api/notifications/[id]/read

URL Parameters:

  • id (string, required): The notification ID

Example Request:

curl -X POST "http://localhost:3000/api/notifications/notif_123/read" \
-H "Cookie: next-auth.session-token=<token>"

Response:

{
"success": true,
"readAt": "2024-01-15T14:30:00Z"
}

Mark All Notifications as Read​

Mark all notifications as read for the authenticated user.

Endpoint: POST /api/notifications/read-all

Example Request:

curl -X POST "http://localhost:3000/api/notifications/read-all" \
-H "Cookie: next-auth.session-token=<token>"

Response:

{
"success": true,
"markedCount": 12
}

Get User Notification Preferences​

Retrieve notification preferences for the authenticated user.

Endpoint: GET /api/notifications/preferences

Response:

interface DetailedNotificationPreferences {
id: string;
userId: string;
language: 'en' | 'uk';
timezone: string;
enabled: boolean;
channels: {
inApp: boolean;
email: boolean;
sms: boolean;
push: boolean;
};
types: {
systemAnnouncements: boolean;
entityVerification: boolean;
opportunityUpdates: boolean;
walletTransactions: boolean;
securityAlerts: boolean;
marketingOffers: boolean;
};
quiet_hours: {
enabled: boolean;
start: string; // "22:00"
end: string; // "08:00"
};
frequency: {
digest: 'real_time' | 'hourly' | 'daily' | 'weekly';
batching: boolean;
};
createdAt: Date;
updatedAt: Date;
}

Example Response:

{
"id": "pref_123",
"userId": "user_456",
"language": "en",
"timezone": "Europe/Kiev",
"enabled": true,
"channels": {
"inApp": true,
"email": true,
"sms": false,
"push": true
},
"types": {
"systemAnnouncements": true,
"entityVerification": true,
"opportunityUpdates": true,
"walletTransactions": true,
"securityAlerts": true,
"marketingOffers": false
},
"quiet_hours": {
"enabled": true,
"start": "22:00",
"end": "08:00"
},
"frequency": {
"digest": "real_time",
"batching": false
},
"createdAt": "2024-01-10T12:00:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}

Update User Notification Preferences​

Update notification preferences for the authenticated user.

Endpoint: PUT /api/notifications/preferences

Request Body:

// Partial update - only include fields to change
interface UpdatePreferencesRequest {
language?: 'en' | 'uk';
timezone?: string;
enabled?: boolean;
channels?: {
inApp?: boolean;
email?: boolean;
sms?: boolean;
push?: boolean;
};
types?: {
systemAnnouncements?: boolean;
entityVerification?: boolean;
opportunityUpdates?: boolean;
walletTransactions?: boolean;
securityAlerts?: boolean;
marketingOffers?: boolean;
};
quiet_hours?: {
enabled?: boolean;
start?: string;
end?: string;
};
frequency?: {
digest?: 'real_time' | 'hourly' | 'daily' | 'weekly';
batching?: boolean;
};
}

Example Request:

curl -X PUT "http://localhost:3000/api/notifications/preferences" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=<token>" \
-d '{
"channels": {
"sms": true
},
"types": {
"marketingOffers": true
},
"quiet_hours": {
"enabled": true,
"start": "23:00",
"end": "07:00"
}
}'

Data Types​

NotificationType​

enum NotificationType {
SYSTEM_ANNOUNCEMENT = 'SYSTEM_ANNOUNCEMENT',
ENTITY_VERIFICATION = 'ENTITY_VERIFICATION',
OPPORTUNITY_UPDATE = 'OPPORTUNITY_UPDATE',
WALLET_TRANSACTION = 'WALLET_TRANSACTION',
SECURITY_ALERT = 'SECURITY_ALERT',
MARKETING_OFFER = 'MARKETING_OFFER',
USER_MENTION = 'USER_MENTION',
MESSAGE_RECEIVED = 'MESSAGE_RECEIVED'
}

NotificationPriority​

enum NotificationPriority {
LOW = 'LOW',
NORMAL = 'NORMAL',
HIGH = 'HIGH',
URGENT = 'URGENT'
}

NotificationChannel​

enum NotificationChannel {
IN_APP = 'IN_APP',
EMAIL = 'EMAIL',
SMS = 'SMS',
PUSH = 'PUSH'
}

NotificationStatus​

enum NotificationStatus {
PENDING = 'PENDING',
DELIVERED = 'DELIVERED',
READ = 'READ',
FAILED = 'FAILED',
EXPIRED = 'EXPIRED'
}

Error Handling​

All endpoints return appropriate HTTP status codes:

  • 200 OK - Successful request
  • 201 Created - Notification created successfully
  • 400 Bad Request - Invalid request data
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Insufficient permissions
  • 404 Not Found - Notification not found
  • 500 Internal Server Error - Server error

Error Response Format:

{
"error": "Error message describing what went wrong"
}

Rate Limiting​

  • GET /api/notifications: 100 requests per minute per user
  • POST /api/notifications: 10 requests per minute per admin
  • POST /api/notifications/[id]/read: 200 requests per minute per user
  • POST /api/notifications/read-all: 5 requests per minute per user
  • Preferences endpoints: 20 requests per minute per user

Integration Examples​

React Hook for Notifications​

import { useState, useEffect } from 'react';
import { useSession } from 'next-auth/react';

export function useNotifications() {
const { data: session } = useSession();
const [notifications, setNotifications] = useState([]);
const [unreadCount, setUnreadCount] = useState(0);
const [loading, setLoading] = useState(false);

const fetchNotifications = async (params = {}) => {
if (!session) return;

setLoading(true);
try {
const queryParams = new URLSearchParams({
limit: '20',
...params
});

const response = await fetch(`/api/notifications?${queryParams}`);
const data = await response.json();

setNotifications(data.notifications);
setUnreadCount(data.unreadCount);
} catch (error) {
console.error('Failed to fetch notifications:', error);
} finally {
setLoading(false);
}
};

const markAsRead = async (notificationId) => {
try {
await fetch(`/api/notifications/${notificationId}/read`, {
method: 'POST'
});

// Update local state
setNotifications(prev =>
prev.map(notif =>
notif.id === notificationId
? { ...notif, readAt: new Date(), status: 'READ' }
: notif
)
);
setUnreadCount(prev => Math.max(0, prev - 1));
} catch (error) {
console.error('Failed to mark notification as read:', error);
}
};

const markAllAsRead = async () => {
try {
const response = await fetch('/api/notifications/read-all', {
method: 'POST'
});
const { markedCount } = await response.json();

setNotifications(prev =>
prev.map(notif => ({
...notif,
readAt: new Date(),
status: 'READ'
}))
);
setUnreadCount(0);
} catch (error) {
console.error('Failed to mark all notifications as read:', error);
}
};

useEffect(() => {
fetchNotifications();
}, [session]);

return {
notifications,
unreadCount,
loading,
fetchNotifications,
markAsRead,
markAllAsRead
};
}

Notification Service Worker​

// sw.js - Service Worker for push notifications
self.addEventListener('push', event => {
if (!event.data) return;

const notification = event.data.json();
const { title, body, actionUrl, data } = notification;

const options = {
body,
icon: '/icons/ring-192.png',
badge: '/icons/ring-badge.png',
data: {
url: actionUrl || '/',
...data
}
};

event.waitUntil(
self.registration.showNotification(title, options)
);
});

self.addEventListener('notificationclick', event => {
event.notification.close();

const urlToOpen = event.notification.data.url;

event.waitUntil(
clients.openWindow(urlToOpen)
);
});

Best Practices​

  1. Pagination: Always use pagination for notification lists
  2. Real-time Updates: Consider WebSocket connections for real-time notifications
  3. Error Handling: Implement proper error handling and retry logic
  4. User Preferences: Respect user notification preferences
  5. Rate Limiting: Implement client-side rate limiting to avoid API limits
  6. Caching: Cache notification data appropriately with proper invalidation
  7. Accessibility: Ensure notifications are accessible to all users

Testing​

Use the interactive Notification System Jupyter notebook for comprehensive API testing and exploration.