Skip to main content

Notification lifecycle

How a notification moves from creation through delivery (or cancellation / purge), from the caller's perspective. Status is computed at read time from timestamps and the live delivery state — there is no stored status field. How to call each step is in endpoints → notifications.

What the platform owns

The platform keeps a record for each message sent, with no stored status field. On each read it computes the status by merging its own scheduledDateTime with the live delivery status. The platform owns the encrypted content (messageContent, channelIdentifier, templateVariables); delivery state (status, deliveryDateTime, isPurged) is reported by the backing messaging provider.

End-to-end journey — immediate send

End-to-end journey — scheduled send + cancel

Notification states

SCHEDULED_DELIVERY is a computed state, not stored: it is returned whenever the record has a non-null scheduledDateTime and the current status is not CANCELLED.

Timestamps

TimestampMeaning
createdAtrecord inserted
sentDateTimethe message was accepted for delivery (not yet delivered)
scheduledDateTimerequested delivery window (set by the caller on send)
deliveryDateTimedelivery confirmed

sentDateTime means accepted, not received. For immediate sends sentDateTimecreatedAt; for scheduled sends it is stamped at send time, when the scheduled job is queued.

Scheduling window

A scheduledDateTime must be more than 5 minutes and at most 35 days in the future. A request outside those bounds returns 422 NOT022003. The notification record has already been written at that point and remains with no sentDateTime.

Cancellation

Only a notification with a non-null scheduledDateTime can be cancelled: a cancel on a non-scheduled notification returns 400 NOT100006, and a notification that is not in a cancellable status returns 412 NOT012001. Both guards must pass.

Purge

POST /v1/notifications/{id}/purge requests deletion of the message body downstream:

  • The message body is removed downstream on a best-effort basis — if removal is refused (too old, policy) the error is tolerated and the purge does not fail; the message is still marked purged.
  • The platform record is not scrubbed. The encrypted messageContent, channelIdentifier, and templateVariables remain in the platform. Regulatory scrubbing of the platform record is a separate data-retention operation.

Allow-list

The notification allow-list is a safety gate for non-production environments: it stops notifications reaching real recipients during development and testing. When enforced (the default), every channelIdentifier on POST /v1/notifications must match an allow-list entry before any record is written, else 403 NOT003002. The list is tenant-global — there is no clientId/brandId scoping, so an allowed identifier is allowed for every tenant in the instance.

Journey summary

  1. Send — allow-list check → template substitution → record written (encrypted) → dispatched → sentDateTime stamped.
  2. Poll / read — status fetched live; SCHEDULED_DELIVERY computed when applicable.
  3. Cancel — must be scheduled (400 NOT100006) and still cancellable (412 NOT012001) → CANCELLED.
  4. Purge — message body removed downstream (best-effort); platform record unchanged; isPurged reflects the downstream record.