Skip to main content

Order notifications ledger

An order notification is a machine-triggered transactional message — an order confirmation, a shipping update, a delivery alert — fired when your commerce or order-management system emits an event at a fulfillment stage (placed, confirmed, shipped, out for delivery, delivered, plus the exception branches: delayed, failed delivery attempt, refunded, cancelled). The Insights → Order notifications ledger is the first-class reading surface for those flows, separate from campaign send reports. Use it when the question is “how are my order-triggered sends doing — which channel carries them, how fast do they attempt, where do they fail?” — not “how did last week’s promotion perform.”

1. What an order-notification event is, and how it enters the ledger

Every entry in the ledger is one event-driven send: your storefront or order-management system emits a webhook at a stage transition, a platform flow or API call turns it into a templated outbound message, and the message row lands in the ledger tagged as machine-triggered transactional traffic. The stage name (order.confirmation, order.shipped, order.out-for-delivery, order.delivered, order.exception) rides on the send so the ledger can group by it. The ledger is distinct from campaign reports because the traffic class is distinct:
  • Campaign sends are one-to-many promotional pushes on your platform’s campaign rails, with quiet hours, frequency caps, and unsubscribe handling.
  • Order notifications are one-to-one transactional sends where the customer’s purchase establishes the consent. Because each message references a real order it classifies as transactional, and reply-silence plus per-stage triggers keep it out of the conversational surfaces.
The no-inbox transactional gate your delivery rules can set applies here exactly as elsewhere: a machine send still records its full message row and DLR trail, without minting an agent-visible conversation. See Keep one-time codes out of the Inbox for the gate mechanics.

2. The Insights reading — what the dashboard surfaces

The ledger header computes four metrics over the window you pick:
  • Delivery rate — delivered (plus read, where the channel returns it) over terminal sends, with in-flight rows excluded.
  • Time-to-first-attempt — the send-to-first-delivery-signal lag per stage and channel; the number that tells you whether a delay belongs to your sender config or the carrier.
  • Channel mix — which channel actually carried each stage’s sends (SMS, WhatsApp, email) against the intended first-choice channel.
  • Failure breakdown — rejected, undelivered, and failed rows grouped by rejection code, so you can tell recipient-side hygiene (undelivered) apart from dispatch/configuration faults (rejected).
Events that diverge from the canonical send pipeline stand out in the exception stage: a delayed-delivery or failed-first-attempt notification you wired to fire is expected traffic, while a stage that silently stopped firing (confirmation volume drops to zero) shows as a missing series rather than a drop in volume.

3. Filter and export

The ledger page carries the standard Insights date filter (24h, 7d, 30d, 90d, 12m, custom calendar range), and a channel filter that narrows the whole page to SMS, WhatsApp, or email. Filters persist in the URL so a teammate opening your link sees the same range. Two export paths:
  1. CSV — every visible section flattened to one file, using the same Export button pattern as the Analytics console.
  2. Streaming — the /api/v1/analytics/messages family with the channel and stage filters applied, so scheduled BI pulls and webhook-driven downstream consumers read the same rows the page renders.

Streaming via the API

The same ledger view you just filtered is one GET away. Match the page: pass the channel filter you set, and narrow the stage — the ledger’s per-stage rows are the message statuses riding that event’s DLR trail — with the status filter. Both filters are the ones the dashboard already emits when you use it:
The channel filter accepts the ledger’s three displayed classes (sms, whatsapp, email) plus every other class the Analytics family supports, and status is one of queued, sent, delivered, failed, read, undelivered — the same rejection-versus-undelivered vocabulary section 2’s failure breakdown uses, so a BI pull of the exception stage is status=failed (dispatch/configuration faults) or status=undelivered (recipient-side hygiene). A successful response is one envelope: the aggregate counters under data.totals, the bucketed rows under data.time_series, and request tracing under meta:
Omit start_date / end_date and the API defaults to the last 30 days (capped at a 365-day lookback); a 422 VALIDATION_ERROR names the offending parameter in error.details.issues. For the full family — the per-channel, per-country, error-code, and cost breakdowns on the same filters — see the Analytics API page. Role scoping applies to the API the same as the page: owner, admin, developer, and billing keys see the cost-exposing breakdowns (/api/v1/analytics/costs and the Total-spend style rows); viewer keys read aggregates — a viewer-role BI pull on the call above still returns the counters, with cost fields absent.

4. Linkage to the commerce spine

Order notifications usually originate from one of two backbones:
  • The commerce spine (Commerce checkout spine) — the cart and checkout state machine emits a stage transition (browsing → cart_active → checkout_initiated → awaiting_payment → paid → fulfilled), and the ledger reads the transactional message your flow fired at that transition. The commerce-checkout channel (Conversational commerce checkout) is exactly one of those emitters.
  • Direct fulfillment hooks — your own order-management system POSTs to POST /api/v1/messages (or a flow trigger) at each stage, with the stage tagged.
Either way the ledger reads only what actually went down a channel: the pipeline joins one send per stage event, then records the DLR trail back onto that send’s row. The merge rules for late and out-of-order receipts are the Message status transition DAG — same contract, whether the row came from a campaign, a commerce spine send, or a direct fulfillment POST.

5. Guardrails — what counts as anomalous

Two anomaly classes matter here, and both are tenant-owned rules you configure on the alerting surfaces:
  • Sudden channel failure spikes — a rejection-code the carrier returns new, or a stage’s delivery rate dropping off its baseline. Wire a rule on the Usage & delivery anomaly alert rules surface; the transport-side tripwires there already watch delivery rate and outbound volume for exactly this.
  • Experience KPIs — if a commerce confirmation flow’s failure translates into conversational fallout (a rebound to inbound support), the KPI alerts surface watches the customer-experience and AI-cost metrics that usage alerts do not cover.
Both fire-event feeds and Notification Center pings, never gate sends. Guardrails read the ledger; the ledger stop-line itself is unaffected.

6. Comparison to campaign sends

The ledger’s invariant is: machine-triggered transactional flows only, never marketing campaigns. If you send a promotional blast to a list, that volume appears in the cross-channel Insights → Analytics rollup and in campaign reports — the order-notifications ledger still reads zero. Confusion between the two surfaces is the common support ticket; the reading rule is this page isolates one-to-one event-driven commerce sends, and campaign isolation is deliberate. The inverse is also true: a notification you accidentally templated with marketing copy gets reclassified by the carrier/content-moderation layer into promotional traffic, and it stops appearing in the ledger as transactional. Keep the content strictly about the order and the class stays clean.

See also