Skip to main content

Notifications

4 API calls in this section.

Endpoints for listing, acknowledging, marking as read, and getting notification statistics. Acknowledgement is intentionally separate from read state.

List Notifications​

Communications & Feedback / Messaging / Notifications
GET/messaging/notifications

Retrieve the authenticated user's sent notifications, sorted by created_at descending.

Authorization

JWT required. Rows are scoped to the authenticated recipient and tenant.

Filters

page, limit (max 100), read_status=true|false, notification_type, priority=normal|important|critical, display_mode=toast|banner|modal, acknowledged=true|false, and optional tenant_id.

Response contract

Each row includes priority, display_mode, requires_acknowledgement, acknowledged_at, channel_status, template_data, and the existing action. action.secondary_actions may contain copy, call, navigate, or external_url; these actions never acknowledge the row. The response also includes unread_count and pending_critical_count.

Delivery exception decision notification

A delivery_exception_resolved row has associated_entity_type=delivery, associated_entity_id=<deliveryId>, and template_data containing deliveryId, deliveryCode, actionKey (retry or return), isRetry, isReturn, and returnDestinationLabel. It uses priority=critical, display_mode=modal, and requires_acknowledgement=true, so the driver app receives it through GET /messaging/notifications?priority=critical&acknowledged=false&page=1&limit=100. Show a dedicated modal using the returned localized title and body; the modal action is “I understand” and calls PUT /messaging/notifications/:notificationId/acknowledge with no body. Acknowledgement closes only the alert. GET /delivery/driver-deliveries remains the persistent operational source through each row's returnStatus.

Frontend integration

On driver login, cold launch, and foreground resume call GET /messaging/notifications?priority=critical&acknowledged=false&page=1&limit=100. Use notification_type to choose the specialized component and display_mode to choose toast, banner, or modal presentation. Render title/body as plain text. Unknown types fall back to the generic title/body component. Show the oldest unacknowledged critical row first.

Query parameters

ParameterTypeDescription
pagestring

Page number for pagination (default: 1)

Example: 1

limitstring

Number of notifications per page (max 100, default: 20)

Example: 20

read_statusstring

Filter by read status: 'true', 'false', or omit for all

Example: false

notification_typestring

Filter by notification type (delivery_status_update, new_assignment, etc.)

prioritystring

Filter by priority: normal, important, or critical

Example: critical

display_modeOptionalstring

Optional filter: toast, banner, or modal

acknowledgedstring

Filter by acknowledgement timestamp: true or false

Example: false

tenant_idstring

UUID of the tenant (required if not in auth token)

