Loading...
Stop Building Webhook Infrastructure
March 6, 2026
5 min read
Get posts like this in your inbox
Bi-weekly engineering deep dives on auth, notifications, and developer infrastructure. No spam.
Sign Up for UpdatesPublished by Zyphr
March 6, 2026
5 min read
Loading...
Bi-weekly engineering deep dives on auth, notifications, and developer infrastructure. No spam.
Sign Up for UpdatesPublished by Zyphr
Every SaaS platform with an API eventually needs webhooks. And every team that builds them goes through the same painful journey: store a URL, POST a JSON payload, maybe retry once on failure. Ship it. Move on.
Six months later, a customer says they missed a critical event. Your retry queue is backed up because one broken endpoint is consuming all the capacity. You have no delivery logs, no circuit breakers, and no way to answer "did this webhook actually get delivered?"
We built this infrastructure for Zyphr's own notification platform. Now we're making it available to every developer who needs webhook delivery for their product.
WaaS lets you power webhook delivery for your platform's customers using Zyphr's battle-tested infrastructure. Instead of building retry logic, circuit breakers, signature verification, delivery logging, and endpoint management from scratch, you define your custom event types, publish events via a single API call, and Zyphr handles everything else.
| You build | Zyphr handles |
|---|---|
| Your event types (order.created, payment.completed) | HMAC-SHA256 signing (Standard Webhooks spec) |
| Publish events from your backend | Automatic retries with exponential backoff |
| Your customers configure their endpoints | Circuit breaker protection |
| Full delivery logs with request/response capture | |
| Rate limiting per endpoint | |
| Embeddable portal for your customers |
Each WaaS application represents a product or service that publishes events. A single Zyphr workspace can have multiple applications.
import { Zyphr } from '@zyphr-dev/node-sdk';
const zyphr = new Zyphr({ apiKey: 'zy_live_xxx' });
const app = await zyphr.waas.applications.createWaaSApplication({
name: 'Acme Commerce',
slug: 'acme-commerce',
});
Define the events your platform publishes. Include example payloads so your customers know what to expect.
await zyphr.waas.eventTypes.createWaaSEventType(app.id, {
eventType: 'order.created',
name: 'Order Created',
category: 'orders',
description: 'Fired when a new order is placed',
examplePayload: {
order_id: 'ord_abc123',
total: 99.99,
currency: 'USD',
items: [{ sku: 'WIDGET-01', quantity: 2, price: 49.99 }],
},
});
When your customers want to receive webhooks, create an endpoint scoped to their tenant ID. Zyphr generates a signing secret they'll use to verify payloads.
const endpoint = await zyphr.waas.endpoints.createWaaSEndpoint(app.id, {
tenantId: 'cust_abc123',
url: 'https://customer.com/webhooks',
events: ['order.created', 'order.shipped'],
});
// endpoint.secret = 'whsec_...' — give this to your customer
One API call triggers delivery to all subscribed endpoints for that tenant. Delivery is asynchronous -- Zyphr queues it immediately and returns a summary.
const result = await zyphr.waas.events.publishWaaSEvent(app.id, {
eventType: 'order.created',
tenantId: 'cust_abc123',
data: {
order_id: 'ord_456',
total: 99.99,
currency: 'USD',
},
idempotencyKey: 'order-ord_456-created',
});
// result.endpointsMatched = 2
// result.deliveriesCreated = 2
That's it. Four steps from zero to production webhook delivery.
When you call publishWaaSEvent, Zyphr's delivery pipeline takes over:
Your customers receive a signed payload that follows the Standard Webhooks spec:
POST https://customer.com/webhooks
Headers:
webhook-id: msg_abc123
webhook-timestamp: 1709380800
webhook-signature: v1,K3xz...
Body:
{
"id": "evt_xxx",
"type": "order.created",
"api_version": "2026-02-01",
"created_at": "2026-03-06T12:00:00Z",
"data": { "order_id": "ord_456", "total": 99.99 }
}
Most webhook providers force your customers into a separate dashboard. With WaaS, you can embed a full webhook management UI directly into your product using the @zyphr-dev/webhook-portal React component.
import { WebhookPortal } from '@zyphr-dev/webhook-portal';
function CustomerSettings() {
return (
<WebhookPortal
token={portalToken}
theme={{ mode: 'dark', accent: '#6366f1' }}
onEndpointCreated={(ep) => console.log('Created:', ep)}
/>
);
}
The portal gives your customers:
Generate a portal token scoped to a specific tenant:
const portal = await zyphr.waas.portal.generateWaaSPortalToken(app.id, {
tenantId: 'cust_abc123',
allowedEventTypes: ['order.*', 'payment.*'],
expiresIn: 3600,
theme: { mode: 'dark', accent: '#6366f1' },
});
You can. But here's what "just add webhooks" actually looks like once you need production reliability:
That's months of engineering. Or one API integration.
WaaS is live today on all Zyphr plans. The free tier includes 1 application, 5 event types, 10 endpoints, and 1,000 events per month -- enough to build and validate your webhook integration before scaling.
Coming soon: