--- title: "Message Events" description: "Receive SMS and WhatsApp activity from Voicetta. Use message events for live communication data and thread events for the finished conversation." publishedAt: "2026-08-22" modifiedAt: "2026-08-22" category: "Reference" tags: "Voicetta, SMS, WhatsApp, webhook, message.received, message.sent, text messages" navOrder: "32" canonical: "https://voicetta.com/developers/message-events" --- # Message Events Voicetta sends SMS and WhatsApp activity through two events. Use them when your product needs to know what is happening in a conversation. | Event | Fires for | |---|---| | `message.received` | A customer message and the reply generated by Voicetta | | `message.sent` | A message Voicetta sends without an incoming customer message | For the finished conversation and its evaluation, use [`thread.completed`](/developers/thread-events). ## Why there are two events An incoming message and an outgoing message are different events. When a customer sends a message, Voicetta creates a `message.received` event. If the assistant replies in the same turn, that reply is included in the `reply` field. When Voicetta starts the conversation itself, it creates a `message.sent` event. That can happen when the voice assistant sends a confirmation during a call or when a follow-up is sent. ## `message.received` ```json { "event": "message.received", "event_id": "b71e9d02-4a6c-4f18-9d3e-7c2b5a4e8f31", "version": 1, "occurred_at": "2026-08-20T14:12:00+00:00", "message": { "message_id": "b71e9d02-4a6c-4f18-9d3e-7c2b5a4e8f31", "workspace_id": "2a1f8e7d-4c3b-4a29-9f18-6d5e4c3b2a19", "assistant_id": "7c6b5a49-3e2d-4c1b-8a97-5f4e3d2c1b09", "assistant_name": "Front Desk", "channel": "whatsapp", "direction": "inbound", "thread_id": "c82fa013-5b7d-4029-8e4f-8d3c6b5f9a42", "source": "inbound", "occurred_at": "2026-08-20T14:12:00+00:00", "content": "Do you have a room free on Friday?", "provider_message_id": "SM8f3c1a2b4d5e6f70", "reply": { "content": "Yes, we have a double available. Shall I hold it?", "provider_message_id": "SM1a2b3c4d5e6f7080", "timestamp": "2026-08-20T14:12:04+00:00" }, "customer": { "customer_id": "5d4c3b2a-1f09-4e8d-7c6b-5a493e2d1c0b", "name": "Jane Texter", "phone": "+15551234567" } } } ``` ## `message.sent` ```json { "event": "message.sent", "event_id": "d93ba124-6e8f-4130-9a5f-9e4d7c6b0a53", "version": 1, "occurred_at": "2026-08-20T10:03:12+00:00", "message": { "message_id": "d93ba124-6e8f-4130-9a5f-9e4d7c6b0a53", "workspace_id": "2a1f8e7d-4c3b-4a29-9f18-6d5e4c3b2a19", "assistant_id": "7c6b5a49-3e2d-4c1b-8a97-5f4e3d2c1b09", "assistant_name": "Front Desk", "channel": "sms", "direction": "outbound", "thread_id": "e04cb235-7f90-4241-8b60-af5e8d7c1b64", "source": "voice_tool", "occurred_at": "2026-08-20T10:03:12+00:00", "content": "Your booking reference is BK-4471. See you Friday.", "provider_message_id": "SM2b3c4d5e6f708190", "customer": { "customer_id": "5d4c3b2a-1f09-4e8d-7c6b-5a493e2d1c0b", "phone": "+15551234567" } } } ``` ## Reading the fields * `content` is the message text. * `channel` is `sms` or `whatsapp`. * `direction` is `inbound` or `outbound`. * `thread_id` identifies the conversation. * `provider_message_id` is the carrier's message id when available. * `reply` appears on `message.received` when the assistant replies in the same turn. ## `source` | Value | Meaning | |---|---| | `inbound` | Customer started the conversation | | `voice_tool` | Voice assistant sent the message during a call | | `evaluation_follow_up` | Recovery follow-up after evaluation | | `test` | Dashboard test message | Test messages are not delivered to production webhooks or returned by the read API. Treat unknown future source values as unknown origins, not errors. ## Timing Messages are usually delivered within 15–30 seconds. They are not guaranteed to arrive in order. If order matters, sort by `occurred_at`. ## Costs If you enable the `costs` block, messages can include an indicative message cost. This is not the billed amount. Use your invoice as the source of truth for billing. ## What messages do not contain A single message does not contain: * a conversation summary * evaluation results * a recording * call latency * assistant configuration Use `thread.completed` for the finished conversation. ## Reading messages through the API ```text GET /v1/messages ``` You can filter by date, assistant, channel, direction, and `thread_id`. Use the API when you need history or when you need to recover messages your webhook did not receive. ## Related pages * [Webhook Reference](/developers/webhooks) * [Thread Events](/developers/thread-events) * [Read API Reference](/developers/api-reference) * [Quickstart](/developers/quickstart)