Webhooks & APIOutbound

message.outbound.updated

Emitted when an outbound message is edited or its delivery status changes

type: message.outbound.updated

Fired when an outbound message is edited or transitions through a delivery state — sent → delivered → read, or sent → failed.

When it fires

  • The provider confirms delivery (deliveredAt is set).
  • The contact reads the message (readAt is set).
  • The provider reports a permanent failure (failedAt, errorCode, errorMessage are set).
  • An operator edits an already-sent message on channels that support editing.

data shape

type Data = {
  chat: ChatPayload;
  message: MessagePayload;             // direction: "OUTBOUND"
  previous?: Partial<MessagePayload>;
  contact?: ContactPayload;
};
  • chat — the owning chat.
  • message — the post-update message state. See MessagePayload.
  • previous — optional, only the fields that changed (pre-update values).
  • contact — the recipient, when resolvable.

Example envelope

{
  "id": "evt_d1e2f3a4-b5c6-7890-def1-234567890abc",
  "type": "message.outbound.updated",
  "timestamp": "2026-04-24T12:14:55.000Z",
  "data": {
    "chat": {
      "id": "6804f4c2a6f9f35f6e66f1a1",
      "integrationId": "67f95b0126a4d1c9e3f0aa12",
      "channel": "WHATSAPP"
    },
    "message": {
      "id": "msg_02",
      "chatId": "6804f4c2a6f9f35f6e66f1a1",
      "direction": "OUTBOUND",
      "type": "TEXT",
      "text": "Hi Alex — how can we help?",
      "sentAt": "2026-04-24T12:14:30.000Z",
      "deliveredAt": "2026-04-24T12:14:50.000Z",
      "readAt": "2026-04-24T12:14:55.000Z"
    },
    "previous": {
      "readAt": null
    }
  },
  "meta": {
    "eventId": "evt_d1e2f3a4-b5c6-7890-def1-234567890abc",
    "event": "message.outbound.updated",
    "occurredAt": "2026-04-24T12:14:55.000Z",
    "organisationId": "6640f3d5c8a0d7e8b7f20222",
    "connectionId": "6640f45ac8a0d7e8b7f2014a",
    "apiVersion": "2026-04-01",
    "attempt": 1
  }
}

Notes

  • Status transitions can arrive multiple times for the same message — once for each state change. Dedupe-and-sort by meta.occurredAt if you apply them to your own store.
  • On failures, inspect message.errorCode and message.errorMessage for the provider's reason.

On this page