Skip to content

Notifications API

The Notifications API provides endpoints for managing user notifications, reading status, and configuring notification preferences.


Overview

CalcBridge's notification system supports:

  • In-App Notifications: Real-time notification delivery
  • Preferences: Per-user notification type and channel configuration
  • Batch Operations: Mark multiple notifications as read, clear read notifications
  • Priority Levels: Low, normal, high, and urgent notifications

Endpoints

List Notifications

List notifications for the current user with pagination.

GET /api/v1/notifications

Query Parameters

Parameter Type Default Description
page integer 1 Page number (1-indexed)
page_size integer 20 Items per page (max 100)
unread_only boolean false Only return unread notifications
sort_by string created_at Sort field: created_at, priority
sort_order string desc Sort direction: asc, desc

Example Request

curl -X GET "https://api.calcbridge.io/api/v1/notifications?unread_only=true&page_size=50" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.get(
    "https://api.calcbridge.io/api/v1/notifications",
    headers={"Authorization": f"Bearer {token}"},
    params={"unread_only": True, "page_size": 50}
)
notifications = response.json()
for notif in notifications["items"]:
    print(f"[{notif['priority']}] {notif['title']}")
const response = await fetch(
  'https://api.calcbridge.io/api/v1/notifications?unread_only=true&page_size=50',
  { headers: { 'Authorization': `Bearer ${token}` } }
);
const notifications = await response.json();
notifications.items.forEach(notif => {
  console.log(`[${notif.priority}] ${notif.title}`);
});

Response

{
  "items": [
    {
      "id": "notif_abc123",
      "type": "compliance_alert",
      "title": "OC Test Warning",
      "message": "Senior OC test cushion below 2% threshold",
      "priority": "high",
      "is_read": false,
      "read_at": null,
      "metadata": {
        "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
        "test_name": "senior_oc",
        "current_value": 121.8,
        "threshold": 120.0
      },
      "created_at": "2026-01-25T10:30:00Z"
    },
    {
      "id": "notif_def456",
      "type": "export_complete",
      "title": "Export Ready",
      "message": "Your XLSX export of CLO Portfolio Q1 2026 is ready for download",
      "priority": "normal",
      "is_read": false,
      "read_at": null,
      "metadata": {
        "export_id": "exp_abc123",
        "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
        "format": "xlsx"
      },
      "created_at": "2026-01-25T10:15:00Z"
    }
  ],
  "total": 25,
  "page": 1,
  "page_size": 50,
  "total_pages": 1
}

Get Notification Statistics

Get notification counts and breakdown for the current user.

GET /api/v1/notifications/stats

Example Request

curl -X GET "https://api.calcbridge.io/api/v1/notifications/stats" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.get(
    "https://api.calcbridge.io/api/v1/notifications/stats",
    headers={"Authorization": f"Bearer {token}"}
)
stats = response.json()
print(f"Unread: {stats['unread_count']} / {stats['total_count']}")
for ntype, count in stats["by_type"].items():
    print(f"  {ntype}: {count}")
const response = await fetch(
  'https://api.calcbridge.io/api/v1/notifications/stats',
  { headers: { 'Authorization': `Bearer ${token}` } }
);
const stats = await response.json();
console.log(`Unread: ${stats.unread_count} / ${stats.total_count}`);

Response

{
  "total_count": 25,
  "unread_count": 8,
  "by_type": {
    "compliance_alert": 5,
    "export_complete": 3,
    "reconciliation_issue": 10,
    "system": 7
  }
}

Get Notification

Get a single notification by ID.

GET /api/v1/notifications/{notification_id}

Path Parameters

Parameter Type Description
notification_id string Notification identifier

Example Request

curl -X GET "https://api.calcbridge.io/api/v1/notifications/notif_abc123" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.get(
    f"https://api.calcbridge.io/api/v1/notifications/{notification_id}",
    headers={"Authorization": f"Bearer {token}"}
)
notif = response.json()
print(f"[{notif['priority']}] {notif['title']}")
print(f"Message: {notif['message']}")
const response = await fetch(
  `https://api.calcbridge.io/api/v1/notifications/${notificationId}`,
  { headers: { 'Authorization': `Bearer ${token}` } }
);
const notif = await response.json();
console.log(`[${notif.priority}] ${notif.title}`);

Response

