Early bird discounts live! Claim your offer

Webhook Security

Secret rotation, replay windows, and what to trust on an inbound delivery.

Outbound webhooks are the only way Subscriby talks to your infrastructure unprompted. Getting the security right prevents spoofing and replay.

Trust only signed, fresh payloads

Every delivery carries:

  • SB-Signature: t=<unix>,v1=<hex_hmac_sha256(secret, "t.body")>
  • SB-Event-Id: <ulid> — unique per event.
  • SB-Event-Name: <event> — matches payload.type.

Do three things on every inbound POST:

  1. Verify the signature with constant-time comparison (crypto.timingSafeEqual / hash_equals / hmac.compare_digest).
  2. Reject stale deliveries — if abs(now - t) > 300 (5 minutes), drop the request even if the signature matches. This is your replay window.
  3. De-dupe on event_id — store seen IDs for at least 24 hours. Retries cause the same event to arrive more than once.

Secret rotation

Rotate a webhook secret the moment a developer leaves, a laptop is lost, or CI logs leak. In the dashboard: Settings → Webhooks → Rotate. Via API:

curl -X POST https://api.subscriby.net/v1/webhook-endpoints/$ID/rotate-secret \
  -H "Authorization: Bearer $SUBSCRIBY_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"

The response returns a brand-new secret field once; you can't fetch it again. Deploy the new secret to your handler before you rotate — otherwise deliveries between the rotation and your deploy will fail verification.

There is no grace window

Rotation replaces the secret in place. The old secret stops verifying the instant rotate-secret returns, and every delivery after that point carries a single v1= signature made with the new one. There is no dual-signing and no overlap period.

Deploy the new secret before you rotate, not after. Anything delivered between the rotation and your deploy fails verification and is retried on the normal backoff schedule — so a slow deploy costs you deliveries, not just failed verifications.

IP allowlist

allowed_ips is an optional list of IPv4 or IPv6 addresses and CIDR ranges (for example 198.51.100.7 or 2001:db8::/32) accepted when creating an endpoint, stored, and returned by the API and the MCP tools.

It is enforced on every delivery. Before a delivery is posted, the worker resolves the endpoint's hostname (or reads the literal address in the URL) and checks every address it gets back against the list. If any address falls outside it, the delivery is dead-lettered without being posted, with the refused address recorded in the delivery's response excerpt (Endpoint host resolved to 203.0.113.10, outside its allowed IPs.). Correct the list or the DNS record, then replay the dead deliveries from the dashboard or with POST /v1/webhook-deliveries/retry-dead.

The list restricts where Subscriby will deliver; it does not authenticate what arrives. Keep verifying the signature (below) on your side, and firewall the handler to Subscriby's egress if you need inbound filtering too. A hostname that does not resolve at all is not refused by the list — the connection failure walks the normal retry ladder.

TLS

Subscriby enforces:

  • Full certificate-chain validation (no self-signed bypasses).
  • TLS 1.2 minimum; we strongly prefer TLS 1.3.

Only https:// targets on public hosts are accepted at registration. Plain http:// URLs are refused, and so is any host that is a loopback, private, link-local or reserved address — or a public name that resolves to one — because the delivery worker would otherwise be reachable as a proxy into the platform's own network. Endpoints registered over http:// before this rule keep receiving deliveries; re-register them over https://.

We do not currently support certificate pinning. If you need it, terminate TLS on a proxy you control and connect from the proxy to your app over an internal network.

Data exposure

Webhook payloads include subscriber identifiers and plan IDs. They never include:

  • Subscriber email or phone numbers unless the endpoint owner's ability set includes project-user:view (and even then, only when consented).
  • Payment card, Stripe, or other PSP-specific credentials.
  • Transaction fee breakdowns (those are an internal audit concern).
  • Team invitation tokens or passkey credentials.

Consumer tip: assume any field you don't recognise in future versions is public-safe metadata. The docs mark every sensitive field explicitly.

How is this guide?

On this page

Subscriby is a product designed by you — for you.

No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request