Skip to content
ROAD RUNNER

WEBHOOKS

Register a webhook endpoint

POST roadrunnerzw.com/api/v1/webhooks

Subscribe to delivery events. Use ["*"] to receive everything.

The response includes a secret: shown once and never again. Use it to verify the X-RR-Signature header on every event we send: hmac_sha256(secret, timestamp + "." + sha256(raw_body)).

URLs must use HTTPS and resolve to a public address.

REQUEST
curl -X POST https://roadrunnerzw.com/api/v1/webhooks \
  -H 'Authorization: Bearer rr_live_your_key_id' \
  -H 'X-RR-Timestamp: $(date +%s)' \
  -H 'X-RR-Signature: $SIGNATURE' \
  -H 'Content-Type: application/json' \
  -d '{
      "url": "https://example.com/hooks/roadrunner",
      "events": [
          "delivery.dispatched",
          "delivery.delivered",
          "delivery.failed"
      ]
  }'
RESPONSE 201
{
    "id": "whk_01JAV3K2QX8M4N7P",
    "object": "webhook_endpoint",
    "url": "https://example.com/hooks/roadrunner",
    "events": [
        "delivery.dispatched",
        "delivery.delivered",
        "delivery.failed"
    ],
    "active": true,
    "consecutive_failures": 0,
    "last_success_at": null,
    "disabled_at": null,
    "created_at": "2026-09-21T14:30:00+02:00",
    "secret": "whsec_EXAMPLESECRETVALUE000000000000000000000"
}

Body

  • url string REQUIRED

    Where we should POST. HTTPS, reachable from the internet, and not an address on a private network: we check before we store it and again before every send.

  • events array of strings REQUIRED

    Which events to send here, at least one. See the Webhooks guide for the full list.

Responses

201 Created

The endpoint was registered. secret is shown ONCE: store it now.

401 Unauthenticated

The signature, key or timestamp did not check out. Also returned for a revoked key, and for a timestamp more than 300 seconds from ours.

403 Forbidden

The key is valid but was not issued the scope this endpoint requires. Scopes are fixed at issue, so this needs a new key rather than a retry.

422 Validation failed

The request was understood and refused. Same envelope as every other error; details names each field at fault, so retrying unchanged will fail the same way.

429 Too many requests

Too many requests for this client. Back off and retry; the response carries Retry-After and X-RateLimit-* headers.