Webhooks that arrive, or tell you why not
Relay takes delivery, retries, signature verification and the dead-letter queue off your critical path. One endpoint in, one verified payload out.
$npm i @relay/sdkDelivering for
- Northwind
- Contoso
- Initech
- Globex
- Lumon
- Vandelay
4.1 billion events delivered last month, at 99.99% first-attempt success.
The whole integration
Two files. There is no third one where the complexity was hiding.
- Signature verification is one call, and it throws rather than returning false
- Retries, backoff and the dead-letter queue are server-side — nothing to schedule
- Typed payloads generated from your own event schema
1import { verify } from '@relay/sdk'2 3export async function POST(req: Request) {4 // Throws on a bad signature or a replayed timestamp, so there is5 // no boolean to forget to check.6 const event = await verify(req, process.env.RELAY_SECRET!)7 8 switch (event.type) {9 case 'invoice.paid':10 await fulfil(event.data.invoiceId)11 break12 case 'invoice.failed':13 await notify(event.data.customerId)14 break15 }16 17 // 200 means "stored". Relay retries anything else for 72 hours.18 return new Response(null, { status: 200 })19}What you stop maintaining
Each of these is a thing teams build in-house, ship, and then own forever.
Delivery
The retry loop you were going to write on Friday
Twelve attempts over 72 hours with exponential backoff, resumed across your deploys rather than lost with the process that scheduled them. Anything that never lands goes to a dead-letter queue you can replay from a dashboard or a single API call.
- Retries survive your restarts
- Replay one event or ten thousand
- Per-endpoint circuit breaking
Verification
Signatures, timestamps and replay windows, once
Constant-time comparison, a configurable tolerance window, and rejection of anything reused. The failure mode of hand-rolled verification is not an outage — it is silently accepting forged events for a year, which is why this is the section to read twice.
- Constant-time compare
- Replay rejection by default
Visibility
Every attempt, with the response body attached
The request, the response, the status code and the latency, for every attempt of every event, kept for 30 days. When a customer says the webhook never arrived, this is the difference between an answer and an afternoon.
- Full request and response bodies
- 30-day retention
- Filter by endpoint, type or status
Works with what you already run
Direct integrations, not a webhook you have to adapt at both ends.
- AvailableS
Stripe
Payments
Verified passthrough of every Stripe event type.
- AvailableG
GitHub
Source
Repository, org and app events, with installation scoping.
- AvailableS
Shopify
Commerce
Order, fulfilment and inventory topics.
- AvailableS
Slack
Alerting
Post failures into a channel with the payload attached.
- BetaA
AWS EventBridge
Infrastructure
Forward into a bus with the original signature preserved.
- PlannedK
Kafka
Infrastructure
Produce to a topic with at-least-once semantics.
What it costs at your volume
Move the slider. There is no plan to pick, and the number below is the number on the invoice.
- 0–1M at $0.08 per 1K
- $80.00
- 1M–10M at $0.05 per 1K
- $50.00
The awkward questions
Infrastructure buyers ask about exits before they ask about features. Fair enough.
- What happens if Relay goes down?
- Your senders keep retrying into us and we keep the backlog; nothing is dropped for the length of your retry window. If we are down longer than that, the failover endpoint documented in the SDK forwards raw to your origin unverified, and you fall back to your own handling.
- Can I self-host it?
- Yes, on the enterprise plan, as a container with a Postgres and a Redis. It is the same image we run. The dashboard and the replay API come with it; the only thing that does not is our on-call.
- How do I get my data out?
- A single export endpoint returns every event, attempt and response body as newline-delimited JSON, and it is available on every plan including the free one. No ticket, no notice period, no export fee.
- Is the SDK required?
- No. It is 40 lines around a documented HTTP contract and an HMAC. The verification algorithm is written out in the docs so you can implement it in a language we do not ship for — several customers have.
- What counts as an event?
- One inbound payload, regardless of how many times we retry it or how many endpoints you fan it out to. Retries are our problem, so charging you for them would be charging you for our failures.
- Do you have an SLA?
- 99.99% on ingest, credited automatically against the next invoice rather than on request. The status page below is the same one our own alerting reads, and its history is not editable after the fact.
Developer Tool
The terminal hero, typing the install
Near-black buttons, square corners and a terminal-green accent. Install command above the fold, real code before any prose, docs and changelog behind it.