Webhooks as a service: send signed webhooks to your customers
Your backend publishes each event once. Webhook Relay signs it with Standard Webhooks, delivers it to every endpoint your customer subscribed, retries failures, paces each endpoint and keeps 35 days of delivery history you can retry, recover and replay from.
Start for $9.99. At 10 million messages it's still a flat plan.
- Self-serve from Basic
- SOC 2 Type II
- Standard Webhooks
- Retries free
- 35-day delivery history
- Running since 2017
Four calls to your first outbound webhook
Register an event type and a customer once, add the HTTPS endpoint they give you, then publish whenever the event happens. The idempotency key means a retry after a timeout or crash never publishes twice.
import { WebhookRelay } from "@webhookrelay/sdk";
const relay = new WebhookRelay({ key: process.env.RELAY_KEY, secret: process.env.RELAY_SECRET });
// Once per customer: register the HTTPS endpoint they give you.
await relay.outbound.eventTypes.upsert("invoice.paid", { description: "An invoice was paid" });
await relay.outbound.consumers.upsert("customer_42", { name: "Acme" });
const endpoint = await relay.outbound.endpoints.create("customer_42", {
url: "https://acme.example/webhooks",
eventTypes: ["invoice.paid"],
autoDisable: true,
});
// endpoint.secret is the signing secret your customer verifies deliveries with.
// Every time the event happens. Retrying with the same key never publishes twice.
const message = await relay.outbound.messages.publish(
{ consumer: "customer_42", eventType: "invoice.paid", payload: { invoice_id: "inv_123", amount: 4900 } },
{ idempotencyKey: "invoice-paid:inv_123" },
);// Error handling shortened; see the setup guide for the full program.
api, err := webhookrelay.New(os.Getenv("RELAY_KEY"), os.Getenv("RELAY_SECRET"))
if err != nil {
log.Fatal(err)
}
// Once per customer: register the HTTPS endpoint they give you.
_, err = api.UpsertOutboundEventType(&webhookrelay.OutboundEventTypeOptions{
Name: "invoice.paid",
Description: "An invoice was paid",
})
_, err = api.UpsertOutboundConsumer(&webhookrelay.OutboundConsumerOptions{ID: "customer_42", Name: "Acme"})
endpoint, err := api.CreateOutboundEndpoint(&webhookrelay.OutboundEndpointOptions{
Consumer: "customer_42",
URL: "https://acme.example/webhooks",
EventTypes: []string{"invoice.paid"},
AutoDisable: true,
})
// endpoint.Secret is the signing secret your customer verifies deliveries with.
// Every time the event happens. Retrying with the same key never publishes twice.
message, err := api.PublishOutboundMessage(&webhookrelay.OutboundMessagePublishOptions{
Consumer: "customer_42",
EventType: "invoice.paid",
Payload: map[string]interface{}{"invoice_id": "inv_123", "amount": 4900},
IdempotencyKey: "invoice-paid:inv_123",
})# 1. Event type
curl --user "$RELAY_KEY:$RELAY_SECRET" -H 'Content-Type: application/json' \
-X POST https://my.webhookrelay.com/v1/outbound/event-types \
-d '{ "name": "invoice.paid", "description": "An invoice was paid" }'
# 2. Consumer (one of your customers, keyed by your own customer ID)
curl --user "$RELAY_KEY:$RELAY_SECRET" -H 'Content-Type: application/json' \
-X PUT https://my.webhookrelay.com/v1/outbound/consumers/customer_42 \
-d '{ "name": "Acme" }'
# 3. Endpoint (the response includes the whsec_ signing secret)
curl --user "$RELAY_KEY:$RELAY_SECRET" -H 'Content-Type: application/json' \
-X POST https://my.webhookrelay.com/v1/outbound/consumers/customer_42/endpoints \
-d '{ "url": "https://acme.example/webhooks", "event_types": ["invoice.paid"], "auto_disable": true }'
# 4. Publish (202 Accepted with a durable receipt)
curl --user "$RELAY_KEY:$RELAY_SECRET" -H 'Content-Type: application/json' \
-H 'Idempotency-Key: invoice-paid:inv_123' \
-X POST https://my.webhookrelay.com/v1/outbound/messages \
-d '{ "consumer": "customer_42", "event_type": "invoice.paid", "event_id": "evt_9001",
"payload": { "invoice_id": "inv_123", "amount": 4900 } }' The endpoint response includes its whsec_ signing secret (or pass secret to import the one your customer already verifies with): give it to your customer with the receiving guide. Full walkthrough, token scopes and response codes: set up the Outbound Gateway. Install with npm install @webhookrelay/sdk or go get github.com/webhookrelay/webhookrelay-go.
What you get without building it
No queue, retry worker, signing code or delivery log of your own. Your customers verify standard signatures and receive each message at least once.
Standard Webhooks signing
webhook-id, webhook-timestamp and webhook-signature headers (HMAC-SHA256) with a separate whsec_ secret per endpoint. Rotating a secret signs with both for 24 hours.
Retries on a schedule
Up to 8 attempts within 48 hours: 5 seconds, 5 minutes, 30 minutes, then hours apart. Retry-After is honoured on 429 and 503. Retries are never billed.
A lane per endpoint
Each endpoint has its own rate limit (50 deliveries per second by default, up to 1,000), concurrency and retry schedule, so one slow customer never delays another.
Health and auto-disable
Endpoints move from active to failing after repeated errors, and one view lists failing endpoints across all your customers. Optionally disable them after 100 consecutive failures over at least 12 hours, or pause one by hand.
35-day history and recovery
Every attempt with its request headers and response, filterable by status, event type or message. Retry one delivery, recover everything that failed during an outage, or replay messages skipped while an endpoint was paused.
Idempotent publishing
Send an Idempotency-Key with each publish. A repeat returns the original receipt, so a retry after a timeout or crash never publishes twice.
Functions per endpoint
Attach a JavaScript Function to one customer's endpoint to reshape the JSON body or drop the message. It runs once per message, and the result is reused for every retry.
Every surface, including MCP
REST API, the TypeScript and Go SDKs, the dashboard and MCP tools, so the dashboard agent or your own coding agent can publish, inspect attempts and replay.
Details: Outbound Gateway overview · monitor, retry and recover · limits
Cheap to start, best to scale
Webhook Relay prices outbound webhooks on how many customers you serve, not how many events you send. Outbound is included in the plan with no per-message fees. Retries and fan-out are free, a payload up to 256 KiB is one message, and outbound messages don't count against your inbound webhook quota.
| Plan | Price (monthly / annual) | Customers | Endpoints per customer | Event types |
|---|---|---|---|---|
| Basic | $9.99 / $8.99 | 100 | 10 | 300 |
| Business | $79.99 / $71.99 | 500 | 25 | 500 |
| Pro | $249.99 / $224.99 | 1,000 | 100 | 1,000 |
Every plan includes 35-day delivery history, up to 8 retry attempts within 48 hours and every SDK, API and MCP tool. Annual prices are per month, billed yearly. Compare everything else on the pricing page.
Cost as you grow
Per-message pricing punishes success: when a customer goes from 1M to 10M events a month, a Svix Basic bill goes from about $115 to about $1,015. On Webhook Relay the bill doesn't move, because the plan is set by how many customers you serve (up to 100, 500 or 1,000), not by volume. Pick a monthly volume:
| Monthly messages | Webhook Relay | Svix Basic | Svix Pro | Hookdeck Outpost Growth |
|---|---|---|---|---|
| 100k | $9.99 | ~$25 | $490 | ~$500 |
| 1M | $9.99 | ~$115 | ~$585 | ~$509 |
| 10M | $9.99–$249.99 | ~$1,015 | ~$1,485 | ~$599 |
| 50M | $9.99–$249.99 | ~$5,015 | ~$5,485 | ~$999 |
List prices checked 2026-10-10, at 30-day retention or the closest tier. Svix: $20 Basic (30 days) or $490 Pro (90 days), each including 50k messages, then $0.0001 per message (svix.com/pricing). Hookdeck Outpost: Growth $499 plus $10 per million (30 days); Starter is $0 plus $10 per million with 7-day retention (hookdeck.com/outpost/pricing). Webhook Relay keeps 35 days on every plan; at 10M+ messages the price range reflects how many customers you serve, not volume.
Cheap to start
$9.99 a month with 35-day delivery history. Getting 30 days elsewhere costs $20 (Svix Basic) or $499 (Outpost Growth); their free and starter tiers keep 7 days.
Flat as you grow
Volume doesn't change the plan. Retries are never billed, fan-out to several endpoints is free, and a 256 KiB payload counts as one message (Svix counts every 64 KiB chunk).
Built to scale
A durable Postgres outbox accepts every publish, each endpoint is paced in its own lane, and bulk recover and replay handle a customer's outage without republishing.
Watch it work on a free Webhook Bin
You don't need a customer to try the receiving side. Point an endpoint at a free Webhook Bin, which needs no signup, and see exactly what your customers will receive: the signed request, every retry and the endpoint going from active to failing.
Bins are public and expire after about 48 hours, so use test payloads only. Publishing needs an account on the Basic plan or above.
- 1
Create a bin
Open a free Webhook Bin and copy its public HTTPS URL. Open Webhook Bin
- 2
Register it as an endpoint
Add the bin URL as an endpoint for a test consumer and publish a message. The request lands with webhook-id, webhook-timestamp and webhook-signature headers.
- 3
Inject failures
Set the bin to answer 500 for a percentage of requests and watch the retries arrive with the same webhook-id and a new signature each time.
- 4
Verify the signature
Paste the captured headers, raw body and endpoint secret into the free verifier. Standard Webhooks verifier
- 5
Generate test signatures
Build the three Standard Webhooks headers for any payload and secret, with SDK snippets. Signature generator
Let your coding agent add webhooks to your product
Using Claude Code, Cursor or Codex? Paste this prompt. Every Outbound Gateway operation is also an MCP tool (publish_outbound_message, list_outbound_deliveries, recover_outbound_deliveries and the rest), and the agent skills teach your agent the workflow.
Machine-readable reference: webhookrelay.com/outbound-webhooks.md
Moving from another provider?
Each guide maps concepts and API calls, explains what changes for your customers' receivers and walks through a dual-publish cutover with a rollback at every step. Weighing options first? Read the webhooks as a service comparison.
Migrating? Keep your signing secrets
Create each endpoint with the secret it uses today (32 to 100 base64 characters, whsec_ prefix optional) and your customers keep verifying with the key they already have. There is no secret handoff. Coming from Svix, receivers that verify with a Svix library need no change at all, because those libraries accept the unbranded webhook-* headers; only receivers that read svix-* headers by name need a rename. From Convoy, Hook0, Outpost's default mode or homegrown signing, the signature scheme changes, but a secret in that format can still be imported so customers reuse their key.
From Svix
Import your whsec_ secrets. Receivers on Svix libraries keep working unchanged.
From Hookdeck Outpost
Tenants become consumers, destinations become endpoints, topics become event types.
From Convoy
A hosted path off Convoy, with a dual-publish window for your customers.
From Hook0
Map applications, subscriptions and event types; move receivers to Standard Webhooks.
From a homegrown queue
Replace the status table, cron retry job and signing code with one publish call.
What isn't there yet
If you need one of these on day one, another provider may suit you better today.
Customer portal
NextAn embeddable portal where your customers manage their own endpoints. Today you register endpoints through the API, SDKs or dashboard.
Queue destinations
NextDelivery to SQS, SNS, Pub/Sub or S3. Today every endpoint is an HTTPS URL.
FIFO ordering
Not planned yetDeliveries are at least once and not strictly ordered. Receivers deduplicate on webhook-id.
HIPAA / PCI
Not planned yetWebhook Relay is SOC 2 Type II, but outbound webhooks are not offered for HIPAA or PCI workloads.
Receive and send from one account
The account that receives your Stripe and GitHub webhooks and forwards them to localhost now delivers yours to your customers. One dashboard, one set of access tokens and audit logs, one bill. Running since 2017, SOC 2 Type II.
Receive webhooks
Buckets give every provider a stable URL, with transforms, fan-out and durable retries.
Tunnels
Expose a local or private service on a stable HTTPS hostname without opening ports.
Webhook Bin
A free, no-signup bin to capture and inspect requests, including your own outbound webhooks.
Send webhooks
The Outbound Gateway delivers your events to your customers, signed, retried and logged.
Webhooks as a service FAQ
What is webhooks as a service?
Webhooks as a service is a hosted system that sends webhooks from your product to your customers on your behalf. Your backend publishes an event once, and the service signs it, delivers it to every endpoint the customer subscribed, retries failures and keeps a delivery log. Webhook Relay's Outbound Gateway does this with Standard Webhooks signatures, up to 8 retry attempts within 48 hours, per-endpoint rate limits and 35 days of history, so you don't build a queue, retry worker or log viewer yourself.
How much does it cost at scale?
Outbound webhooks are included in the Basic ($9.99 a month), Business ($79.99) and Pro ($249.99) plans with no per-message fees. The plan is set by how many customers you serve (100, 500 or 1,000), not by how many messages you send, so the bill is the same at 1 million or 10 million messages a month. Retries and fan-out are free and a payload up to 256 KiB counts as one message. At list prices checked on 2026-10-10, 10 million messages a month costs about $1,015 on Svix Basic and about $599 on Hookdeck Outpost Growth.
Does it count against my webhook quota?
No. Outbound messages do not count against the monthly webhook quota that applies to the webhooks you receive with buckets. Outbound limits are the number of customers, endpoints per customer and event types on your plan.
Is it Standard Webhooks compatible?
Yes. Every delivery carries webhook-id, webhook-timestamp and webhook-signature headers, signed with HMAC-SHA256 using a whsec_ secret per endpoint, exactly as the Standard Webhooks specification describes. Your customers can verify deliveries with any Standard Webhooks library or the receiving guide in the docs, and test them with the free Standard Webhooks signature verifier.
Can I migrate from Svix?
Yes, and your customers keep their signing secrets. Svix secrets are whsec_ plus base64, so you pass each one as the secret when you create the endpoint on Webhook Relay, and deliveries are signed with the same key. Deliveries use webhook-id, webhook-timestamp and webhook-signature headers instead of svix-*, and Svix's own verification libraries accept those unbranded headers, so receivers that use a Svix library need no change at all. Receivers that read svix-* headers by name only rename them. There are also guides for Hookdeck Outpost, Convoy, Hook0 and homegrown queues.
Can I keep my existing signing secrets when I migrate?
Yes. When you create an endpoint you can pass the secret it uses today: 32 to 100 standard base64 characters, with or without the whsec_ prefix. If you leave it out, a new whsec_ secret is generated. Importing the secret means your customers keep verifying with their current key and you never have to hand out new secrets. Asymmetric keys are not accepted. If the previous provider used a different signature scheme, such as Convoy, Hook0 or Hookdeck Outpost in its default mode, receivers still switch to Standard Webhooks verification, but they can reuse the same key.
Which plans include outbound webhooks?
The Outbound Gateway is generally available on the Basic, Business and Pro plans and on Enterprise, with no per-message fees. It is not part of the Free plan. Sign up, choose a plan, then open the Outbound webhooks page in the dashboard or call the API with an access token; no support ticket is needed.
Can an AI agent set it up?
Yes. Every Outbound Gateway operation is available as an MCP tool, such as publish_outbound_message, list_outbound_deliveries and recover_outbound_deliveries, under the same permissions and audit log as the REST API. Paste the prompt on this page into Claude Code, Cursor or Codex and the agent reads the machine-readable reference at webhookrelay.com/outbound-webhooks.md, registers your event types, creates consumers and endpoints and publishes with idempotency keys, asking you before any production change.
Is there a customer portal?
Not yet. An embeddable portal where your customers manage their own endpoints is the next phase. Today you create endpoints for your customers through the REST API, the TypeScript or Go SDK, MCP or the dashboard, and give each customer their endpoint's signing secret.
What are the limits?
Basic includes 100 customers, 10 endpoints per customer and 300 event types; Business 500, 25 and 500; Pro 1,000, 100 and 1,000. An account can have at most 1,000 customers. Payloads are JSON up to 256 KiB. Each endpoint delivers 50 messages per second by default, configurable up to 1,000, with a 15-second attempt timeout that can be raised to 60. Deliveries are retried up to 8 times within 48 hours, and history is kept for 35 days. It is self-serve on Basic and above: open the Outbound webhooks page in the dashboard after signing up. It is not available on the Free plan.
