Delivery events
Apple Delivered and Read as a stored projection on the stream. The live ask is still send-status.
event: delivery is a fan-out of delivery truth the service has already
stored for one of your sends. It is not a live read of the Mac, and it is not
a second event: command. Command status does
not change when this frame arrives.
For message.send, succeeded still means the Mac ingested the outbound echo
— the bubble exists in chat.db. It is not Apple's Delivered stamp.
event: delivery
data: {"commandId":"cmd-1","conversationId":"a0000000-0000-4000-8000-000000000001","deliveryState":"delivered","deliveryService":"iMessage","deliveryError":null,"deliveredAt":"2026-08-24T18:03:14.000Z","readAt":null,"occurredAt":"2026-08-24T18:03:14.000Z"}The frame
Prop
Type
When a frame is emitted
A frame is emitted when deliveryState changes, or when deliveredAt or
readAt first appears or moves forward. A check that only restamps the last
time the projection was looked at is silent.
deliveryState stays delivered when a later readAt lands. The new
timestamp is the change, so you can see a second frame whose state is still
delivered.
An SMS send is not part of this sweep and does not emit event: delivery.
Do not mark the message delivered from event: command with status: "succeeded". That frame is
the echo. Apple's stamp is deliveryState, deliveredAt and readAt here — or the live read
below, which can disagree with a projection that has not been updated yet.
Live read, not this frame
GET /v1/send-status/:commandId asks the Mac now. Use it
when you need the current Apple stamp rather than the last projection the
stream fanned out. The two are different objects. This frame does not replace
that GET, and that GET does not arrive on the stream.
Catch-up
includeDelivery: true on POST /v1/replay returns
deliveries[]: one current projection per requested command that has been
checked, in the same shape as this frame. It requires commandIds. It is not
a reconstruction of every poll.
Sort is occurredAt, then commandId. limit caps the array (default 50,
max 200). Unchecked commands and another account's commands are omitted. Apply
by commandId. A Read that landed after delivered is on this object even
when deliveryState stayed delivered. Live and replay can overlap.