{
  "id": "notif_abc123",
  "type": "compliance_alert",
  "title": "OC Test Warning",
  "message": "Senior OC test cushion below 2% threshold",
  "priority": "high",
  "is_read": false,
  "read_at": null,
  "metadata": {
    "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
    "test_name": "senior_oc",
    "current_value": 121.8,
    "threshold": 120.0
  },
  "created_at": "2026-01-25T10:30:00Z"
}

Error Responses

Status Error Description
404 Notification not found Invalid notification_id or access denied

Mark Single Notification as Read

Mark a single notification as read.

PATCH /api/v1/notifications/{notification_id}/read

Path Parameters

Parameter Type Description
notification_id string Notification identifier

Example Request

curl -X PATCH "https://api.calcbridge.io/api/v1/notifications/notif_abc123/read" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.patch(
    f"https://api.calcbridge.io/api/v1/notifications/{notification_id}/read",
    headers={"Authorization": f"Bearer {token}"}
)
notif = response.json()
print(f"Read at: {notif['read_at']}")
const response = await fetch(
  `https://api.calcbridge.io/api/v1/notifications/${notificationId}/read`,
  {
    method: 'PATCH',
    headers: { 'Authorization': `Bearer ${token}` }
  }
);
const notif = await response.json();
console.log('Read at:', notif.read_at);

Response

{
  "id": "notif_abc123",
  "type": "compliance_alert",
  "title": "OC Test Warning",
  "message": "Senior OC test cushion below 2% threshold",
  "priority": "high",
  "is_read": true,
  "read_at": "2026-01-25T11:00:00Z",
  "metadata": {
    "workbook_id": "550e8400-e29b-41d4-a716-446655440000",
    "test_name": "senior_oc"
  },
  "created_at": "2026-01-25T10:30:00Z"
}

Error Responses

Status Error Description
404 Notification not found Invalid notification_id or access denied

Mark Notifications as Read (Batch)

Mark multiple notifications as read in a single request.

POST /api/v1/notifications/mark-read

Request Body

Field Type Required Description
notification_ids string[] Yes Notification IDs to mark as read

Example Request

curl -X POST https://api.calcbridge.io/api/v1/notifications/mark-read \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "notification_ids": ["notif_abc123", "notif_def456", "notif_ghi789"]
  }'
import requests

response = requests.post(
    "https://api.calcbridge.io/api/v1/notifications/mark-read",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "notification_ids": ["notif_abc123", "notif_def456", "notif_ghi789"]
    }
)
# Returns 204 No Content on success
if response.status_code == 204:
    print("Notifications marked as read")
const response = await fetch('https://api.calcbridge.io/api/v1/notifications/mark-read', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    notification_ids: ['notif_abc123', 'notif_def456', 'notif_ghi789']
  })
});
if (response.status === 204) {
  console.log('Notifications marked as read');
}

Response

Returns 204 No Content on success.


Mark All as Read

Mark all notifications as read for the current user.

POST /api/v1/notifications/mark-all-read

Example Request

curl -X POST "https://api.calcbridge.io/api/v1/notifications/mark-all-read" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.post(
    "https://api.calcbridge.io/api/v1/notifications/mark-all-read",
    headers={"Authorization": f"Bearer {token}"}
)
# Returns 204 No Content on success
if response.status_code == 204:
    print("All notifications marked as read")
const response = await fetch('https://api.calcbridge.io/api/v1/notifications/mark-all-read', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${token}` }
});
if (response.status === 204) {
  console.log('All notifications marked as read');
}

Response

Returns 204 No Content on success.


Clear Read Notifications

Delete all read notifications for the current user.

DELETE /api/v1/notifications/clear

Example Request

curl -X DELETE "https://api.calcbridge.io/api/v1/notifications/clear" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.delete(
    "https://api.calcbridge.io/api/v1/notifications/clear",
    headers={"Authorization": f"Bearer {token}"}
)
# Returns 204 No Content on success
if response.status_code == 204:
    print("Read notifications cleared")
const response = await fetch('https://api.calcbridge.io/api/v1/notifications/clear', {
  method: 'DELETE',
  headers: { 'Authorization': `Bearer ${token}` }
});
if (response.status === 204) {
  console.log('Read notifications cleared');
}

Response

Returns 204 No Content on success.


Delete Notification

Delete a specific notification.

DELETE /api/v1/notifications/{notification_id}

Path Parameters

Parameter Type Description
notification_id string Notification identifier

Example Request

curl -X DELETE "https://api.calcbridge.io/api/v1/notifications/notif_abc123" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.delete(
    f"https://api.calcbridge.io/api/v1/notifications/{notification_id}",
    headers={"Authorization": f"Bearer {token}"}
)
# Returns 204 No Content on success
if response.status_code == 204:
    print("Notification deleted")
const response = await fetch(
  `https://api.calcbridge.io/api/v1/notifications/${notificationId}`,
  {
    method: 'DELETE',
    headers: { 'Authorization': `Bearer ${token}` }
  }
);
if (response.status === 204) {
  console.log('Notification deleted');
}

