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 100 queued events destined for the same webhook URL are batched into a single HTTP POST request and delivered sequentially in FIFO order.
  • Retries & backoff: If the client endpoint does not return a 2xx HTTP status code (or if the connection times out), delivery is retried up to 20 times using quadratic backoff:

    delay = base + (base × retry2) seconds, where base = 60 seconds.

  • Idempotency: Retried deliveries reuse the original eventId. Receiving servers should track processed eventId values to avoid duplicate processing.

2. Verifying X-Hub-Signature-256

  1. Read the X-Hub-Signature-256 header and verify that it starts with sha256=.
  2. Capture the raw UTF-8 request body bytes before parsing or re-serializing JSON.
  3. 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.
  4. 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).

More information