SBS TELECOM — 20 years of Tier-1 SMS termination and enterprise messaging excellence.Explore Solutions
S
SBS TELECOMEnterprise Telecom
Webhooks

Real-Time Delivery Notifications

Push-based webhooks deliver delivery receipts and inbound messages to your endpoint the moment they occur — no polling required. Signed, retried, and built for production reliability.

Webhook Types

Real-Time Events for Every Message

Delivery Receipt Webhooks

Fired when a message delivery status changes — on delivery, failure, or expiry. Provides real-time confirmation that a message has reached (or failed to reach) the recipient.

  • Delivered confirmation
  • Failed delivery notification
  • Expired message notification
  • Carrier-level status detail

MO Message Webhooks

Fired when an inbound message (MO) is received on your virtual number or shared shortcode. Delivers the sender's number, message content, and timestamp to your endpoint.

  • Inbound SMS to your number
  • Sender number and content
  • Received timestamp
  • Network identifier

Retry Logic

If your webhook endpoint is unreachable or returns a non-2xx status, our system retries delivery using exponential backoff — ensuring you never permanently lose a webhook event.

  • Automatic retry on failure
  • Exponential backoff (15s, 1m, 5m, 30m, 2h)
  • Up to 5 retry attempts
  • Failed event logging

Signature Verification

Every webhook request is signed with an HMAC-SHA256 signature using your webhook secret. Verify the signature on your server to confirm the request genuinely originated from SBS TELECOM.

  • HMAC-SHA256 request signing
  • Signature in X-SBS-Signature header
  • Timestamp in X-SBS-Timestamp
  • Replay attack prevention
Payload Format

Webhook Payload Structure

All webhooks are delivered as HTTP POST requests with a JSON body. The payload structure is consistent across event types, with an event field identifying the type.

Delivery Receipt Payload
  • eventdelivery_receipt
  • messageIdYour message ID from submit
  • toDestination number (E.164)
  • fromSender ID used
  • statusDELIVERED | FAILED | EXPIRED | UNDELIVERABLE
  • errorCodeCarrier error code (on failure)
  • deliveredAtISO 8601 delivery timestamp
  • networkCarrier network identifier
Delivery Receipt Example
POST https://yourapp.com/webhooks/sms
Content-Type: application/json
X-SBS-Signature: sha256=abc123...
X-SBS-Timestamp: 1711101735

{
  "event": "delivery_receipt",
  "messageId": "msg_01HX8K2P4NQR9VTZE",
  "to": "+447911123456",
  "from": "SBSTELECOM",
  "status": "DELIVERED",
  "errorCode": null,
  "deliveredAt": "2025-03-22T10:42:16Z",
  "network": "EE-UK",
  "latency": 0.82
}
MO Message Example
{
  "event": "mo_message",
  "messageId": "mo_01HX9M3Q6PRW0XUZB",
  "from": "+447911654321",
  "to": "74100",
  "text": "STOP",
  "receivedAt": "2025-03-22T10:45:01Z",
  "network": "Vodafone-UK"
}
Security

Verifying Webhook Signatures

Every webhook request includes an HMAC-SHA256 signature computed from the request timestamp and body, using your webhook signing secret. Always verify this signature before processing the payload.

Reject any request where signature verification fails — it may be a forged or replayed request. Also check that the timestamp in the X-SBS-Timestamp header is within an acceptable window (we recommend 5 minutes) to prevent replay attacks.

  • Retrieve your signing secret from the portal
  • Compute HMAC-SHA256 of timestamp.body
  • Compare with X-SBS-Signature header value
  • Reject if signatures do not match
  • Reject if timestamp is outside 5-minute window
  • Return HTTP 200 only after successful verification
Signature Verification (Python)
import hmac
import hashlib
import time

def verify_webhook(
    payload: bytes,
    signature_header: str,
    timestamp_header: str,
    secret: str
) -> bool:
    # Check timestamp recency (5 min window)
    ts = int(timestamp_header)
    if abs(time.time() - ts) > 300:
        return False

    # Compute expected signature
    msg = f"{timestamp_header}.{payload.decode()}"
    expected = hmac.new(
        secret.encode(),
        msg.encode(),
        hashlib.sha256
    ).hexdigest()

    # Compare signatures securely
    received = signature_header.replace('sha256=', '')
    return hmac.compare_digest(expected, received)

Ready to Implement Webhooks?.

Get API credentials and a webhook signing secret to start receiving real-time delivery notifications.

UK Registered20 Years ExperienceTier-1 Connectivity190+ Countries24/7 Support