Event catalog
Every webhook event BlueBot sends, when it fires, and a full example payload for each.
Every event BlueBot sends to a webhook, with a full example of each. Each one is posted as JSON with the same envelope: id (the event, evt_…, also sent as the webhook-id header, the same on every retry), object: "event", type, api_version (the payload version your endpoint is pinned to, 2026-11-13 today), timestamp, and data. Message events carry the whole message as GET /v1/messages/{id} returns it, metadata included, so you can match an event to the request that caused it.
| Event | When it fires |
|---|---|
| A text was accepted and is waiting for the Mac, or a scheduled text became due. | |
Messages on the Mac showed the text sent. Also fires for a text you typed by hand on your Mac or iPhone, with source: "mac". | |
| iMessage showed the text delivered to the person’s device. | |
| The person read the text. Only for people who share read receipts. | |
| Messages couldn’t send the text, or it was an iMessage-only text to somebody not on iMessage. | |
| The Mac took the text and didn’t say whether it went before its 3-minute lease ran out. | |
The text was still waiting when its expires_at passed, so it will never go. | |
| A queued or scheduled text was canceled: by you, because the person is on your stop list, or when its sequence or broadcast stopped. | |
| Somebody texted you. Pictures and voice memos are on the message as files. | |
| A text was edited in Messages, by you or by the other person. | |
| A text was unsent in Messages. Its words are gone from BlueBot too. | |
| Somebody added a tapback (love, like, laugh and so on) to a text, or you did from your Mac or iPhone. | |
| A tapback was taken back. | |
| The Mac saw a chat BlueBot didn’t know: a new group, or a first text with somebody. | |
| A person was added: by a send to somebody new, a text from somebody new, an import, the API or the dashboard. | |
| A person went on your stop list. Their queued texts were canceled. | |
| A person came off your stop list: they texted START, or you took them off. | |
| A person reached the end of a sequence, or it stopped early because they replied or stopped. | |
| Every text in a broadcast has settled: sent, failed, skipped, expired or canceled. | |
| An incoming text matched a keyword rule that has the “Send a webhook event” action. | |
| The Mac checked in after being offline. Held texts start going. | |
The Mac hasn’t checked in for 2 minutes. Texts wait with hold.reason: "device_offline". | |
One of the Mac’s setup checks turned needs_you, such as Messages signing out or Full Disk Access being turned off. |
Subscribe to the events you need when you make the webhook; an endpoint never receives types it didn’t ask for. To check a handler against these payloads without sending a text, use Send a test event in the dashboard, POST /v1/webhooks/{id}/test, or bluebot listen.
Messages
message.queued
A text was accepted and is waiting for the Mac, or a scheduled text became due.
Its hold says why it is waiting, if anything holds it. A queued text can still be canceled.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.queued",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "queued",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": null,
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": null
}
}message.sent
Messages on the Mac showed the text sent. Also fires for a text you typed by hand on your Mac or iPhone, with source: "mac".
service says whether it went as an iMessage or a regular text. A text sent with a file that couldn’t be attached is sent with failure set.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.sent",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "sent",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": "imessage",
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": "2026-11-13T19:41:02.000Z",
"sent_at": "2026-11-13T19:41:05.000Z",
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": null
}
}message.delivered
iMessage showed the text delivered to the person’s device.
Regular texts (SMS) never report delivery, so a text that went as SMS stays sent.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.delivered",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "delivered",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": "imessage",
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": "2026-11-13T19:41:02.000Z",
"sent_at": "2026-11-13T19:41:05.000Z",
"delivered_at": "2026-11-13T19:41:06.000Z",
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": null
}
}message.read
The person read the text. Only for people who share read receipts.
Most people don’t share read receipts, so don’t wait for this event.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.read",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "read",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": "imessage",
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": "2026-11-13T19:41:02.000Z",
"sent_at": "2026-11-13T19:41:05.000Z",
"delivered_at": "2026-11-13T19:41:06.000Z",
"read_at": "2026-11-13T19:43:30.000Z",
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": null
}
}message.failed
Messages couldn’t send the text, or it was an iMessage-only text to somebody not on iMessage.
failure.reason is a stable code and failure.detail says what the Mac saw.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.failed",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "failed",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "imessage",
"service": null,
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": {
"reason": "not_on_imessage",
"detail": "Messages couldn’t send this as an iMessage."
},
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": "2026-11-13T19:41:02.000Z",
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": "2026-11-13T19:41:09.000Z",
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": null
}
}message.unconfirmed
The Mac took the text and didn’t say whether it went before its 3-minute lease ran out.
It may have gone. Check the conversation, then settle it with POST /v1/messages/{id}/resolve: mark_sent if it went, send_again if not. BlueBot never sends it again on its own.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.unconfirmed",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "unconfirmed",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": null,
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": "2026-11-13T19:41:02.000Z",
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": "2026-11-13T19:44:02.000Z",
"expired_at": null,
"canceled_at": null,
"received_at": null
}
}message.expired
The text was still waiting when its expires_at passed, so it will never go.
Usually the Mac was away or the text sat behind quiet hours or a daily limit for longer than the expiry setting.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.expired",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "expired",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": null,
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": "2026-11-14T19:41:00.000Z",
"canceled_at": null,
"received_at": null
}
}message.canceled
A queued or scheduled text was canceled: by you, because the person is on your stop list, or when its sequence or broadcast stopped.
cancel_reason says which.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.canceled",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "message",
"direction": "out",
"state": "canceled",
"to": "+15555550123",
"from": "+15555550100",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Hi Maria, the showing at 412 Oak St is confirmed for 3 PM.",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": null,
"sms_retry": false,
"source": "api",
"source_ref": null,
"metadata": {
"crm_id": "48213"
},
"hold": null,
"send_at": null,
"expires_at": "2026-11-14T19:41:00.000Z",
"failure": null,
"cancel_reason": "opted_out",
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:41:00.000Z",
"queued_at": "2026-11-13T19:41:00.000Z",
"sending_at": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": "2026-11-13T19:42:00.000Z",
"received_at": null
}
}message.received
Somebody texted you. Pictures and voice memos are on the message as files.
Fires once the Mac has uploaded the message’s files, or after 2 minutes without them (their status is then waiting). Group texts carry chat_id.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.received",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_2Bf8QzD4kJmA6nXwEuTr1c",
"object": "message",
"direction": "in",
"state": "received",
"to": "+15555550100",
"from": "+15555550123",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Perfect, see you there!",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": "imessage",
"sms_retry": false,
"source": "mac",
"source_ref": null,
"metadata": {},
"hold": null,
"send_at": null,
"expires_at": null,
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:44:12.000Z",
"queued_at": null,
"sending_at": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": "2026-11-13T19:44:10.000Z"
}
}message.edited
A text was edited in Messages, by you or by the other person.
text is the new words and edited_at when. BlueBot can read edits but can’t make them.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.edited",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_2Bf8QzD4kJmA6nXwEuTr1c",
"object": "message",
"direction": "in",
"state": "received",
"to": "+15555550100",
"from": "+15555550123",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Perfect, see you there at 3!",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": "imessage",
"sms_retry": false,
"source": "mac",
"source_ref": null,
"metadata": {},
"hold": null,
"send_at": null,
"expires_at": null,
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": "2026-11-13T19:44:40.000Z",
"unsent_at": null,
"created_at": "2026-11-13T19:44:12.000Z",
"queued_at": null,
"sending_at": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": "2026-11-13T19:44:10.000Z"
}
}message.unsent
A text was unsent in Messages. Its words are gone from BlueBot too.
text is null and unsent_at says when.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "message.unsent",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "msg_2Bf8QzD4kJmA6nXwEuTr1c",
"object": "message",
"direction": "in",
"state": "received",
"to": "+15555550100",
"from": "+15555550123",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": null,
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": "imessage",
"sms_retry": false,
"source": "mac",
"source_ref": null,
"metadata": {},
"hold": null,
"send_at": null,
"expires_at": null,
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": "2026-11-13T19:45:00.000Z",
"created_at": "2026-11-13T19:44:12.000Z",
"queued_at": null,
"sending_at": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": "2026-11-13T19:44:10.000Z"
}
}Reactions
reaction.added
Somebody added a tapback (love, like, laugh and so on) to a text, or you did from your Mac or iPhone.
direction says whose it was. BlueBot can read tapbacks but can’t send them.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "reaction.added",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "rxn_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "reaction",
"kind": "love",
"emoji": null,
"from": "+15555550123",
"direction": "in",
"added_at": "2026-11-13T19:45:00.000Z",
"message_id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"removed_at": null
}
}reaction.removed
A tapback was taken back.
The reaction has the id reaction.added gave it.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "reaction.removed",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "rxn_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "reaction",
"kind": "love",
"emoji": null,
"from": "+15555550123",
"direction": "in",
"added_at": "2026-11-13T19:45:00.000Z",
"message_id": "msg_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"removed_at": "2026-11-13T19:46:00.000Z"
}
}Chats
chat.created
The Mac saw a chat BlueBot didn’t know: a new group, or a first text with somebody.
A group chat’s id is what chat_id takes on a send.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "chat.created",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "chat_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "chat",
"name": "Oak St closing",
"is_group": true,
"participants": [
"+15555550123",
"+15555550187"
],
"service": "imessage",
"last_message_at": "2026-11-13T19:41:00.000Z",
"created_at": "2026-11-13T19:41:00.000Z"
}
}Contacts
contact.created
A person was added: by a send to somebody new, a text from somebody new, an import, the API or the dashboard.
created_via says how.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "contact.created",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "contact",
"handle": "+15555550123",
"kind": "phone",
"first_name": "Maria",
"last_name": "Alvarez",
"company": null,
"tags": [
"buyer"
],
"custom_fields": {},
"stopped": false,
"stopped_at": null,
"stop_source": null,
"last_service": "imessage",
"first_message_at": null,
"last_message_at": null,
"created_via": "api",
"created_at": "2026-11-13T19:41:00.000Z"
}
}contact.stopped
A person went on your stop list. Their queued texts were canceled.
stop_source: "reply" means they texted a stop word such as STOP. BlueBot won’t text them again until they text START or you take them off the list.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "contact.stopped",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "contact",
"handle": "+15555550123",
"kind": "phone",
"first_name": "Maria",
"last_name": "Alvarez",
"company": null,
"tags": [
"buyer"
],
"custom_fields": {},
"stopped": true,
"stopped_at": "2026-11-13T19:50:00.000Z",
"stop_source": "reply",
"last_service": "imessage",
"first_message_at": "2026-11-13T19:41:00.000Z",
"last_message_at": "2026-11-13T19:41:00.000Z",
"created_via": "api",
"created_at": "2026-11-13T19:41:00.000Z"
}
}contact.unstopped
A person came off your stop list: they texted START, or you took them off.
Texts to them go again from now on. Texts canceled while they were stopped stay canceled.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "contact.unstopped",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "contact",
"handle": "+15555550123",
"kind": "phone",
"first_name": "Maria",
"last_name": "Alvarez",
"company": null,
"tags": [
"buyer"
],
"custom_fields": {},
"stopped": false,
"stopped_at": null,
"stop_source": null,
"last_service": "imessage",
"first_message_at": "2026-11-13T19:41:00.000Z",
"last_message_at": "2026-11-13T19:41:00.000Z",
"created_via": "api",
"created_at": "2026-11-13T19:41:00.000Z"
}
}Automations
sequence.completed
A person reached the end of a sequence, or it stopped early because they replied or stopped.
state and stop_reason say which.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "sequence.completed",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "enr_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "enrollment",
"sequence_id": "seq_1Hq2LxW9cVbN3mKpRtYs0a",
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"handle": "+15555550123",
"contact": {
"id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "contact",
"handle": "+15555550123",
"kind": "phone",
"first_name": "Maria",
"last_name": "Alvarez",
"company": null,
"tags": [
"buyer"
],
"custom_fields": {},
"stopped": false,
"stopped_at": null,
"stop_source": null,
"last_service": "imessage",
"first_message_at": "2026-11-13T19:41:00.000Z",
"last_message_at": "2026-11-13T19:41:00.000Z",
"created_via": "api",
"created_at": "2026-11-13T19:41:00.000Z"
},
"state": "stopped",
"stop_reason": "replied",
"completed_at": "2026-11-13T19:41:00.000Z"
}
}broadcast.completed
Every text in a broadcast has settled: sent, failed, skipped, expired or canceled.
counts has the totals.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "broadcast.completed",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "bc_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "broadcast",
"name": "Open house Saturday",
"state": "completed",
"recipient_count": 42,
"counts": {
"sent": 12,
"delivered": 27,
"failed": 1,
"skipped": 2
},
"completed_at": "2026-11-13T19:41:00.000Z"
}
}automation.matched
An incoming text matched a keyword rule that has the “Send a webhook event” action.
Fires once per incoming text, for the first rule that matched. message is the text that matched. A stop word never matches a rule, so it never fires for one.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "automation.matched",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"object": "automation_match",
"rule_id": "kw_1Hq2LxW9cVbN3mKpRtYs0a",
"rule_name": "Pricing",
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"actions": [
"reply",
"tag",
"webhook"
],
"message": {
"id": "msg_2Bf8QzD4kJmA6nXwEuTr1c",
"object": "message",
"direction": "in",
"state": "received",
"to": "+15555550100",
"from": "+15555550123",
"chat_id": null,
"contact_id": "ct_1Hq2LxW9cVbN3mKpRtYs0a",
"conversation_id": "conv_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "PRICING",
"text_deleted": false,
"files": [],
"service_requested": "auto",
"service": "imessage",
"sms_retry": false,
"source": "mac",
"source_ref": null,
"metadata": {},
"hold": null,
"send_at": null,
"expires_at": null,
"failure": null,
"cancel_reason": null,
"resolution": null,
"resolved_at": null,
"resent_message_id": null,
"reply_to_id": null,
"reactions": [],
"edited_at": null,
"unsent_at": null,
"created_at": "2026-11-13T19:44:12.000Z",
"queued_at": null,
"sending_at": null,
"sent_at": null,
"delivered_at": null,
"read_at": null,
"failed_at": null,
"unconfirmed_at": null,
"expired_at": null,
"canceled_at": null,
"received_at": "2026-11-13T19:44:10.000Z"
},
"matched_at": "2026-11-13T19:41:00.000Z"
}
}Your Mac
device.online
The Mac checked in after being offline. Held texts start going.
Also fires the first time a newly connected Mac checks in.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "device.online",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "dev_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "device",
"status": "online",
"name": "Dana’s MacBook Air",
"number": "+15555550100",
"app_version": "1.0.0",
"macos_version": "15.1",
"last_seen_at": "2026-11-13T19:41:00.000Z",
"last_sync_at": "2026-11-13T19:41:00.000Z",
"offline_since": null,
"paired_at": "2026-11-01T15:00:00.000Z",
"checks": {
"messages": {
"state": "ok",
"detail": null
},
"full_disk_access": {
"state": "ok",
"detail": null
},
"forwarding": {
"state": "ok",
"detail": null
},
"awake": {
"state": "ok",
"detail": null
},
"filevault": {
"state": "ok",
"detail": null
}
},
"checks_ok": true,
"transcription": false,
"held_count": 0,
"queued_count": 0,
"unconfirmed_count": 0,
"paused_until": null,
"today": {
"sent": 14,
"new_people": 3,
"new_people_limit": 50,
"daily_limit": 1000,
"resets_at": "2026-11-14T05:00:00.000Z"
},
"failed_checks": []
}
}device.offline
The Mac hasn’t checked in for 2 minutes. Texts wait with hold.reason: "device_offline".
The owner is emailed once if it stays away 10 minutes.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "device.offline",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "dev_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "device",
"status": "offline",
"name": "Dana’s MacBook Air",
"number": "+15555550100",
"app_version": "1.0.0",
"macos_version": "15.1",
"last_seen_at": "2026-11-13T19:41:00.000Z",
"last_sync_at": "2026-11-13T19:41:00.000Z",
"offline_since": "2026-11-13T19:39:00.000Z",
"paired_at": "2026-11-01T15:00:00.000Z",
"checks": {
"messages": {
"state": "ok",
"detail": null
},
"full_disk_access": {
"state": "ok",
"detail": null
},
"forwarding": {
"state": "ok",
"detail": null
},
"awake": {
"state": "ok",
"detail": null
},
"filevault": {
"state": "ok",
"detail": null
}
},
"checks_ok": true,
"transcription": false,
"held_count": 2,
"queued_count": 2,
"unconfirmed_count": 0,
"paused_until": null,
"today": {
"sent": 14,
"new_people": 3,
"new_people_limit": 50,
"daily_limit": 1000,
"resets_at": "2026-11-14T05:00:00.000Z"
},
"failed_checks": []
}
}device.check_failed
One of the Mac’s setup checks turned needs_you, such as Messages signing out or Full Disk Access being turned off.
failed_checks names them and each check’s detail says what the Mac saw.
{
"id": "evt_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "event",
"type": "device.check_failed",
"api_version": "2026-11-13",
"timestamp": "2026-11-13T19:41:00.000Z",
"data": {
"id": "dev_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "device",
"status": "online",
"name": "Dana’s MacBook Air",
"number": "+15555550100",
"app_version": "1.0.0",
"macos_version": "15.1",
"last_seen_at": "2026-11-13T19:41:00.000Z",
"last_sync_at": "2026-11-13T19:41:00.000Z",
"offline_since": null,
"paired_at": "2026-11-01T15:00:00.000Z",
"checks": {
"messages": {
"state": "needs_you",
"detail": "Messages isn’t signed in to iMessage."
},
"full_disk_access": {
"state": "ok",
"detail": null
},
"forwarding": {
"state": "ok",
"detail": null
},
"awake": {
"state": "ok",
"detail": null
},
"filevault": {
"state": "ok",
"detail": null
}
},
"checks_ok": false,
"transcription": false,
"held_count": 0,
"queued_count": 0,
"unconfirmed_count": 0,
"paused_until": null,
"today": {
"sent": 14,
"new_people": 3,
"new_people_limit": 50,
"daily_limit": 1000,
"resets_at": "2026-11-14T05:00:00.000Z"
},
"failed_checks": [
"messages"
]
}
}