Response

Returns 204 No Content on success.

Error Responses

Status Error Description
404 Notification not found Invalid notification_id or access denied

Get Notification Preferences

Get notification preferences for the current user.

GET /api/v1/notifications/preferences

Example Request

curl -X GET "https://api.calcbridge.io/api/v1/notifications/preferences" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.get(
    "https://api.calcbridge.io/api/v1/notifications/preferences",
    headers={"Authorization": f"Bearer {token}"}
)
prefs = response.json()
print(f"Email: {prefs['email_notifications']}")
print(f"Push: {prefs['push_notifications']}")
for ntype, enabled in prefs["notification_types"].items():
    print(f"  {ntype}: {'enabled' if enabled else 'disabled'}")
const response = await fetch(
  'https://api.calcbridge.io/api/v1/notifications/preferences',
  { headers: { 'Authorization': `Bearer ${token}` } }
);
const prefs = await response.json();
console.log('Email:', prefs.email_notifications);
console.log('Push:', prefs.push_notifications);

Response

{
  "email_notifications": true,
  "push_notifications": false,
  "notification_types": {
    "compliance_alert": true,
    "export_complete": true,
    "reconciliation_issue": true,
    "system": true,
    "insight_ready": false
  }
}

Update Notification Preferences

Update notification preferences for the current user.

PATCH /api/v1/notifications/preferences

Request Body

All fields are optional. Only provided fields are updated.

Field Type Description
email_notifications boolean Enable email delivery
push_notifications boolean Enable push delivery
notification_types object Per-type enable/disable

Example Request

curl -X PATCH https://api.calcbridge.io/api/v1/notifications/preferences \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_notifications": true,
    "push_notifications": true,
    "notification_types": {
      "compliance_alert": true,
      "insight_ready": true
    }
  }'
import requests

response = requests.patch(
    "https://api.calcbridge.io/api/v1/notifications/preferences",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "email_notifications": True,
        "push_notifications": True,
        "notification_types": {
            "compliance_alert": True,
            "insight_ready": True
        }
    }
)
prefs = response.json()
print(f"Email: {prefs['email_notifications']}")
print(f"Push: {prefs['push_notifications']}")
const response = await fetch('https://api.calcbridge.io/api/v1/notifications/preferences', {
  method: 'PATCH',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    email_notifications: true,
    push_notifications: true,
    notification_types: {
      compliance_alert: true,
      insight_ready: true
    }
  })
});
const prefs = await response.json();
console.log('Preferences updated');

Response

{
  "email_notifications": true,
  "push_notifications": true,
  "notification_types": {
    "compliance_alert": true,
    "export_complete": true,
    "reconciliation_issue": true,
    "system": true,
    "insight_ready": true
  }
}

Notification Types

Type Description Default Priority
compliance_alert Compliance test failures or warnings high
export_complete Export job completed normal
reconciliation_issue Reconciliation discrepancy detected high
system System maintenance, updates, announcements low
insight_ready New AI insights are available normal
workbook_shared A workbook was shared with you normal
task_complete Background task completed normal

Priority Levels

Priority Description Use Case
urgent Requires immediate attention Critical compliance breaches
high Important, review soon Compliance warnings, reconciliation errors
normal Standard notification Export completion, sharing, insights
low Informational only System updates, announcements

Best Practices

  1. Configure preferences early: Set up notification types and channels before starting work
  2. Enable compliance alerts: Always keep compliance notifications enabled
  3. Use batch operations: Mark multiple notifications as read in one request
  4. Clear read notifications periodically: Use the clear endpoint to maintain a clean inbox
  5. Monitor statistics: Check the stats endpoint for notification volume trends
  6. Set appropriate priority filters: Focus on high and urgent notifications first