Webhooks

Webhooks are SIMRelay's push-based event mechanism. Subscribe an HTTPS endpoint, and we send POST requests when SMS arrives, when delivery happens, or when a hosted SIM changes state. Every webhook is HMAC-SHA256 signed.

Events you can subscribe to

  • message.inbound — a new SMS arrived at one of your numbers.
  • message.delivery — an outbound SMS reached (or failed to reach) the recipient.
  • number.claimed / number.released — hosted SIM lifecycle.
  • number.locked / number.unlocked — lock state changes.

Setup

Create a webhook subscription per team via the dashboard or API. You'll provide the endpoint URL, the events you want, and a signing secret (we generate one for you; rotate any time). Once active, we start delivering events. Test from the dashboard before relying on it.

Payload shape

{
  "event": "message.inbound",
  "event_id": "evt_abc123",
  "timestamp": "2026-05-11T14:30:00Z",
  "data": {
    "message_id": "msg_xyz789",
    "from": "+491701234567",
    "to": "+4915123456789",
    "body": "Your verification code is 482915",
    "received_at": "2026-05-11T14:29:58Z"
  }
}

Signature verification

The X-Simrelay-Signature header carries an HMAC-SHA256 over the raw request body, using your signing secret. Verify on your end before trusting the payload. Pseudocode:

signature = request.header("X-Simrelay-Signature")
expected = hmac_sha256(signing_secret, raw_request_body)
if not constant_time_compare(signature, expected):
    return 401

Retry policy

We retry failed deliveries with exponential backoff for up to 24 hours: at 1m, 5m, 15m, 1h, 4h, 12h, 24h. After that the event is marked failed and surfaced in the delivery log. We do not auto-disable webhooks for repeated failures, but we'll email the team admin after sustained failure.

Idempotency

Each event has a stable event_id. Treat retries as idempotent on your side — check whether you've already processed the ID before acting on it.