Reliability & Troubleshooting
Retry behavior, auto-disable rules, and debugging failed deliveries
Flipswitch webhooks are designed for reliable, at-least-once delivery with automatic retries and failure handling.
Delivery Guarantees
Webhooks provide at-least-once delivery. In rare cases (e.g., network timeouts where the server received the request but the response was lost), the same event may be delivered more than once. Deduplicate on your end using the X-Flipswitch-Delivery-Id header or the eventId field in the request body.
Response Handling
Your endpoint's HTTP response status determines what happens next:
| Response | Result |
|---|---|
2xx | Success — delivery is complete |
408, 409, 425, 429, 5xx | Retryable — delivery is retried with backoff |
Other non-2xx (e.g., 400, 401, 404) | Permanent failure — no retries |
Your endpoint must respond within 5 seconds. Timeouts are treated as retryable failures.
Retry Behavior
Failed deliveries are retried with exponential backoff:
- Base delay: 5 seconds
- Multiplier: 2x per attempt
- Jitter: random value up to 25% of the delay
- Maximum delay: 15 minutes
- Default max attempts: 10
Approximate retry schedule:
| Attempt | Approximate Delay |
|---|---|
| 1 | Immediate |
| 2 | ~5s |
| 3 | ~10s |
| 4 | ~20s |
| 5 | ~40s |
| 6 | ~80s |
| 7 | ~160s |
| 8 | ~320s |
| 9 | ~640s |
| 10 | ~900s (capped at 15 min) |
After all attempts are exhausted, the delivery is moved to dead letter status and no further retries are made.
Auto-Disable Rules
Flipswitch automatically disables webhooks that are consistently failing, to avoid wasting resources on broken endpoints.
Rule A: Repeated Client Errors
If a webhook has 5 or more consecutive terminal failures and the most recent failure returned 401, 403, 404, 410, or 422, the webhook is automatically disabled.
These status codes typically indicate a misconfigured URL, missing authentication, or a deleted endpoint — problems that won't resolve on their own.
Rule B: Sustained Failure Pattern
If all of the following are true, the webhook is automatically disabled:
- 15+ consecutive terminal failures
- 20+ terminal failures in the last 30 minutes
- 95%+ failure rate in the last 30 minutes
- Zero successes in the last 30 minutes
When a webhook is auto-disabled, pending deliveries for that destination are skipped. After fixing the issue, re-enable the webhook in the dashboard. Flipswitch clears the failure counters when you re-enable.
Delivery Log
Every webhook has a delivery log showing recent delivery attempts. Navigate to Project > Webhooks > select a webhook to view its delivery history.
Each entry shows:
- Event type — which event triggered the delivery
- Status — current delivery state
- Timestamp — when the delivery was attempted
- Response status — HTTP status code returned by your endpoint
Delivery Statuses
| Status | Description |
|---|---|
succeeded | Your endpoint returned a 2xx response |
pending | Delivery is queued and waiting to be sent |
in_progress | Delivery is currently being attempted |
retry_scheduled | Delivery failed and is scheduled for retry |
failed_permanent | Delivery failed with a non-retryable status code |
dead_letter | All retry attempts exhausted |
skipped | Delivery was skipped (e.g., destination was disabled) |
Troubleshooting
My webhook was auto-disabled. What do I do?
Check the delivery log for recent failure details. Common causes: your endpoint URL changed, authentication credentials expired, or the server is returning errors. Fix the underlying issue, then re-enable the webhook in the dashboard.
Retries never succeed and eventually go to dead letter.
Verify your endpoint returns a 2xx status within 5 seconds. Check that your server isn't rejecting requests due to missing headers, IP allowlists, or firewall rules. Use the Send Ping button to test connectivity.
I'm receiving duplicate events.
This is expected behavior with at-least-once delivery. Deduplicate using the X-Flipswitch-Delivery-Id header (unique per delivery attempt) or the eventId field (unique per event, shared across retries).
Signature verification fails.
- Verify you're using the raw request body, not re-serialized JSON.
- Check that you're using the full secret string (including
whsec_) as UTF-8 bytes for HMAC. - If you recently rotated the secret, ensure your code checks all
sha256=values in theX-Flipswitch-Signatureheader. See Handling Secret Rotation. - Confirm the timestamp from the
X-Flipswitch-Timestampheader matches what you're using to build the signed payload.