Notification endpoints are available to all authenticated users. Each user can only manage their own notifications — there is no admin override for individual notification records.
List notifications
GET /api/system/notifications?action=list
Returns the authenticated user’s notifications, ordered by most recent first.
Permission: All authenticated users
Set to true to return only unread notifications.
Maximum records to return (max 100).
Number of records to skip for pagination.
curl -X GET "https://propops.yourcompany.com/api/system/notifications?action=list&unread_only=true" \
-H "Authorization: Bearer <token>"
{
"success": true,
"data": [
{
"id": 5541,
"type": "job_update",
"title": "Job JOB-1042 status changed",
"message": "Boiler repair — 14 Elm Close has been updated to In Progress",
"resource_type": "job",
"resource_id": "550e8400-e29b-41d4-a716-446655440042",
"is_read": false,
"created_at": "2024-06-14T09:30:00Z"
},
{
"id": 5538,
"type": "case_note",
"title": "New case note on JOB-1038",
"message": "Contractor left a note: Access confirmed for Friday morning",
"resource_type": "job",
"resource_id": "aa11bb22-cc33-4444-dd55-ee6677889900",
"is_read": false,
"created_at": "2024-06-13T16:12:00Z"
}
],
"unread_count": 7,
"total": 142
}
Get a single notification
GET /api/system/notifications?action=get
Returns full details for a specific notification.
Permission: All authenticated users (own notifications only)
curl -X GET "https://propops.yourcompany.com/api/system/notifications?action=get¬ification_id=5541" \
-H "Authorization: Bearer <token>"
Mark notifications as read
Mark a single notification as read
POST /api/system/notifications
Marks one notification as read.
Permission: All authenticated users
Requires CSRF token.
ID of the notification to mark as read.
CSRF token from GET /api/security/csrf-token.
curl -X POST "https://propops.yourcompany.com/api/system/notifications" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"action": "mark_read",
"notification_id": 5541,
"csrf_token": "<csrf-token>"
}'
{
"success": true,
"message": "Notification marked as read"
}
Mark all notifications as read
POST /api/system/notifications
Marks all unread notifications for the authenticated user as read in a single request.
Permission: All authenticated users
Requires CSRF token.
curl -X POST "https://propops.yourcompany.com/api/system/notifications" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"action": "mark_all_read", "csrf_token": "<csrf-token>"}'
{
"success": true,
"message": "All notifications marked as read",
"count": 7
}
Delete a notification
DELETE /api/system/notifications
Permanently deletes a notification from the authenticated user’s inbox.
Permission: All authenticated users (own notifications only)
Requires CSRF token.
ID of the notification to delete.
curl -X DELETE "https://propops.yourcompany.com/api/system/notifications" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"notification_id": 5538, "csrf_token": "<csrf-token>"}'
{
"success": true,
"message": "Notification deleted"
}
Notification types
The type field in notification responses indicates the event that triggered the notification:
| Type | Description |
|---|
job_update | A job you are associated with changed status or was updated |
job_assigned | A job was assigned to you (contractor) or your branch (agent) |
case_note | A new case note was added to a job you follow |
document_uploaded | A document was uploaded to a job you follow |
approval_required | A job requires your approval before it can proceed |
recall_raised | A completed job has been recalled |
certification_expiring | One of your certifications is due to expire within 30 days |
gdpr_request | A GDPR data-subject request has been submitted (Staff only) |
security_alert | A security event requires your attention (Staff only) |
system | A system-generated message (maintenance windows, announcements) |
Code examples
// Fetch unread notifications and mark them all as read
const token = 'Bearer <token>';
const listRes = await fetch(
'/api/system/notifications?action=list&unread_only=true',
{ headers: { Authorization: token } }
);
const { data: notifications, unread_count } = await listRes.json();
if (unread_count > 0) {
const csrfRes = await fetch('/api/security/csrf-token', {
headers: { Authorization: token }
});
const { data: { token: csrfToken } } = await csrfRes.json();
await fetch('/api/system/notifications', {
method: 'POST',
headers: { Authorization: token, 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'mark_all_read', csrf_token: csrfToken }),
});
}