Skip to main content

ACK Lifecycle

NotificationDelivery sent to company user
|
|-- [Web dashboard button]
| POST /api/v1/notifications/{id}/ack
| AckIngestionService::ackByUser(notification, user, AckSource::Web)
|
|-- [Inbound transport reply (SMS, email, webhook)]
| POST /api/v1/inbound/sms or /api/v1/inbound/email
| Validate inbound signature → AckIngestionService::ackByTransport(...)
|
v
AckIngestionService (sole ACK writer)
├── notification.ack_status = AckStatus::Acked
├── notification.acked_at = now()
├── notification.ack_source = <triggering stream>
├── notification.escalation_cancelled_at = now()
├── Mark ALL NotificationDeliveries for this notification as acknowledged
├── Dispatch EscalationCancelMessage
└── CommunicationLogger::log(
type: AckReceived,
content: "ACK received via sms_reply — all 3 delivery streams marked acknowledged"
)

Cross-Stream Rule

When any one delivery stream ACKs a notification, all delivery streams for that notification are immediately marked acknowledged. The AckIngestionService logs a single AckReceived event naming the triggering stream and total stream count.

Partial acknowledgement does not exist in this system.

ACK Routing Back to PSAP

After ACK, Cloud routes the confirmation back to the originating PSAPLink PSAP instance:

ModeMechanism
pollPSAPLink PSAP polls GET /api/v1/core/ack-queue/{psapId}?after=<cursor>. Cursor stored in var/ack_poll_cursor.txt.
callbackCloud POSTs to PSAPLink PSAP's POST /api/v1/core/callback/ack (HMAC-signed). Requires PSAP to be reachable.

ACK Sources

Sourceack_source value
Web dashboard buttonweb
Inbound SMS replysms_reply
Inbound email replyemail_reply
Inbound webhookwebhook