Skip to main content
Surge sends HTTP POST requests to a URL you control whenever something happens: a message arrives, a campaign is approved, a contact opts out. You configure the URL in the dashboard and Surge takes care of delivery, retries, and ordering.

1. Configure your webhook endpoint

Go to Settings → Webhooks in the dashboard at hq.surge.app. Add the URL where you want to receive events. Surge sends all event types to a single endpoint (you filter by type in your handler). Your endpoint must:
  • Be publicly accessible over https:// (or http://, but HTTPS is strongly recommended)
  • Resolve to a public IP address
  • Return a 2xx status code within the request timeout
  • Handle duplicate deliveries (Surge retries failed attempts, so your handler should be idempotent)
Webhook URL restrictions. Surge blocks webhook URLs that resolve to private IP ranges (10.x.x.x, 172.16.x.x, 192.168.x.x, 127.x.x.x) or reserved TLDs (.local, .internal, .localhost, .test) to prevent server-side request forgery. This means http://localhost:4000/webhooks won’t work — use a tunneling service like ngrok or Cloudflare Tunnel in development.

2. Verify the signature

Every webhook request includes a webhook-signature header. Verifying it confirms the request came from Surge and wasn’t tampered with in transit. Surge signs requests using HMAC-SHA256 following the Standard Webhooks specification. Use the standardwebhooks library in Python, TypeScript, or Ruby, or compute the signature directly in any language.
Surge sets three headers on every request: webhook-id, webhook-timestamp, and webhook-signature. The library handles them for you in Python / TypeScript / Ruby; you read them directly when computing the signature manually (Elixir example below).

Where to find your webhook secret

Your signing secret is in Settings → Webhooks in the dashboard, next to your webhook endpoint URL.

3. Handle events

A webhook event has this shape:
A minimal handler checks type and dispatches:
Return 200 quickly. If your processing takes time, enqueue the work and return immediately — Surge will retry if your handler times out.

Replay protection

The Standard Webhooks spec includes a timestamp in the signature payload. Surge rejects replays outside a tolerance window. If you’re testing with recorded payloads, make sure your test framework handles timestamp validation or disables it appropriately.

Older signature header

Earlier versions of Surge used surge-signature as the header name. This header is deprecated and being phased out. If your handler still reads surge-signature, migrate to webhook-signature. See Deprecation Notices.

Next steps

Webhook events

Every event type, its payload shape, and when it fires.

Two-way messaging

Reply to inbound messages and keep conversation state in sync.

Signature validation

Reference for the Standard Webhooks signature scheme Surge uses.

Deprecation notices

Migrating from the older surge-signature header.