PRODUCT · STATUS
Component status, real uptime figures, and every incident we have had — written the way we would want to read them.
Settlement API: 99.99% over the trailing 12 months. Figures come from external probes hitting production from outside our network — maintenance windows count against the numbers, because your payouts do not care why we were down.
Trailing 90 days: 99.99%. The number the topbar quotes, and the one our internal error budget is set against.
Trailing 90 days. The dashboard ships more often than the API and occasionally pays for it (see the April 19 incident below). The API does not share its deploy path.
Trailing 90 days, measured as events delivered within 60 seconds of the state change. Late deliveries count as downtime even when they eventually arrive.
Trailing 90 days across ACH, wire, SEPA, and RTP, measured as submission windows met. Rail availability partly depends on banking partners and network hours; we publish the blended figure rather than excusing it.
Trailing 90 days. Reconciliation runs continuously; an export delayed past its schedule counts against this figure.
We publish what the probes record. When an incident dents a number, the number stays dented until the trailing window rolls past it.
FAIL-CLOSED
The important property of this system is not that it never breaks. It is what it refuses to do while broken.
# screening provider impaired, 2 payouts held GET /v1/payouts?status=queued { "data": [ { "id": "po_8c21", "status": "queued", "hold_reason": "screening_unavailable" }, { "id": "po_8c22", "status": "queued", "hold_reason": "screening_unavailable" } ], "note": "resumes automatically; policy not bypassed" }
Every incident since launch, with timeline and root cause. In none of them did funds move outside policy or go missing — the ledger reconciled to the cent throughout.
14:02 UTC: webhook deliveries began lagging state changes. 14:09: paged; a consumer backlog in the delivery pipeline was consuming events slower than the API produced them. 14:37: backlog drained, deliveries current. No events were lost; deliveries arrived late, in order, with valid signatures. Payout processing was unaffected. What changed: backlog depth now pages at one-tenth the level that triggered this, and the delivery pool scales on queue depth instead of CPU.
17:41 UTC: a banking partner's file window was missed after their gateway rejected our submission file for a header our generator had emitted for months; the rejection surfaced after the window closed. Affected payouts fell back to the next submission window automatically, exactly as designed — later than intended, never lost, never unscreened. 19:05: root cause confirmed with the partner. What changed: submission files are pre-validated against each partner's current spec before the window opens, and a rejected file now pages immediately rather than on the next poll.
10:14 UTC: a failed deploy left the dashboard returning errors for roughly 20 minutes. 10:19: deploy rolled back automatically; 10:34: fully recovered after cache invalidation. The settlement API, rails, and webhooks were unaffected throughout — the dashboard does not sit in the money path. What changed: dashboard deploys now canary against synthetic checks before taking full traffic, and rollback no longer waits on cache expiry.
Two channels, both machine- and human-friendly. Planned maintenance is announced at least 7 days ahead on both.
Subscribe to the status.changed event and receive signed notifications when any component changes state — the same signed-webhook machinery as payout events. Setup is documented on Developers.
Write to status@latchpay.xyz to be added to the status list. Incident opens, resolutions, and maintenance announcements only. No product news, ever.
Announced 7 days ahead, scheduled outside rail submission windows, and counted against the uptime figures above if anything is actually unavailable.