Delivery and retries
How Cavuno retries failed deliveries, what endpoint statuses mean, and how to handle duplicate events.
A
JWebhook delivery is asynchronous and at least once. An event can arrive more than once, and events can arrive out of order. Your receiver needs to cope with both.
Respond quickly
Any 2xx response counts as success. Reply as soon as you have verified the signature and stored the event, then do the real work afterwards.
Cavuno gives each attempt 10 seconds in total before treating it as a timeout. Slow processing inside the request is the most common cause of avoidable retries.
How retries work
A delivery gets up to 10 attempts in total, including the first one. The first retry follows about 30 seconds later, and the gap roughly doubles each time up to a maximum of 6 hours. Cavuno varies each gap slightly so that many endpoints failing at once do not retry in lockstep.
Retries also stop 3 days after the first attempt, whichever limit is reached first. If your receiver recovers inside that window, the event still arrives.
If you return 429 or 503 with a Retry-After header, Cavuno waits at least that long before trying again.
Which responses retry
| Response | What happens |
|---|---|
2xx | Delivered. No further attempts. |
408, 409, 425, 429, 5xx | Retried on the schedule above. |
| Timeout or network error | Retried on the schedule above. |
Other 4xx | Treated as permanent. That delivery stops immediately. |
410 | The endpoint is disabled straight away. |
3xx | Counted as a failure. Redirects are never followed. |
Point the endpoint at its final URL. A redirect is treated as a broken destination, not something to follow.
Endpoint status
An endpoint is in one of three states, shown in the endpoint list.
| Status | What it means |
|---|---|
| Enabled | Normal. Events are being delivered. |
| Failing | Three live attempts in a row failed. Delivery continues and you get one alert. |
| Disabled | Ten live attempts in a row failed, or the endpoint returned 410. No new events are delivered. |
A successful delivery clears the failure streak and moves a Failing endpoint back to Enabled on its own.
A Disabled endpoint never re-enables itself. Fix the receiver, then either enable it yourself or send a successful test, which also recovers it. A failed test never makes an endpoint's status worse.
Handle duplicates and out-of-order events
Two rules cover both problems.
- Store each
idyou have processed and ignore an event whoseidyou have already seen. Retries and replays reuse the original event ID. - Keep the last
revisionyou applied for each record. Ignore any event whoserevisionis lower than or equal to it. Revisions only ever increase for a given record.
Without the second rule, a retried older update can arrive after a newer one and overwrite good data with stale data.
Delivery log and replay
The Deliveries panel lists real deliveries, newest first, and you can filter by endpoint and status. Opening one shows the attempt history with the response status, latency, and a short diagnostic for each attempt. Response bodies and event payloads are never shown.
Deliveries end in one of these states.
| Status | Meaning |
|---|---|
| Pending | Waiting for its first attempt. |
| Retrying | An attempt failed and another is scheduled. |
| Delivered | A 2xx response was received. |
| Failed | A permanent response ended the delivery. |
| Exhausted | The attempt limit or the 3 day window ran out. |
Use Replay to send a delivery again. Replay reuses the original event ID and the exact original body, so a receiver that deduplicates correctly will recognise it. Only the timestamp and signature are new.
Deliveries can be replayed for 30 days after the event. After that the stored body is removed and replay is refused. If you need data that is older than the window, read the current state of the record from the API instead.
Limits
| Limit | Value |
|---|---|
| Endpoints per board | 50 |
| Endpoint URL | HTTPS only, up to 2048 characters |
| Credentials in the URL | Not allowed |
| Private, loopback, and internal addresses | Not allowed |
| Attempt timeout | 10 seconds |
| Delivery history and replay | 30 days |
Cavuno re-checks the destination address at delivery time, not just when you save the endpoint. A public hostname that later resolves to a private address is blocked when the attempt is made.