Incoming message event (message.received)
Dispatched via HTTP POST to the user account's registered webhook URL whenever a new inbound SMS message arrives in the inbox folder.
POST <client_webhook_url>
Table of contents
Callback summary
| Property | Value |
| Event type | "message.received" |
| HTTP method | POST |
| Target endpoint | Client's registered webhook url (configured via POST /api/v2/webhook or PUT /api/v2/webhook) |
| Content-Type | application/json |
| Signature header | X-Hub-Signature-256: sha256=<hex_digest> |
| Expected client response | Any 2xx HTTP status code (e.g., 200 OK, 204 No Content); no response payload is required |
Important: Webhook requests are always formatted as a JSON array of event envelopes (WebhookEventEnvelope[]), even when delivering a single event (an array of length 1, up to 100 events per delivery request). If the webhook subscription includes multiple event types, a single batch array may contain both "message.received" and "message.status.updated" events. Receiving endpoints must deserialize the root payload as an array and inspect each item's type discriminator.
Request headers (sent to client)
| Header | Presence | Description |
Content-Type |
Always | application/json |
X-Hub-Signature-256 |
When secret is configured |
Lowercase hexadecimal HMAC-SHA256 signature of the raw UTF-8 request body, prefixed with sha256= (e.g., sha256=9f83a04b...), computed using the webhook's shared secret (whsec_...). |
Webhook payload schema
Root array (WebhookDeliveryPayload)
| Type | Description |
object[] (WebhookEventEnvelope[]) |
Non-empty JSON array of 1 to 100 event envelope objects. |
Event envelope object (WebhookEventEnvelope)
| Field | Type | Description |
eventId |
string (UUID) | Unique identifier for this webhook event. Retained across retry attempts; use this value for idempotency and deduplication. |
time |
string (ISO 8601) | Timestamp when the event occurred (with timezone offset). |
type |
string | Event type discriminator. Set to "message.received" for incoming message events. |
user |
string | Username of the account that received the message. |
payload |
object (MessageReceivedPayload) |
Event-specific data object containing the incoming SMS details. |
payload object (MessageReceivedPayload)
Properties with null values (such as unused binary fields on a text SMS, or content on a binary SMS) are omitted from the serialized JSON output.
| Field | Type | Presence | Description |
messageId |
string (UUID) | Always | Unique identifier of the received message. |
from |
string | When available | Sender phone number (E.164 format) or alphanumeric sender ID. Omitted if null. |
to |
string | Always | Destination recipient phone number (gateway number/short code that received the SMS). |
type |
string | Always | Message payload type: "text" or "binary". |
content |
string | When type is "text" |
Text content of the incoming SMS message. Omitted when type is "binary". |
hexContent |
string | When type is "binary" |
Hexadecimal-encoded binary payload. Omitted when type is "text". |
userDataHeader |
string | Optional ("binary") |
Hexadecimal-encoded User Data Header (UDH). Present only on "binary" messages when UDH is present. |
dataCoding |
integer | When type is "binary" |
Data coding scheme (DCS) integer. Omitted when type is "text". |
createdAt |
string (ISO 8601) | Always | Timestamp when the message was received by the gateway. |
Delivery, retry & signature verification
1. Batching & retry policy
- Batch size: Up to
100queued events destined for the same webhook URL are batched into a single HTTPPOSTrequest and delivered sequentially in FIFO order. - Retries & backoff: If the client endpoint does not return a
2xxHTTP status code (or if the connection times out), delivery is retried up to20times using quadratic backoff:delay = base + (base × retry2) seconds, wherebase = 60 seconds. - Idempotency: Retried deliveries reuse the original
eventId. Receiving servers should track processedeventIdvalues to avoid duplicate processing.
2. Verifying X-Hub-Signature-256
- Read the
X-Hub-Signature-256header and verify that it starts withsha256=. - Capture the raw UTF-8 request body bytes before parsing or re-serializing JSON.
- Compute the HMAC-SHA256 hash over the raw body bytes using the UTF-8 bytes of the shared
secret(whsec_...) returned when the webhook was configured. - Format the hash as lowercase hexadecimal prefixed with
sha256=and compare it against the header value using a constant-time comparison function (e.g.,CryptographicOperations.FixedTimeEquals).
Examples
1. Incoming text SMS event (text)
Single message.received event delivered inside the root JSON array when a standard text SMS arrives.
Webhook request (sent to client):
POST /api/sms/inbound HTTP/1.1 Host: client.example.com Content-Type: application/json X-Hub-Signature-256: sha256=9f83a04b12c845d09e3a7b6c5d4e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e
[
{
"eventId": "26385eed-6a6c-4deb-b549-dc055211a71d",
"time": "2026-10-21T10:21:00+02:00",
"type": "message.received",
"user": "http_user",
"payload": {
"messageId": "26385eed-6a6c-4deb-b549-dc055211a71d",
"from": "+36201002000",
"to": "+36201002001",
"type": "text",
"content": "Message 1 goes to 1 number",
"createdAt": "2026-10-21T10:21:00+02:00"
}
}
]
Expected client response (2xx):
HTTP/1.1 200 OK
(No response payload is required)
2. Incoming binary SMS event (binary)
Single message.received event delivered when a binary SMS with a User Data Header (UDH) and data coding scheme (DCS) arrives.
Webhook request (sent to client):
POST /api/sms/inbound HTTP/1.1 Host: client.example.com Content-Type: application/json X-Hub-Signature-256: sha256=3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d
[
{
"eventId": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
"time": "2026-10-21T10:22:00+02:00",
"type": "message.received",
"user": "http_user",
"payload": {
"messageId": "37492ffd-7b7d-4efc-c65a-ed166322b82e",
"from": "+36201002000",
"to": "+36201002001",
"type": "binary",
"hexContent": "0605040B8423F0",
"userDataHeader": "050003340201",
"dataCoding": 4,
"createdAt": "2026-10-21T10:22:00+02:00"
}
}
]
3. Batch delivery of multiple incoming messages
When multiple inbound SMS messages arrive concurrently, up to 100 event envelopes are batched into a single HTTP POST request.
Webhook request (sent to client):
POST /api/sms/inbound HTTP/1.1 Host: client.example.com Content-Type: application/json X-Hub-Signature-256: sha256=7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f
[
{
"eventId": "26385eed-6a6c-4deb-b549-dc055211a71d",
"time": "2026-10-21T10:21:00+02:00",
"type": "message.received",
"user": "http_user",
"payload": {
"messageId": "26385eed-6a6c-4deb-b549-dc055211a71d",
"from": "+36201002000",
"to": "+36201002001",
"type": "text",
"content": "First inbound message",
"createdAt": "2026-10-21T10:21:00+02:00"
}
},
{
"eventId": "8f3b2a1c-9d4e-4f5a-b6c7-1a2b3c4d5e6f",
"time": "2026-10-21T10:21:01+02:00",
"type": "message.received",
"user": "http_user",
"payload": {
"messageId": "8f3b2a1c-9d4e-4f5a-b6c7-1a2b3c4d5e6f",
"from": "+36201003000",
"to": "+36201002001",
"type": "text",
"content": "Second inbound message",
"createdAt": "2026-10-21T10:21:01+02:00"
}
}
]
Client response requirements
| Client HTTP status code | Dispatcher behavior |
2xx (200 OK – 299) |
Delivery is marked as acknowledged and removed from the dispatch queue. No response payload is required (any response body is ignored). |
3xx, 4xx, 5xx, or Network Timeout |
Delivery is treated as failed and scheduled for retry according to the quadratic backoff policy (up to 20 retries). |