Messages
message.queued
Message accepted by the API and queued for delivery.
| Field | Required | Type | Notes |
|---|
| object | yes | "message" | Public object name of the inner resource. |
| message_id | yes | string | Message id. |
| status | yes | "queued" | Always queued for this event. |
| to | yes | string | Recipient phone number. |
| from | yes | string | Sender phone number. |
| client_id | yes | string | null | Partner client id when the send was attributed to one. |
| ten_dlc_id | yes | string | null | 10DLC application id when the send was attributed to one. |
{
"id": "evt_queued_example",
"object": "event",
"type": "message.queued",
"livemode": true,
"occurred_at": "2026-05-01T17:00:00.000Z",
"data": {
"object": "message",
"message_id": "msg_uuid",
"status": "queued",
"to": "+14155551234",
"from": "+18005550199",
"client_id": null,
"ten_dlc_id": null
}
}message.sent
Message handed off to the carrier. `provider_message_id` is an opaque carrier reference (not a vendor brand).
| Field | Required | Type | Notes |
|---|
| object | yes | "message" | Public object name of the inner resource. |
| message_id | yes | string | Message id. |
| status | yes | "sent" | Always sent for this event. |
| provider_message_id | yes | string | Opaque carrier reference. Not a vendor brand. |
| client_id | yes | string | null | Partner client id when the send was attributed to one. |
| ten_dlc_id | yes | string | null | 10DLC application id when the send was attributed to one. |
{
"id": "evt_sent_example",
"object": "event",
"type": "message.sent",
"livemode": true,
"occurred_at": "2026-05-01T17:00:01.000Z",
"data": {
"object": "message",
"message_id": "msg_uuid",
"status": "sent",
"provider_message_id": "opaque_carrier_ref",
"client_id": null,
"ten_dlc_id": null
}
}message.delivered
Carrier confirmed the message was delivered to the recipient. Not emitted today for numbers that don't report delivery receipts, so a missing `message.delivered` doesn't mean the message failed.
| Field | Required | Type | Notes |
|---|
| object | yes | "message" | Public object name of the inner resource. |
| message_id | yes | string | Message id. |
| status | yes | "delivered" | Always delivered for this event. |
| delivered_at | yes | string | null | Carrier delivery time. Null when the carrier omitted a timestamp. |
{
"id": "evt_delivered_example",
"object": "event",
"type": "message.delivered",
"livemode": true,
"occurred_at": "2026-05-01T17:00:05.000Z",
"data": {
"object": "message",
"message_id": "msg_uuid",
"status": "delivered",
"delivered_at": "2026-05-01T17:00:05.000Z"
}
}message.failed
Delivery failed. Use `data.delivery_error_code` (Statxt dictionary) for suppress/retry decisions. `data.error_code` is a deprecated compatibility field. On numbers that don't report delivery receipts, only failures at send time emit this event today; later delivery failures don't.
| Field | Required | Type | Notes |
|---|
| object | yes | "message" | Public object name of the inner resource. |
| message_id | yes | string | Message id. |
| status | yes | "failed" | Always failed for this event. |
| error_code | yes | string | null | Deprecated compatibility code. Prefer delivery_error_code. |
| delivery_error_code | yes | string | null | Statxt delivery-failure dictionary code. Null when unmapped. |
| error_message | yes | string | null | Human-readable failure reason. Null when the carrier omitted one. |
| client_id | no | string | null | Present only on API send failures, not carrier status callbacks. |
| ten_dlc_id | no | string | null | Present only on API send failures, not carrier status callbacks. |
{
"id": "evt_failed_example",
"object": "event",
"type": "message.failed",
"livemode": true,
"occurred_at": "2026-05-01T17:00:05.000Z",
"data": {
"object": "message",
"message_id": "msg_uuid",
"status": "failed",
"error_code": null,
"delivery_error_code": "carrier_rejected",
"error_message": "Carrier rejected the destination."
}
}message.received
Inbound message received from a contact. Fires once per inbound SMS/MMS regardless of provider.
| Field | Required | Type | Notes |
|---|
| object | yes | "message" | Public object name of the inner resource. |
| message_id | yes | string | Inbound message id. |
| from | yes | string | Sender phone number. |
| to | yes | string | Destination phone number. |
| body | yes | string | Message text. |
| media_urls | yes | string[] | MMS media URLs. Empty for SMS. |
| received_at | yes | string | When the inbound message was received. |
{
"id": "evt_received_example",
"object": "event",
"type": "message.received",
"livemode": true,
"occurred_at": "2026-05-01T17:05:00.000Z",
"data": {
"object": "message",
"message_id": "msg_uuid",
"from": "+14155551234",
"to": "+18005550199",
"body": "Stop sending me texts",
"media_urls": [],
"received_at": "2026-05-01T17:05:00.000Z"
}
}Campaigns
campaign.created
Draft campaign created via the API.
| Field | Required | Type | Notes |
|---|
| object | yes | "campaign" | Public object name of the inner resource. |
| campaign_id | yes | string | Campaign id. |
| name | yes | string | Campaign name. |
| status | yes | draft | scheduled | starting | Initial campaign status. |
| total_campaigns | yes | integer | Downstream campaigns created for this request. |
| total_recipients | yes | integer | Recipients accepted into the campaign. |
| dnc_skipped | yes | integer | Recipients skipped because they are on the DNC list. |
| stopped_skipped | yes | integer | Recipients skipped because they opted out. |
{
"id": "evt_campaign_created_example",
"object": "event",
"type": "campaign.created",
"livemode": true,
"occurred_at": "2026-05-01T18:00:00.000Z",
"data": {
"object": "campaign",
"campaign_id": "campaign_uuid",
"name": "May Promo Blast",
"status": "draft",
"total_campaigns": 1,
"total_recipients": 3200,
"dnc_skipped": 14,
"stopped_skipped": 8
}
}campaign.launched
Campaign send started.
| Field | Required | Type | Notes |
|---|
| object | yes | "campaign" | Public object name of the inner resource. |
| campaign_id | yes | string | Campaign id. |
| name | yes | string | Campaign name. |
{
"id": "evt_campaign_launched_example",
"object": "event",
"type": "campaign.launched",
"livemode": true,
"occurred_at": "2026-05-01T18:01:00.000Z",
"data": {
"object": "campaign",
"campaign_id": "campaign_uuid",
"name": "May Promo Blast"
}
}campaign.paused
Active campaign paused; remaining recipients will not be sent until it is resumed.
| Field | Required | Type | Notes |
|---|
| object | yes | "campaign" | Public object name of the inner resource. |
| campaign_id | yes | string | Campaign id. |
| name | yes | string | Campaign name. |
| paused_at | yes | string | When the pause was requested. |
{
"id": "evt_campaign_paused_example",
"object": "event",
"type": "campaign.paused",
"livemode": true,
"occurred_at": "2026-05-01T18:10:00.000Z",
"data": {
"object": "campaign",
"campaign_id": "campaign_uuid",
"name": "May Promo Blast",
"paused_at": "2026-05-01T18:10:00.000Z"
}
}campaign.cancelled
Campaign cancelled before completion. Already-sent messages are not retracted.
| Field | Required | Type | Notes |
|---|
| object | yes | "campaign" | Public object name of the inner resource. |
| campaign_id | yes | string | Campaign id. |
| name | yes | string | Campaign name. |
| cancelled_at | yes | string | When the cancellation was requested. |
| reason | yes | "api_cancel" | Always api_cancel for this event. |
{
"id": "evt_campaign_cancelled_example",
"object": "event",
"type": "campaign.cancelled",
"livemode": true,
"occurred_at": "2026-05-01T18:15:00.000Z",
"data": {
"object": "campaign",
"campaign_id": "campaign_uuid",
"name": "May Promo Blast",
"cancelled_at": "2026-05-01T18:15:00.000Z",
"reason": "api_cancel"
}
}campaign.completed
All recipients have been processed (delivered or failed).
| Field | Required | Type | Notes |
|---|
| object | yes | "campaign" | Public object name of the inner resource. |
| campaign_id | yes | string | Campaign id. |
| name | yes | string | Campaign name. |
| sent_count | yes | integer | Recipients the send completed for. |
| failed_count | yes | integer | Recipients that failed. |
| recipient_count | yes | integer | Recipients in the campaign. |
{
"id": "evt_campaign_completed_example",
"object": "event",
"type": "campaign.completed",
"livemode": true,
"occurred_at": "2026-05-01T18:30:00.000Z",
"data": {
"object": "campaign",
"campaign_id": "campaign_uuid",
"name": "May Promo Blast",
"sent_count": 3188,
"failed_count": 12,
"recipient_count": 3200
}
}campaign.failed
Campaign aborted due to an error before sending could complete.
| Field | Required | Type | Notes |
|---|
| object | yes | "campaign" | Public object name of the inner resource. |
| campaign_id | yes | string | Campaign id. |
| name | yes | string | Campaign name. |
| reason | yes | "batch_execution_failed" | Always batch_execution_failed for this event. |
{
"id": "evt_campaign_failed_example",
"object": "event",
"type": "campaign.failed",
"livemode": true,
"occurred_at": "2026-05-01T18:05:00.000Z",
"data": {
"object": "campaign",
"campaign_id": "campaign_uuid",
"name": "May Promo Blast",
"reason": "batch_execution_failed"
}
}Contacts
contact.created
New contact added to the organization. Fires for both API-driven creates (POST /v1/contacts, /v1/contacts/bulk) and inbound-driven creates (an inbound message from an unknown phone number creates the contact automatically).
| Field | Required | Type | Notes |
|---|
| object | yes | "contact" | Public object name of the inner resource. |
| contact_id | yes | string | Contact id. |
| phone | yes | string | Contact phone number. |
| first_name | yes | string | null | First name when supplied. |
| last_name | yes | string | null | Last name when supplied. |
| source | yes | api | api_bulk | inbound_message | How the contact was created. |
{
"id": "evt_contact_created_example",
"object": "event",
"type": "contact.created",
"livemode": true,
"occurred_at": "2026-05-01T19:00:00.000Z",
"data": {
"object": "contact",
"contact_id": "contact_uuid",
"phone": "+14155551234",
"first_name": null,
"last_name": null,
"source": "inbound_message"
}
}contact.opted_out
Contact opted out of further messaging. Triggered automatically when an inbound message contains an exact opt-out keyword (STOP, UNSUBSCRIBE, etc.) and the org has auto-opt-out enabled.
| Field | Required | Type | Notes |
|---|
| object | yes | "contact" | Public object name of the inner resource. |
| contact_id | yes | string | Contact id. |
| phone | yes | string | Contact phone number. |
| keyword | yes | string | Exact opt-out keyword that triggered the event. |
| opted_out_at | yes | string | When the opt-out was recorded. |
{
"id": "evt_contact_opted_out_example",
"object": "event",
"type": "contact.opted_out",
"livemode": true,
"occurred_at": "2026-05-01T17:05:00.000Z",
"data": {
"object": "contact",
"contact_id": "contact_uuid",
"phone": "+14155551234",
"keyword": "STOP",
"opted_out_at": "2026-05-01T17:05:00.000Z"
}
}Premium numbers
premium_number.purchased
A premium number was successfully purchased and provisioned into inventory.
| Field | Required | Type | Notes |
|---|
| object | yes | "premium_number_operation" | Public object name of the inner resource. |
| operation_id | yes | string | Premium-number operation id. |
| operation | yes | "buy" | Always buy for this event. |
| status | yes | "completed" | Always completed for this event. |
| phone_number_id | yes | string | Purchased phone number id. |
| action_required | yes | string | null | Null on a completed purchase. |
| error_message | yes | string | null | Null on a completed purchase. |
{
"id": "evt_pn_purchased_example",
"object": "event",
"type": "premium_number.purchased",
"livemode": true,
"occurred_at": "2026-07-07T12:00:00.000Z",
"data": {
"object": "premium_number_operation",
"operation_id": "op_uuid",
"operation": "buy",
"status": "completed",
"phone_number_id": "pn_uuid",
"action_required": null,
"error_message": null
}
}premium_number.rotated
A premium number was successfully rotated and replaced with a new number.
| Field | Required | Type | Notes |
|---|
| object | yes | "premium_number_operation" | Public object name of the inner resource. |
| operation_id | yes | string | Premium-number operation id. |
| operation | yes | "rotate" | Always rotate for this event. |
| status | yes | "completed" | Always completed for this event. |
| phone_number_id | yes | string | Original phone number id. |
| replacement_phone_number_id | yes | string | null | Replacement phone number id. Null if the carrier omitted it. |
| action_required | yes | string | null | Null on a completed rotation. |
| error_message | yes | string | null | Null on a completed rotation. |
{
"id": "evt_pn_rotated_example",
"object": "event",
"type": "premium_number.rotated",
"livemode": true,
"occurred_at": "2026-07-07T12:05:00.000Z",
"data": {
"object": "premium_number_operation",
"operation_id": "op_uuid",
"operation": "rotate",
"status": "completed",
"phone_number_id": "pn_uuid",
"replacement_phone_number_id": "pn_replacement_uuid",
"action_required": null,
"error_message": null
}
}premium_number.deleted
A premium number was released from the carrier and removed from inventory.
| Field | Required | Type | Notes |
|---|
| object | yes | "premium_number_operation" | Public object name of the inner resource. |
| operation | yes | "delete" | Always delete for this event. |
| status | yes | "completed" | Always completed for this event. |
| phone_number_id | yes | string | Released phone number id. |
{
"id": "evt_pn_deleted_example",
"object": "event",
"type": "premium_number.deleted",
"livemode": true,
"occurred_at": "2026-07-07T12:10:00.000Z",
"data": {
"object": "premium_number_operation",
"operation": "delete",
"status": "completed",
"phone_number_id": "pn_uuid"
}
}premium_number.operation.failed
A premium number buy or rotate failed. Delete does not emit this event. Inspect `error_message` for details.
| Field | Required | Type | Notes |
|---|
| object | yes | "premium_number_operation" | Public object name of the inner resource. |
| operation_id | yes | string | Premium-number operation id. |
| operation | yes | buy | rotate | Buy or rotate. Delete does not emit this event. |
| status | yes | "failed" | Always failed for this event. |
| phone_number_id | yes | string | null | Phone number id the operation targeted. |
| replacement_phone_number_id | no | string | null | Present on rotate failures. Omitted on buy failures. |
| action_required | yes | string | null | Null when the operation failed outright. |
| error_message | yes | string | null | Why the operation failed. Null when the worker omitted a message. |
{
"id": "evt_pn_op_failed_example",
"object": "event",
"type": "premium_number.operation.failed",
"livemode": true,
"occurred_at": "2026-07-07T12:15:00.000Z",
"data": {
"object": "premium_number_operation",
"operation_id": "op_uuid",
"operation": "rotate",
"status": "failed",
"phone_number_id": "pn_uuid",
"replacement_phone_number_id": null,
"action_required": null,
"error_message": "Rotation budget limit reached."
}
}premium_number.operation.needs_action
A premium number operation requires additional input before it can proceed. Inspect `action_required` on the operation.
| Field | Required | Type | Notes |
|---|
| object | yes | "premium_number_operation" | Public object name of the inner resource. |
| operation_id | yes | string | Premium-number operation id. |
| operation | yes | buy | rotate | Buy or rotate. Delete does not emit this event. |
| status | yes | "needs_action" | Always needs_action for this event. |
| phone_number_id | yes | string | null | Phone number id the operation targeted. |
| replacement_phone_number_id | no | string | null | Present on rotate. Omitted on buy. |
| action_required | yes | string | null | What the operator must do next. Null if unspecified. |
| error_message | yes | string | null | Null unless the worker also recorded an error. |
{
"id": "evt_pn_op_needs_action_example",
"object": "event",
"type": "premium_number.operation.needs_action",
"livemode": true,
"occurred_at": "2026-07-07T12:20:00.000Z",
"data": {
"object": "premium_number_operation",
"operation_id": "op_uuid",
"operation": "rotate",
"status": "needs_action",
"phone_number_id": "pn_uuid",
"replacement_phone_number_id": null,
"action_required": "choose_area_code",
"error_message": null
}
}Calls
call.started
A voice call was placed or began ringing in. `data` is the call as GET /v1/calls/{id} returns it. Requires calls:read to subscribe.
| Field | Required | Type | Notes |
|---|
| object | yes | "call" | Public object name of the inner resource. |
| id | yes | string | Call id. |
| direction | yes | outbound | inbound | Whether the call is outbound or inbound. |
| status | yes | string | Current call status. |
| from | yes | string | Calling phone number. |
| to | yes | string | Called phone number. |
| user_id | yes | string | null | User the call is attributed to. |
| contact_id | yes | string | null | Contact the call is attributed to. |
| conversation_id | yes | string | null | Conversation id when the call is attached to one. |
| end_reason | yes | string | null | Why the call ended. Null until the call ends. |
| started_at | yes | string | When the call was placed or offered. |
| answered_at | yes | string | null | When the call was answered. Null until then. |
| ended_at | yes | string | null | When the call ended. Null until then. |
| duration_seconds | yes | integer | null | Connected duration in seconds. Null until the call ends. |
| created_at | yes | string | When the call record was created. |
{
"id": "evt_call_started_example",
"object": "event",
"type": "call.started",
"livemode": true,
"occurred_at": "2026-05-01T20:00:00.000Z",
"data": {
"object": "call",
"id": "call_uuid",
"direction": "outbound",
"status": "dialing",
"from": "+14155550000",
"to": "+14155551234",
"user_id": "user_uuid",
"contact_id": "contact_uuid",
"conversation_id": null,
"end_reason": null,
"started_at": "2026-05-01T20:00:00.000Z",
"answered_at": null,
"ended_at": null,
"duration_seconds": null,
"created_at": "2026-05-01T20:00:00.000Z"
}
}call.answered
A voice call was answered and connected. Requires calls:read to subscribe.
| Field | Required | Type | Notes |
|---|
| object | yes | "call" | Public object name of the inner resource. |
| id | yes | string | Call id. |
| direction | yes | outbound | inbound | Whether the call is outbound or inbound. |
| status | yes | string | Current call status. |
| from | yes | string | Calling phone number. |
| to | yes | string | Called phone number. |
| user_id | yes | string | null | User the call is attributed to. |
| contact_id | yes | string | null | Contact the call is attributed to. |
| conversation_id | yes | string | null | Conversation id when the call is attached to one. |
| end_reason | yes | string | null | Why the call ended. Null until the call ends. |
| started_at | yes | string | When the call was placed or offered. |
| answered_at | yes | string | null | When the call was answered. Null until then. |
| ended_at | yes | string | null | When the call ended. Null until then. |
| duration_seconds | yes | integer | null | Connected duration in seconds. Null until the call ends. |
| created_at | yes | string | When the call record was created. |
{
"id": "evt_call_answered_example",
"object": "event",
"type": "call.answered",
"livemode": true,
"occurred_at": "2026-05-01T20:00:06.000Z",
"data": {
"object": "call",
"id": "call_uuid",
"direction": "outbound",
"status": "in_progress",
"from": "+14155550000",
"to": "+14155551234",
"user_id": "user_uuid",
"contact_id": "contact_uuid",
"conversation_id": null,
"end_reason": null,
"started_at": "2026-05-01T20:00:00.000Z",
"answered_at": "2026-05-01T20:00:06.000Z",
"ended_at": null,
"duration_seconds": null,
"created_at": "2026-05-01T20:00:00.000Z"
}
}call.ended
A voice call ended, whether it connected or not. `end_reason` says how; `duration_seconds` is the connected time. Requires calls:read to subscribe.
| Field | Required | Type | Notes |
|---|
| object | yes | "call" | Public object name of the inner resource. |
| id | yes | string | Call id. |
| direction | yes | outbound | inbound | Whether the call is outbound or inbound. |
| status | yes | string | Current call status. |
| from | yes | string | Calling phone number. |
| to | yes | string | Called phone number. |
| user_id | yes | string | null | User the call is attributed to. |
| contact_id | yes | string | null | Contact the call is attributed to. |
| conversation_id | yes | string | null | Conversation id when the call is attached to one. |
| end_reason | yes | string | null | Why the call ended. Null until the call ends. |
| started_at | yes | string | When the call was placed or offered. |
| answered_at | yes | string | null | When the call was answered. Null until then. |
| ended_at | yes | string | null | When the call ended. Null until then. |
| duration_seconds | yes | integer | null | Connected duration in seconds. Null until the call ends. |
| created_at | yes | string | When the call record was created. |
{
"id": "evt_call_ended_example",
"object": "event",
"type": "call.ended",
"livemode": true,
"occurred_at": "2026-05-01T20:02:06.000Z",
"data": {
"object": "call",
"id": "call_uuid",
"direction": "outbound",
"status": "completed",
"from": "+14155550000",
"to": "+14155551234",
"user_id": "user_uuid",
"contact_id": "contact_uuid",
"conversation_id": null,
"end_reason": "completed",
"started_at": "2026-05-01T20:00:00.000Z",
"answered_at": "2026-05-01T20:00:06.000Z",
"ended_at": "2026-05-01T20:02:06.000Z",
"duration_seconds": 120,
"created_at": "2026-05-01T20:00:00.000Z"
}
}