- Docs
- Webhooks
- Overview
Receiving webhooks
Relay sends an HTTPS POST to your server the moment something happens, so you never have to poll.
Updated Oct 18, 2026 · 6 min read
How delivery works
When an event fires, Relay signs the payload and sends it to every endpoint subscribed to that event type. Your server has 10 seconds to answer with a 2xx status.
- Events arrive at least once, so make your handler idempotent.
- Order isn't guaranteed. Use the
created_atfield to sort. - Payloads are JSON and never larger than 256 KB.
api.relay.dev/ips.Create an endpoint
Register the URL that should receive events. You'll get back a signing secret; store it somewhere safe.
import { Relay } from "@relay/node";const relay = new Relay(process.env.RELAY_KEY);// Subscribe an endpoint to the events you care aboutconst endpoint = await relay.endpoints.create({ url: "https://api.acme-bikes.com/hooks/relay", events: ["order.paid", "order.refunded"],});console.log(endpoint.secret); // whsec_7f3a…Verify the signature
Every request carries a Relay-Signature header. Check it against the raw body before you trust the payload.
const valid = relay.webhooks.verify({ payload: req.rawBody, signature: req.headers["relay-signature"], secret: process.env.RELAY_WEBHOOK_SECRET,});if (!valid) return res.status(400).end();Rotating secrets
Roll a secret from the dashboard and both the old and new secret stay valid for 24 hours, so you can deploy without dropping events.
Retries
If your endpoint fails or times out, Relay backs off and tries again up to six times over three days.
| Attempt | After |
|---|---|
| 1 | Immediately |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 8 hours |
| 6 | 1 day |
relay events replay.Next steps
Browse the full list of event types, or test against your laptop with the local tunnel.
Was this page helpful?