Delivery & retries
Curviate delivers every event at least once with automatic retries and transparent endpoint health tracking.
At-least-once delivery
Curviate guarantees that every event is delivered at least once. Under normal conditions each event produces a single POST to your endpoint; in rare cases — network blips, retries that succeed after a previous attempt that appeared to time out — you may receive the same event more than once.
Every delivery payload includes an id field (format: wdl_<ulid>) that is unique
per delivery attempt. Use the combination of event + data.account_id +
data.occurred_at as a natural idempotency key on your side to detect and safely
discard duplicates.
Retry schedule
When your endpoint returns a non-2xx response or the connection times out,
Curviate schedules a retry with exponential backoff. Up to 5 attempts are made
in total:
| Attempt | Delay after previous failure | Total elapsed from first attempt |
|---|---|---|
| 1 | Immediate | 0 s |
| 2 | 30 seconds | ~30 s |
| 3 | 5 minutes | ~5 m 30 s |
| 4 | 30 minutes | ~36 m |
| 5 | 2 hours | ~2 h 36 m |
Each attempt has a 10-second HTTP timeout. If your server does not return a
2xx within 10 seconds, the attempt is recorded as failed and the next retry is
scheduled.
Acknowledge the delivery immediately with a 200 after signature
verification — then process the event asynchronously. Handler logic that runs
synchronously inside the webhook request risks hitting the 10-second timeout and
triggering an unnecessary retry.
Endpoint health
Curviate tracks the health of each registered webhook and surfaces it in the dashboard:
| Status | Meaning |
|---|---|
ok | The most recent delivery attempt succeeded. |
degraded | All 5 retry attempts for the last delivery failed. No further retries are scheduled until the webhook is re-enabled from the dashboard. |
When a webhook becomes degraded:
- Fix the issue on your endpoint (check firewall rules, TLS certificate, response codes).
- Re-enable the webhook from Settings → Webhooks in the dashboard.
- Events that occurred while the webhook was degraded are not replayed automatically (replay is planned post-MVP).
Delivery history
The dashboard shows a 7-day delivery success rate per webhook, computed from individual attempt records. Each retry is stored as a separate row — you can see exactly how many attempts each event required and whether they succeeded or failed.
Delivery records are retained for a rolling window and are visible in the dashboard.
Idempotency recap
Because delivery is at-least-once, your handler may receive the same logical
event more than once across retries. Deduplicate on the combination of
event, data.account_id, and
data.occurred_at in your own datastore. The id
field (wdl_…) uniquely identifies a delivery attempt,
not a logical event — two attempts for the same event will have different
id values.