Retry & Delivery
Synapse delivers webhooks reliably using automatic retries with exponential backoff and a circuit breaker to protect your server from being overwhelmed.
Delivery Flow
When an email event occurs, Synapse fans out the event to all active webhook endpoints that subscribe to that event type. Each endpoint receives its own independent delivery with its own retry cycle.
Retry Policy
Failed deliveries are retried up to 3 times with exponential backoff:
| Attempt | Delay before attempt |
|---|---|
| 1 | Immediate |
| 2 | 10 seconds |
| 3 | 30 seconds |
| 4 (final) | 120 seconds |
What counts as a failure?
| Response | Behavior |
|---|---|
| 2xx | Success. Delivery complete. Failure counter reset. |
| 4xx (client error) | Permanent failure. No retries -- your server explicitly rejected the request. |
| 5xx (server error) | Retried with backoff. |
| Timeout (>10 seconds) | Retried with backoff. |
| Connection error | Retried with backoff. |
Return 200 OK quickly from your webhook handler. Acknowledge receipt immediately, then process the event asynchronously. If your handler takes longer than 10 seconds, the delivery will be marked as timed out.
Circuit Breaker
If an endpoint accumulates 10 consecutive failures (across multiple event deliveries), Synapse automatically suspends the endpoint:
is_activeis set tofalsesuspended_atis set to the current timestamp- No further deliveries are attempted until the endpoint is re-enabled
Re-enabling a Suspended Endpoint
Update the endpoint and set is_active: true:
This resets the consecutive failure counter to 0. Use the test endpoint to verify your server is reachable before re-enabling.
Delivery Logs
Every delivery attempt is logged. You can inspect delivery history for any endpoint:
Auth: JWT (dashboard). Requires webhooks:read permission.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
status_filter | string | (all) | Filter by success or failed |
limit | integer | 20 | Max items per page (capped at 100) |
offset | integer | 0 | Pagination offset |
Response
Delivery Record Fields
| Field | Type | Description |
|---|---|---|
id | UUID | Unique delivery attempt ID |
endpoint_id | UUID | The webhook endpoint |
event_type | string | The event that triggered this delivery |
status | string | success or failed |
http_status_code | integer or null | HTTP response status (null on timeout/connection error) |
response_body | string or null | First 1,000 characters of the response body |
attempt_number | integer | 1-based attempt number (0 = test delivery) |
duration_ms | integer or null | Round-trip time in milliseconds |
error_message | string or null | Error description on failure |
created_at | string (ISO 8601) | When the attempt was made |
Best Practices
- Return 200 quickly. Acknowledge receipt, enqueue work, return. Do not perform slow processing in the handler.
- Handle duplicates. Network retries may deliver the same event more than once. Use
idfrom the payload to deduplicate. - Verify signatures. Always verify
X-Synapse-Signaturebefore processing. See Signature Verification. - Monitor the circuit breaker. If
consecutive_failuresis climbing, check your server logs. Suspension at 10 failures means you're missing events. - Use test deliveries. After deploying handler changes, send a test event before relying on real traffic.