Retries
How SolidHooks retries a failed delivery, what ends the schedule, and how each kind of response from your endpoint is treated.
When your endpoint does not return a 2xx, SolidHooks retries the same delivery automatically. The retry reuses the delivery row, so it adds attempts to the attempts log rather than creating new deliveries, and it never counts against your delivery quota.
How many attempts you get, and over how long, is set by your plan.
How it works
The first attempt happens immediately. After that, the gaps between attempts follow an exponential schedule:
| Attempt | Waits before it | Roughly after the first attempt |
|---|---|---|
| 1 | none | 0 |
| 2 | 5 seconds | 5 s |
| 3 | 5 minutes | 5 min |
| 4 | 30 minutes | 35 min |
| 5 | 2 hours | 2 h 35 min |
| 6 | 5 hours | 7 h 35 min |
| 7 | 10 hours | 17 h 35 min |
| 8 | 10 hours | 27 h 35 min |
Each gap carries up to 10% of random jitter so a burst of failures does not retry in lockstep. Two plan entitlements bound the schedule, and whichever runs out first ends it:
maxDeliveryAttempts: the total number of attempts, first attempt included.maxRetryHours: a wall-clock ceiling measured from the first attempt.
| Plan | maxDeliveryAttempts | maxRetryHours |
|---|---|---|
| Hobby | 3 | 1 |
| Launch | 8 | 36 |
| Scale | 8 | 36 |
| Enterprise | 8 | 36 |
Both limits are also clamped by the plan's retentionDays, because a retry cannot outlive the delivery record it belongs to. Check your own values with GET /v1/billing/plan; enterprise organisations can have them changed.
While a delivery is still being retried, nextAttemptAt on the delivery tells you when the next attempt is due. null means no further attempts are scheduled.
How your endpoint's response is interpreted
| Response | What happens |
|---|---|
2xx | Success. |
3xx | Failure, retried on the schedule. Redirects are never followed. |
410 Gone | Failure. Two consecutive 410 responses disable the destination and email the organisation's owners and admins. Any other response in between resets the count. |
429, 502, 504 | Parked, not failed. SolidHooks honours Retry-After (seconds or an HTTP date, capped at 1 hour), the park costs no retry attempt, and a delivery can be parked at most 5 times. |
Any other 4xx or 5xx | Failure, retried on the schedule. |
A parked delivery has status: "throttled" and throttledReason: "destination_busy". It is queued, not lost.
Parking uses no attempt, so the attempt count alone cannot bound it. maxRetryHours does: a park that would wake the delivery after the ceiling is not taken, and the response is treated as an ordinary failure instead.
Why redirects are not followed
A redirect would send the signed payload, and your destination's custom headers, to a URL you never configured. Treating 3xx as a failure keeps deliveries going only where you pointed them. Set the destination URL to the final address.
Timeouts
A request to your endpoint times out after 20 seconds by default. A timeout is a failure and follows the schedule above. To change it, set timeoutMs on the destination to a value between 1000 and 30000.
curl -s -X PATCH "$API/v1/destinations/dest_..." \
-H "authorization: Bearer $SDHK_KEY" \
-H 'content-type: application/json' \
-d '{ "data": { "timeoutMs": 10000 } }'Manual retries and replays
POST /v1/deliveries/{id}/retryretries one delivery. It is free and creates no new delivery. It returns409 CONFLICTwhile the delivery isthrottled, because it is already queued and will send on its own.POST /v1/events/{id}/replayre-runs an event through its connections and creates new deliveries, which are billable.
Next steps
- Deliveries — statuses and the attempts log
- Throughput and rate limits — why a delivery can read
throttled - Verifying deliveries — check the signature on each attempt
- Replay — re-run an event