Monitoring & Debugging
Zyphr provides full observability into your webhook deliveries — delivery logs with request/response capture, endpoint health tracking, and test events for integration development.
Delivery Logs
List Deliveries
Retrieve delivery history for a webhook endpoint:
curl "https://api.zyphr.dev/v1/webhooks/YOUR_WEBHOOK_ID/deliveries?limit=20&offset=0" \
-H "Authorization: Bearer YOUR_API_KEY"
Filter by status:
curl "https://api.zyphr.dev/v1/webhooks/YOUR_WEBHOOK_ID/deliveries?status=failed" \
-H "Authorization: Bearer YOUR_API_KEY"
Valid status filters: pending, success, failed, exhausted.
Delivery Detail
Get full details for a specific delivery, including the payload and response body:
curl "https://api.zyphr.dev/v1/webhooks/YOUR_WEBHOOK_ID/deliveries/DELIVERY_ID" \
-H "Authorization: Bearer YOUR_API_KEY"
The detail response includes:
| Field | Description |
|---|---|
id | Delivery record ID |
msg_id | Stable message ID (for deduplication) |
event_id | Originating event ID |
event_type | Event type (e.g., email.delivered) |
payload | Full webhook payload that was sent |
status | Current delivery status |
attempts | Number of delivery attempts made |
max_attempts | Maximum attempts allowed |
next_attempt_at | When the next retry is scheduled (if applicable) |
last_response_status | HTTP status code from your endpoint |
last_response_body | Response body from your endpoint (truncated to 1,000 chars) |
last_error | Error message if the delivery failed |
first_attempted_at | Timestamp of the first delivery attempt |
last_attempted_at | Timestamp of the most recent attempt |
completed_at | Timestamp when delivery succeeded or was exhausted |
Endpoint Health
Each webhook tracks health metrics that help you identify problematic endpoints:
| Field | Description |
|---|---|
status | Current webhook status: active, paused, or disabled |
consecutive_failures | Number of consecutive failed deliveries |
last_failure_at | Timestamp of the most recent failure |
disabled_at | Timestamp when the webhook was auto-disabled |
disabled_reason | Reason for auto-disable (e.g., "10 consecutive failures") |
Webhook Statuses
| Status | Description |
|---|---|
active | Endpoint is receiving deliveries normally |
paused | Endpoint is temporarily paused — deliveries are held |
disabled | Endpoint was auto-disabled due to consecutive failures |
Pausing a webhook is useful during maintenance. While paused, new events still create delivery records but deliveries are not attempted until the webhook is set back to active.
Test Events
Send a test event to verify your endpoint is configured correctly:
curl -X POST https://api.zyphr.dev/v1/webhooks/YOUR_WEBHOOK_ID/test \
-H "Authorization: Bearer YOUR_API_KEY"
The default test event uses the webhook.test event type. Customize the event type and payload:
curl -X POST https://api.zyphr.dev/v1/webhooks/YOUR_WEBHOOK_ID/test \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_type": "email.delivered",
"payload": {
"message_id": "test-msg-123",
"recipient_email": "test@example.com"
}
}'
Test events create a real delivery record with max_attempts: 1 (no retries) so you can inspect the full delivery lifecycle.
Common Issues
| Symptom | Likely Cause | Solution |
|---|---|---|
last_error: "Request timed out after 30000ms" | Endpoint is too slow | Respond within 30 seconds — process events asynchronously |
last_response_status: 401 or 403 | Authentication failure | Ensure your endpoint doesn't require auth for webhook POST requests |
last_response_status: 404 | Wrong URL | Verify the webhook URL is correct |
last_response_status: 500 | Server error | Check your endpoint's error logs |
last_error contains DNS error | DNS resolution failed | Verify the hostname is correct and DNS is configured |
last_error contains SSL/TLS error | Certificate issue | Ensure your SSL certificate is valid and not expired |
Webhook status is disabled | 10 consecutive failures | Fix the underlying issue, then re-enable with PUT /v1/webhooks/:id |
| Signature verification fails | Wrong secret or algorithm | Confirm you're using the correct secret and signature format |