Skip to content
AISARAISAR
Messages

Messages

Message status updated

message.status.updated

Fires when the delivery status of an outbound message changes. Statuses progress in order: queued → sent → delivered → read → played; a lower status is silently dropped if a higher one is already recorded. failed is a terminal status, but it is only recorded when the message has not already reached a higher status: a provider failure receipt arriving AFTER delivered/read/played was already recorded (e.g. delayed or duplicated) is silently suppressed — an already-delivered message's status is never downgraded retroactively. A suppressed receipt is not lost silently: it is written to the channel log (GET /channels/{id}/logs) under the message.status.failed_suppressed code. This event fires for outbound messages only, and not every channel reports every status (e.g. some channels do not report read).

HTTP request

AISAR sends a signed POST request to your webhook_url:

http
POST {webhook_url}
Content-Type: application/json
X-AISAR-Signature: sha256=...

{
  "event": "message.status.updated",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-03-26T12:00:00.000000Z",
  "company_id": 1,
  "data": {
    "message_id": 123,
    "conversation_id": 45,
    "channel_id": 2,
    "external_message_id": "3EB0ABC123456789",
    "status": {
      "name": "delivered",
      "timestamp": "2026-03-26T12:00:05+00:00",
      "error_details": null
    }
  }
}

The X-AISAR-Signature header carries an HMAC-SHA256 signature of the request body — use it to verify the request came from AISAR.

Example payload

json
{
  "event": "message.status.updated",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-03-26T12:00:00.000000Z",
  "company_id": 1,
  "data": {
    "message_id": 123,
    "conversation_id": 45,
    "channel_id": 2,
    "external_message_id": "3EB0ABC123456789",
    "status": {
      "name": "delivered",
      "timestamp": "2026-03-26T12:00:05+00:00",
      "error_details": null
    }
  }
}

Payload fields

FieldTypeDescription
message_idintegerInternal message ID
conversation_idintegerConversation ID
channel_idintegerChannel ID
external_message_idstringPlatform-specific message ID
status.namestringStatus: queued (queued for sending), sent (sent to recipient device), delivered (delivered to recipient device), read (read by recipient), played (played by recipient — voice/video), failed (delivery failed, terminal, but suppressed when a higher status is already recorded — see the event description)
status.timestampstringISO 8601 timestamp when the status was recorded
status.error_detailsstring|nullError description in the "text (code)" format — a human-readable reason (from the runtime/provider response or an error catalog) with the technical code in parentheses; the code may be absent, leaving just the text. Only present when name is failed