Webhook IP allowlist: GitHub and Stripe publish ranges, Sume does not
GitHub exposes webhook IPs via /meta and Stripe lists addresses. The Sume docs publish no sender ranges, so verify the signature and a 5-minute window.

You cannot allowlist Sume's webhook senders by IP, because the Sume docs I read publish no address list. GitHub and Stripe both do, and both tell you to use the list as an extra layer. For Sume, the control you have is the signature plus the timestamp window.
What the other vendors say
GitHub's best practices say you can restrict your server to GitHub's addresses, which you fetch from the GET /meta endpoint, and that the addresses change occasionally. Stripe's webhook page recommends using both protections: an allowlist of its published addresses and signature verification.
Both pages treat the IP list as a complement. The signature is the part that proves the body was not forged or altered.
| Vendor | Published sender IPs | Signature |
|---|---|---|
| GitHub | Yes, from GET /meta; changes occasionally | Secret-based; use a high-entropy secret |
| Stripe | Yes, a published list | Stripe-Signature, HMAC-SHA256 with t= and v1= |
| Sume | None in the docs I read | x-sume-webhook-signature: sume-v1=<hex>, HMAC-SHA256 over timestamp.raw_body |
What you can rely on with Sume
Sume also validates your URL in the other direction: it must be public HTTPS, and localhost or private-network URLs are rejected. Run webhooks re-check that at delivery time. That means your receiver has to be reachable from the internet, so put it behind a TLS-terminating gateway rather than a private subnet.
- The signature covers the timestamp and the raw body, so a forged or edited body fails.
- The default replay tolerance is 5 minutes in the SDK verifier, so an old captured request is rejected.
- During a secret rotation the header carries several sume-v1 entries, newest first, for a 24-hour window.
- The x-sume-webhook-secret-fingerprint header tells you which secret signed the request.
If your network policy demands an IP list
Do not copy addresses from a log and freeze them into a firewall. Without a published list they can change without notice, and you will drop real deliveries. Keep the endpoint open to the internet, rate-limit it at the edge, reject unsigned requests before any work, and ask Sume support whether a range is available for your plan. I found no commitment in the docs either way.
A defensive baseline
Treat the endpoint as public. Accept only POST, cap the body size, and compute the signature before parsing JSON so unsigned traffic costs almost nothing. Use a constant-time comparison for the signature, and refuse to start if the signing secret is empty, because an empty secret makes every signature predictable.
Keep the secret out of source control and read it from the environment, where Sume's docs name SUME_COM_WEBHOOK_SIGNING_SECRET. Log the secret fingerprint header, not the secret itself, so a mismatch after a rotation is easy to diagnose. If you later receive a published IP list from any vendor, add it as a second layer, as GitHub and Stripe suggest, but keep the signature check in place.
Sources
Related posts
More in Developers
- Return 503 with Retry-After in a deploy: Sume run webhooks honour it
Sume run webhooks honour Retry-After on 429 and 503 up to 1 hour. Job webhooks use a fixed 30s spacing, so keep the drain short and the fallback poll on.
- Which Sume audio endpoint to call: TTS, STT, music, detach, timeline
A decision map for Sume's audio API: seven endpoints, what each takes in and returns, limits and list prices, and the order they chain in.
- Sume video tools: public URL or media import first? Per tool
Video captions takes a public HTTPS URL; trim, filter, inspect, frames, compose and detach need a workspace media.sume.com clip. A tool-by-tool input guide.
- Which voice does my avatar speak with? Check voice.status is ready
Sume TTS speaks in an avatar's voice when voice.status is ready. List avatars, check voice.status, then send avatar_id or avatar_handle on the TTS request.
Written by Sume