Example: {{tenant_id}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/messaging/notifications?page=1&limit=100&priority=critical&acknowledged=false&tenant_id=${TENANT_ID}" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json"

Response examples

200OK
Response body
json
1{2  "success": true,3  "message": "Notifications retrieved successfully",4  "notifications": [5    {6      "id": "123e4567-e89b-42d3-a456-426614174000",7      "notification_type": "assignment_driver_switched",8      "title": "Driver changed for delivery #3239A",9      "body": "You were switched from delivery #3239A after pickup. Coordinate with your dispatcher and transfer the package to Ahmed Hassan.",10      "read_status": false,11      "priority": "critical",12      "display_mode": "modal",13      "requires_acknowledgement": true,14      "acknowledged_at": null,15      "associated_entity_type": "delivery",16      "associated_entity_id": "123e4567-e89b-42d3-a456-426614174001",17      "template_data": {18        "deliveryId": "123e4567-e89b-42d3-a456-426614174001",19        "deliveryCode": "3239A",20        "newDriver": {21          "driverId": "123e4567-e89b-42d3-a456-426614174002",22          "userId": "123e4567-e89b-42d3-a456-426614174003",23          "fullName": "Ahmed Hassan",24          "avatarUrl": "https://example.com/ahmed.jpg",25          "phone": "+9647500000000"26        }27      },28      "action": {29        "target": "internal",30        "path": "/driver/pickup_and_delivery/123e4567-e89b-42d3-a456-426614174001",31        "secondary_actions": [32          {33            "id": "copy_driver_contact",34            "type": "copy",35            "label": "Copy contact",36            "value": "Ahmed Hassan — +9647500000000"37          },38          {39            "id": "call_driver",40            "type": "call",41            "label": "Call driver",42            "value": "+9647500000000"43          }44        ]45      },46      "channel_status": {47        "in_app": {48          "status": "available",49          "available_at": "2026-07-27T10:30:03Z"50        },51        "push": {52          "status": "failed",53          "retry_count": 1,54          "error": "push delivery failed"55        }56      }57    }58  ],59  "pagination": {60    "page": 1,61    "limit": 100,62    "total": 1,63    "total_pages": 164  },65  "unread_count": 1,66  "pending_critical_count": 167}

Acknowledge Notification​

Communications & Feedback / Messaging / Notifications
PUT/messaging/notifications/{{notification_id}}/acknowledge

Acknowledge one persistent notification. No request body or user ID is accepted. The UUID is scoped to the authenticated recipient and tenant. The operation atomically sets acknowledged_at, read_status=true, and updated_at; repeated calls return HTTP 200 with the existing timestamp. HTTP 404 notification_not_found is used for missing or unauthorized rows. HTTP 409 notification_acknowledgement_not_required is used for non-acknowledgeable rows. Driver-switch notifications keep their existing acknowledgement behavior, but acknowledgement no longer controls delivery custody or status actions; custody already transferred during Switch Driver and the response returns handoff=null.

Frontend integration contract

Continue showing the existing “I understand” action when a driver-switch notification has requires_acknowledgement=true. Treat HTTP 200 as notification acknowledgement only; do not wait for handoff.completed before allowing the replacement driver to continue. Queue valid acknowledgement requests while offline and retry safely. Secondary actions do not acknowledge a notification.

Path parameters

ParameterTypeDescription
notification_idRequiredstring

Variable used inside the request path.

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Staging
Request
curl
1curl --globoff --request PUT "https://staging-api.ondi.io/functions/v1/messaging/notifications/${NOTIFICATION_ID}/acknowledge" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json"

Response examples

200OK
Response body
json
1{2  "success": true,3  "message": "Notification acknowledged successfully",4  "notification": {5    "id": "123e4567-e89b-42d3-a456-426614174000",6    "acknowledged_at": "2026-07-27T10:35:00Z",7    "requires_acknowledgement": true,8    "read_status": true,9    "updated_at": "2026-07-27T10:35:00Z"10  },11  "already_acknowledged": false,12  "handoff": null13}

Mark Notifications as Read​

Communications & Feedback / Messaging / Notifications
PUT/messaging/notifications/mark-read

Mark notifications as read for the current user. Users can only mark their own notifications as read.

  • If notification_ids array is provided: marks only those specific notifications as read

  • If request body is empty or not provided: marks all unread notifications as read

Validation

  • The system validates that all provided notification IDs belong to the authenticated user

  • Only unread notifications are updated (already read notifications are skipped)

  • Returns error invalid_notification_ids with list of invalid IDs if any provided IDs don't exist or don't belong to the user

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth token)

Example: {{tenant_id}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Body parameters

ParameterTypeDescription
notification_idsarray<string>—
Staging
Request
curl
1curl --globoff --request PUT "https://staging-api.ondi.io/functions/v1/messaging/notifications/mark-read?tenant_id=${TENANT_ID}" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json" \4  --data-raw '{5  "notification_ids": [6    "uuid1",7    "uuid2",8    "uuid3"9  ]10}'

Response examples

200OK
Response body
json
1{2  "success": true,3  "message": "Notifications marked as read",4  "updated_count": 35}

Get Notification Statistics​

Communications & Feedback / Messaging / Notifications
GET/messaging/notifications/stats

Get notification statistics for the current user including total, unread, and read counts.

Authorization

  • Requires valid authentication token

  • Users can only view their own notification statistics

Response

  • Returns notification counts (total, unread, read)

  • Useful for displaying notification badges in UI

Query parameters

ParameterTypeDescription
tenant_idstring

UUID of the tenant (required if not in auth token)

Example: {{tenant_id}}

Headers

ParameterTypeDescription
Authorizationstring

Example: Bearer {{access_token}}

Content-Typestring

Example: application/json

Staging
Request
curl
1curl --globoff --request GET "https://staging-api.ondi.io/functions/v1/messaging/notifications/stats?tenant_id=${TENANT_ID}" \2  --header "Authorization: Bearer ${ONDI_ACCESS_TOKEN}" \3  --header "Content-Type: application/json"

Response examples

200OK
Response body
json
1{2  "success": true,3  "message": "Notification stats retrieved",4  "stats": {5    "total": 45,6    "unread": 12,7    "read": 338  }9}