Webhooks
Zyphr sends webhook events to notify your application in real time when things happen — emails are delivered, push notifications fail, users sign up, and more. You can manage webhooks through the Dashboard or the API.
Overview
When you create a webhook endpoint, Zyphr sends HTTP POST requests to your URL whenever subscribed events occur. Each delivery is signed with HMAC-SHA256 so you can verify authenticity.
| Feature | Details |
|---|---|
| Event Types | 25 events across email, push, and auth |
| Delivery | HTTP POST with 30-second timeout |
| Retries | Configurable retry policy with exponential backoff |
| Security | HMAC-SHA256 signatures (Standard Webhooks format) |
| Monitoring | Full delivery logs with request/response capture |
| Circuit Breaker | Auto-disables after 10 consecutive failures |
Quick Start
1. Create a Webhook
Via Dashboard
- Navigate to Webhooks in the sidebar
- Click Create Webhook
- Enter your endpoint URL (e.g.,
https://yourapp.com/webhooks/zyphr) - Select the events you want to receive
- Optionally add a description and custom headers
- Click Create
- Copy the webhook secret — it is only shown once
Via API
curl -X POST https://api.zyphr.dev/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/zyphr",
"events": ["email.delivered", "email.bounced", "push.delivered"],
"description": "Production webhook endpoint"
}'
const webhook = await zyphr.webhooks.create({
url: 'https://yourapp.com/webhooks/zyphr',
events: ['email.delivered', 'email.bounced', 'push.delivered'],
description: 'Production webhook endpoint',
});
// Store the secret securely — only returned once
console.log(webhook.secret);
2. Handle Events
import express from 'express';
const app = express();
app.post('/webhooks/zyphr', express.raw({ type: 'application/json' }), (req, res) => {
// 1. Verify the signature (see Security & Signatures)
// 2. Respond immediately
res.status(200).json({ received: true });
// 3. Process the event asynchronously
const event = JSON.parse(req.body.toString());
console.log(`Received ${event.type}: ${event.id}`);
});
3. Verify Signatures
Every delivery is signed. Always verify before processing. See Security & Signatures for examples in TypeScript, Python, Go, and PHP.
4. Send a Test Event
Via Dashboard
On the Webhooks page, click on a webhook and use the Send Test button to send a test event.
Via API
curl -X POST https://api.zyphr.dev/v1/webhooks/YOUR_WEBHOOK_ID/test \
-H "Authorization: Bearer YOUR_API_KEY"
Managing Webhooks
Via Dashboard
From the Webhooks page you can:
- View all webhooks with their status (active/disabled) and event subscriptions
- Edit a webhook's URL, events, or custom headers
- Enable/Disable a webhook without deleting it
- View delivery history — see every delivery attempt with status codes, response bodies, and timing
- Retry failed deliveries — click to retry a specific failed delivery
- Rotate the signing secret — generate a new secret if compromised
- Delete a webhook
Via API
# List webhooks
curl https://api.zyphr.dev/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY"
# Get webhook details
curl https://api.zyphr.dev/v1/webhooks/WEBHOOK_ID \
-H "Authorization: Bearer YOUR_API_KEY"
# Update a webhook
curl -X PATCH https://api.zyphr.dev/v1/webhooks/WEBHOOK_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/v2",
"events": ["email.delivered", "email.bounced", "sms.delivered"]
}'
# Rotate the signing secret
curl -X POST https://api.zyphr.dev/v1/webhooks/WEBHOOK_ID/rotate-secret \
-H "Authorization: Bearer YOUR_API_KEY"
# View delivery history
curl "https://api.zyphr.dev/v1/webhooks/WEBHOOK_ID/deliveries?page=1&per_page=25" \
-H "Authorization: Bearer YOUR_API_KEY"
# Retry a failed delivery
curl -X POST https://api.zyphr.dev/v1/webhooks/WEBHOOK_ID/deliveries/DELIVERY_ID/retry \
-H "Authorization: Bearer YOUR_API_KEY"
# Delete a webhook
curl -X DELETE https://api.zyphr.dev/v1/webhooks/WEBHOOK_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Event Envelope
All events use the same envelope format:
{
"id": "evt_550e8400-e29b-41d4-a716-446655440000",
"type": "email.delivered",
"api_version": "2026-02-01",
"created_at": "2026-02-07T12:00:00.000Z",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440000",
"recipient_email": "user@example.com",
"timestamp": "2026-02-07T12:00:00.000Z"
}
}
Plan Limits
| Plan | Max Webhooks |
|---|---|
| Free | 2 |
| Starter | 10 |
| Pro | 50 |
| Scale | Unlimited |
| Enterprise | Unlimited |
Next Steps
- Event Types & Filtering — All 25 event types and payload schemas
- Delivery & Retry Logic — Retry policies and circuit breaker
- Security & Signatures — Signature verification examples
- Monitoring & Debugging — Delivery logs and endpoint health
- Best Practices — Idempotency, response handling, plan limits
Zyphr is building a Webhooks-as-a-Service product that lets you power webhook delivery for your own platform's customers. See Webhooks-as-a-Service for the roadmap.