message.sent
POST
your webhook addressMessage sent. The provider sent the message to the network. The data is the message as GET /messages/{id} returns it, without events; status is the status of this change (the message may have moved on by the time the webhook arrives).
Body
| Field | Type | Description |
|---|---|---|
type | string | Always message.sent. |
timestamp | string (date-time) | When the event happened, UTC. |
data | Message |
json
{
"type": "message.sent",
"timestamp": "2026-11-02T12:00:04+00:00",
"data": {
"id": "msg_CgdWeHQN4sPaZnXfh7kP5",
"status": "sent",
"to": "+5521998120937",
"from": null,
"country": "BR",
"channel": "whatsapp",
"template": {
"name": "welcome_bonus",
"version": 3
},
"language": "pt",
"reference": "crm-42",
"text": "Olá Ana! Seu bônus BONUS10 já está ativo.",
"text_masked": false,
"segments": 1,
"encoding": null,
"price": {
"amount": "0.062500",
"currency": "USD"
},
"error": null,
"test": false,
"campaign": null,
"created_at": "2026-11-02T12:00:00+00:00",
"updated_at": "2026-11-02T12:00:00+00:00"
}
}Objects
Message object
| Field | Type | Description |
|---|---|---|
id | string | The message, msg_…. |
status | string | One of: accepted, queued, submitted, sent, delivered, read, rejected, failed, expired, cancelled. |
to | string | The number in E.164. |
from | string, nullable | The sender name of an SMS; null for WhatsApp (its number is not shown) and for a test SMS. |
country | string | ISO 3166-1 alpha-2 of the number. |
channel | string | One of: whatsapp, sms. |
template | object, nullable | The template and the number of the version the message was sent with; null for an own SMS text. |
template.name | string | |
template.version | integer | |
language | string, nullable | The language of the template; null for an own SMS text. |
reference | string, nullable | Your own id of the message, as you sent it. |
text | string, nullable | The text as sent; null once it is past its retention period (90 days, text_masked). |
text_masked | boolean | Whether text was erased after the retention period (90 days). |
segments | integer | The parts the SMS is sent and priced in (its price is the price of a segment times them); 1 for WhatsApp. |
encoding | string, nullable | The encoding of the SMS: gsm7 (160 characters, 153 a segment of a longer text) or ucs2 (70, 67); null for WhatsApp. One of: gsm7, ucs2. |
price | object, nullable | The price fixed at acceptance, in the currency of the account; for an SMS, the price of a segment times segments. Null for a test message. |
price.amount | string | |
price.currency | string | |
error | object, nullable | Why the message did not reach the recipient: a stable code and a text in the language of Accept-Language. Null while it is on its way or when delivered. |
error.code | string | |
error.text | string | |
test | boolean | Sent with a test key: through the sandbox, free. |
campaign | object, nullable | The console campaign that sent the message; null for a message of the API. |
campaign.id | string | |
campaign.name | string | |
created_at | string | When the message was accepted. |
updated_at | string | When the message last changed. |
Headers
| Header | Description |
|---|---|
webhook-id | The delivery, whd_…. The same on every attempt of one delivery: use it to drop a repeated delivery. |
webhook-timestamp | Unix time of the attempt, in seconds. Refuse deliveries older than 5 minutes. |
webhook-signature | v1, and the base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}, keyed with the secret (the part after whsec_, base64-decoded). |
content-type | application/json |
user-agent | ACE-SEND-Webhooks/1 |
Check the signature before you trust the body, answer 2xx within 5 seconds and do the work afterwards. See Webhooks for the signature check, retries and duplicates.