Get missed events
Webhooks are best-effort: a long enough outage on your side, a misconfigured TLS cert, or a 5xx blip during a retry window can leave a delivery permanently failed. Plan for it — combine the Dashboard's delivery log with a periodic reconcile against the REST API and your handlers will never drift from the source of truth.
What "missed" means
A delivery is failed while Stridge is still retrying it (Retries) and permanently failed once the retry budget is exhausted. Once permanently failed, Stridge stops attempting that delivery; the event itself is not lost — it stays queryable through the REST API and replayable from the Dashboard.
Common reasons a delivery exhausts retries:
- Your server returns 5xx for the entire retry window (deploy, dependency outage).
- The endpoint URL is wrong or no longer resolving (DNS, TLS cert expired).
- A signature mismatch causes your handler to reject every retry (see Verify signature).
- Your handler timed out under load; the retry policy gave up before recovery.
Inspect failed deliveries
In the Dashboard under Webhooks → Deliveries, filter by status failed to see every delivery that exhausted retries — including the response code your server returned, the request body, and the signature headers. This is the first place to look when an event you expected didn't land.
Replay a delivery
From the same Deliveries view, opening a failed row exposes a Replay action that re-sends the exact same envelope (same id, same payload) to your subscriber. Because your handler is already keyed by webhook-id, replays are safe — a successful redelivery is a no-op for any envelope you already processed.
Replay is the fast path while you are debugging a broken handler — fix the bug, deploy, then replay the failed deliveries to catch up. For a backlog larger than a handful of events, reconcile via REST instead.
Reconcile against the REST API
For systems where missing an event is unacceptable — settlements, deposits — run a periodic job that lists the underlying resource from the REST API and reconciles it against what your database has marked as processed. The webhook stream becomes the fast path; the reconcile is the safety net.
A workable shape:
Persist the last created_at (or last id) you successfully processed for each resource — deposits, settlements, transactions.
Once an interval (every 5–15 minutes for hot resources; hourly for cold), list the resource from the API filtered by created_at >= cursor and walk every page.
For each row you have not processed, run the same handler logic the webhook would have triggered — keyed by the resource id so replays are idempotent.
Only after the page is fully processed; never before, or a crash mid-page will drop events.
The REST endpoints to reconcile against are the same ones you would use for a one-off lookup — see the API Reference for the per-resource list endpoints (GET /v1/deposits, GET /v1/settlements, and so on).
Build for replays
Whether an event arrives once, three times via retry, or twice via reconcile-on-top-of-webhook, your handler should produce the same end state. The contract is non-negotiable:
- Key everything by event id, not arrival time —
webhook-idfor live events, the resource id (deposit.id,settlement.id) for reconciles. - Make state transitions idempotent —
deposit.confirmedarriving twice should not double-credit a balance. - Keep a processed-events table — even a simple
(event_id, processed_at)row per webhook is enough to turn duplicate deliveries into no-ops.