Skip to main content
Webhooks let SmsManager push events to your server the moment something happens — a message is delivered, a delivery fails, or a recipient replies. Instead of polling the API for status updates, your endpoint receives an HTTP POST request containing a JSON payload describing the event. This is the most efficient way to build real-time message tracking, automate retries, and handle inbound messages.

Webhook types

SmsManager sends three types of webhook events:

sentMessage

Fired whenever the delivery status of an outbound message changes. You may receive multiple events per message as it moves through the delivery pipeline — for example, first sent, then delivered. Status values include: sending, sent, delivered, undelivered, rejected, failed, and seen (Viber/WhatsApp only).

incomingReplyMessage

Fired when a recipient replies directly to a message you sent. The payload links the reply to the original outbound message via message_id.

incomingMessage

Fired for unsolicited inbound messages — messages that arrive on your number but are not in direct reply to a specific outbound message you sent.

Setting up a webhook URL

You can configure webhook delivery in two ways: 1. Per-message callback — set the callback field in the message request body. SmsManager posts all delivery events for that specific message to the URL you provide.
Per-message callback
2. Account-wide default — set a default_callback_url on your API key via the SmsManager REST API. All messages sent with that API key will use this URL unless overridden by a per-message callback field.
Set default callback URL
Use an account-wide default during development so you capture events from all test messages without having to set callback on each request.

Webhook payload format

SmsManager posts an array of event objects to your callback URL. Multiple delivery events may be batched into a single POST. Here is a full example of a sentMessage payload for a delivered SMS:
sentMessage payload
The channel-specific object (sms, viber, whatsapp_template, or whatsapp_body) varies by the gateway value:

The payload field

When you include a payload object in your original message request, SmsManager echoes it back in every webhook event for that message. Use this to correlate delivery events with your own application data — order IDs, user IDs, campaign names, and so on — without needing to look anything up by message_id.
Message request with payload
In the webhook, you receive the same payload object:
Webhook event (excerpt)

Delivery status sequence

A typical successful delivery produces two webhook events in sequence:
If delivery fails, the sequence ends with:
Or immediately with:
For Viber and WhatsApp, you may also receive a seen event when the recipient opens the message.
Your webhook handler must be idempotent — SmsManager may deliver the same event more than once in rare cases (network retries). Use message_id + result as a deduplication key.

Handling incoming messages

incomingReplyMessage — a reply to one of your outbound messages:
incomingReplyMessage payload
incomingMessage — an unsolicited inbound message not tied to a specific outbound:
incomingMessage payload

Best practices

  • Respond with HTTP 200 immediately. SmsManager considers any non-2xx response a failure and will retry. Return 200 OK as fast as possible, then process the payload asynchronously (for example, push it to a queue).
  • Handle duplicate webhooks. Network issues can cause the same event to be delivered more than once. Use message_id + result as a composite key to deduplicate events before processing.
  • Log raw webhook payloads. Store the raw JSON body alongside your processed data so you can replay events during debugging without relying on SmsManager’s retry window.
  • Validate message_id against your records. Ignore events for message IDs you don’t recognise — this protects against spoofed webhook requests.
  • Use HTTPS. Always expose your webhook endpoint over HTTPS to protect message content and delivery metadata in transit.

result_info codes

The result_info field gives a human-readable description of the delivery outcome. It follows the format [code] Description where the numeric code is carrier-specific and optional. Common examples: Use result (the machine-readable enum) in your application logic, and result_info for logging and support.

What SmsManager POSTs to your endpoint

What SmsManager sends to your callback URL

Next steps

Send SMS

Learn how to set the callback field on SMS messages.

Send Viber

Understand Viber-specific delivery statuses and the seen event.

Batch Sending

Correlate batch delivery events using message_id index suffixes.

Phone Verification

Use the Verify API for OTP flows with HMAC offline proofs.