You send the event. We deliver the webhooks.
Relay queues your events, delivers them to your customers' endpoints, retries the ones that fail and signs each request, so you can stop writing delivery code.
npm install relay
import { Client } from "relay";
const client = new Client(process.env.API_KEY);
// Send once. Delivery, retries and signing happen for you.
await client.events.send({
type: "invoice.paid",
customer: "cus_123",
data: { invoiceId: "inv_456" },
});
import os
from relay import Client
client = Client(os.environ["API_KEY"])
# Send once. Delivery, retries and signing happen for you.
client.events.send(
type="invoice.paid",
customer="cus_123",
data={"invoice_id": "inv_456"},
)
# Send once. Delivery, retries and signing happen for you.
curl -X POST https://api.example.com/v1/events \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "invoice.paid", "customer": "cus_123",
"data": {"invoice_id": "inv_456"} }'
The webhook code you'd rather not maintain.
Queues, backoff, signing and a log of every attempt. Built once, so your team can spend its time on the product.
Delivery log
See every delivery, not only the failures.
When a customer says they never got an event, look it up. Each attempt keeps its request, the response code and the body that came back.
- Filter by customer, endpoint or event type
- Open any attempt to read the full payload
- Share a link to one delivery with your support team
Deliveries
Retries
Retries you don't have to write.
Endpoints go down. Set a backoff schedule per endpoint, and a delivery that fails waits and tries again. Replay any attempt by hand when your customer is back up.
- Your own schedule, per endpoint
- Pause an endpoint that keeps failing
- Replay one delivery or a whole time range
order.shipped
sample scheduleAttempt 1 · now
503 Service Unavailable
Attempt 2 · after 1 minute
503 Service Unavailable
Attempt 3 · after 10 minutes
Timed out
Attempt 4 · after 1 hour
200 OK · delivered
Signatures
Requests your customers can check.
Each delivery carries a timestamp and a signature made with that endpoint's secret. Your customers verify it in one call before they trust the payload.
- A separate secret for each endpoint
- Rotate a secret without missing events
- A verify helper in each SDK
POST /webhooks
Verified- content-type:
- application/json
- webhook-id:
- msg_2f9a7c
- webhook-timestamp:
- 1767225600
- webhook-signature:
- v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN
const event = client.webhooks.verify(
body, headers, secret
);
Test it on your laptop before your customers see it.
Test mode
Send with a test key and nothing reaches a real customer. Read each payload in the log, then switch the key when you're ready.
Local tunnel
Forward events to the server on your machine while you build the receiver. When it works, point the same endpoint at production.
$ npx relay listen --forward localhost:3000
Listening for test events...
→ invoice.paid 200 /webhooks
→ user.created 200 /webhooks
Three lines between you and your first webhook.
-
1
Install the SDK
Add the library to the app that creates events.
$ npm install relay -
2
Add your customer's endpoint
Register the URL each customer wants events sent to.
client.endpoints.create({ url }) -
3
Send an event
Call send when something happens. The rest is in the log.
client.events.send({ type, data })
Start small. Move up when you ship.
Every plan has the same API. Ask us which one fits what you're sending.
Hobby
For side projects and trying the API.
Add your price
- Test mode and local tunnel
- Delivery log
- Signed requests
Team
For production appsFor products sending webhooks to paying customers.
Add your price
- Everything in Hobby
- Retry schedules per endpoint
- Replay by hand or by time range
- Team members and roles
Scale
For high-volume senders with their own requirements.
Add your price
- Everything in Team
- A portal your customers can use to manage endpoints
- A setup call with an engineer
Do my customers need to install anything?
No. They give you a URL and receive plain HTTPS requests. Checking the signature is optional, and the SDKs include a helper for it.
What happens when an endpoint is down?
The delivery is tried again on the schedule you set for that endpoint, and every attempt shows in the log. You can also replay it by hand once the endpoint is back.
Can I test without sending to real customers?
Yes. Use a test key, or forward events to your own machine with the local tunnel while you build.
Which languages can I use?
This page shows Node.js, Python and plain HTTP. Anything that can make an HTTPS request can send events. Ask us about the language you use.
We already send webhooks ourselves. Can we move over?
Tell us how you send them today and we'll talk through moving your existing endpoints across.
Get a test key and send your first event.
Tell us what you're building and we'll set you up with keys.