message.* events follow a message from the moment iSnap accepts or receives it. For each of the
nine event types, this page says when it is sent and when it is not, lists the fields of data, and
shows a full event. You need it to track a send to its final status and to receive inbound messages.
A send through the API produces message.queued, or message.scheduled when the message is held and
then message.queued when it is released. message.sent or message.failed follows, then
message.delivered and message.read if the line’s device reports them, and
message.fallback_triggered when the device sent, or tried to send, the message over SMS or RCS.
Delivery order is not guaranteed. Order events by the timestamps inside data, not by arrival:
message.delivered can reach you before message.sent. See
Sending messages for the statuses of a message.
Common fields
Everymessage.* event carries these fields in data. The sections below list the fields each
event type adds.
The message object has no
chat_id. Three events carry the chat id beside message:
message.received, message.sent with origin: "device", and the message.read that follows your
own mark-read call.
The message events of a trial are tied to the trial’s pool line. A subscription with a line
filter receives them only if it lists that line id.
On a line that another account owned before you, you receive the device reports about the messages
of that account: see Lines that change owner.
Personal data. data.message carries the message text, the handles of the contact and of the
line (phone numbers or email addresses), attachment file names and the handles of the senders of
reactions. message.received can add contact_name. Subscribe to message events only when you need
them. Do not copy this data into logs, tickets or other tools. Refer to a contact by an id of your
own.
message.queued
Sent when:
- a message is accepted for immediate sending, by
POST /v1/messages, byPOST /v1/chats/{chat_id}/share-contact-card, or by a send with a trial key; - a held message is released for sending. In that case the event is skipped if the message is no
longer
queuedat that moment.
data holds the common fields only.
data.message.
message.scheduled
Sent when a message is accepted but held, and again each time its planned send time moves by more
than 15 minutes. A smaller move sends nothing, and so does the move of a held message that enters
the reply lane because its contact wrote. message.queued follows when the message is released.
See Held messages.
data.message.
message.sent
Sent in two cases, told apart by data.origin.
Common fields:
A message created through the API
origin is api: the line’s device confirms that it sent a message created through the API. data
holds the three common fields. message.status is sent, and message.service is the service the
device used, when the device reports one.
A message typed on the device
origin is device: someone typed a message on the line’s own device. The message is recorded with
direction: outbound and status: delivered, and message.sent_at and message.delivered_at both
hold the device’s time. data adds one field:
This case exists only for a line that has a device of its own: a rented line or a BYOD line. It is
not sent for a shared line or for a line that runs trials, nor for the device’s own copy of a message
created through the API.
data.message.
message.delivered
Sent the first time the line’s device reports that an outbound message was delivered. iSnap learns
of a delivery only from the device: no report means no event. A report for a status the message
already has, or for a message that iSnap has deleted, sends nothing. A message can reach read with
no message.delivered and with delivered_at still null.
data.message.
message.read
Sent in two cases. Every case carries message and read_at: rely on these two fields, and treat
the others as present only in their case.
The first case concerns a message you sent, whose
message.status is read. The second concerns an
inbound message: message.direction is inbound, and message.status stays delivered.
The recipient read your message
The line’s device reports that the recipient read an outbound message.data holds the two common
fields and can add message_id, line_id and status (always read); on an iMessage line it
always adds them.
Your own mark-read call
POST /v1/chats/{chat_id}/read sends one event per inbound
message it newly marks read. On a line that another account owned before you, that includes the
inbound messages that account had not marked read: see
Lines that change owner. data adds:
data.message.
message.failed
Sent in three cases. Every case carries message and failed_at. For the cause, read
message.error_code and message.error_message: they have one meaning in every case, while the
fields beside message differ.
iSnap never resends a failed message: send a new message to retry. See
Sending messages.
The device refuses the send
The line’s device reports that it could not send the message.data adds:
The device reports a failure after the send
The line’s device reports the statusfailed for a message it had sent. data adds:
iSnap fails a message that was still waiting
iSnap fails the message itself: the line was terminated, the message waited too long, or the device took it and never reported an outcome.data adds:
data.message.
message.received
Sent when an inbound message is stored. An inbound message has status: delivered.
The event is not sent:
- on a shared line, for a message from a contact the line has no active binding with;
- on a line that runs trials, for the text that carries a pairing code, and for a message from a sender who is not the paired prospect of a trial;
- for a second copy of a message the device reports twice;
- for history that a device reports from before iSnap was watching the line.
data.message and contact_name.
message.cancelled
Sent when you cancel a queued or held message with
DELETE /v1/messages/{id}. It is not sent for a message of
a trial.
data holds the common fields only. message.status is cancelled and message.cancelled_at is
set.
data.message.
message.fallback_triggered
Sent when the line’s device reports that a message went out, or was attempted, over SMS or RCS
instead of iMessage, whether that attempt succeeded or failed. It does not prove that an iMessage
attempt was made first: the device also reports it for a message it sent directly as SMS or RCS
because it already knew the recipient is not on iMessage. The same report also produces
message.sent or message.failed.
data.message.