Delivery guarantees
- At-least-once: the same event can arrive more than once — after a retry, after
a network blip that hides a successful
2xxfrom RadiumOne, or (rarely) more than once for other reasons. Dedupe on the top-levelidbefore you act on an event a second time. See Build your handler. - Unordered: deliveries for different events, and even for the same transaction, aren’t guaranteed to arrive in the order they occurred. See Ordering below for how to recover the right sequence when it matters.
Retry schedule
If your endpoint doesn’t return a2xx (timeout, non-2xx status, connection error),
RadiumOne retries on this backoff schedule by default. The schedule is a
platform-configurable default, not a contractual guarantee — build your
reconciliation job (see below) to not depend on an exact attempt count or timing.
Eight attempts total, spanning ≈29.6 hours from the first attempt to the last, by
default — not the ~72 hours you may see quoted elsewhere; the schedule above is the
authoritative source. After the final attempt fails, that delivery is exhausted and
isn’t retried further.
A
2xx you return after a slow but eventually-successful attempt still counts
as delivered — it’s specifically the timeout/non-2xx cases above that trigger the
next scheduled retry.Timeouts
Respond within RadiumOne’s delivery timeout. If your handler needs to do slow work (database writes, calling other services), enqueue it and respond2xx immediately —
see Build your handler. A handler that’s
merely slow, not broken, looks identical to a failing one from RadiumOne’s side and
consumes the same retry budget.
Ordering
Deliveries for the same transaction aren’t guaranteed to arrive in the order the underlying state changes happened — a retry of an earlier event can arrive after a later one. Don’t assume “the last webhook I received” is the current state.- Use each event’s
created_atas the ordering token if you need to reconcile the sequence of events for one transaction. - If your logic depends on the current state rather than the event history (for
example, deciding whether to fulfil an order), call
GET /v1/transactions/{id}/status(API reference) to re-fetch the authoritative current state instead of trusting whichever event arrived most recently.
Endpoint suspension
RadiumOne stops sending to an endpoint that’s provably broken, not merely slow or temporarily down:- What trips it: sustained failures whose cause can’t fix itself — an
unresolvable hostname, a bad TLS certificate, an SSRF-blocked address, or a
410 Goneresponse. This must recur across multiple separate deliveries (at least 5 by default) over a sustained window (24 hours by default) before your endpoint is suspended. - What never counts: timeouts,
5xxresponses, and ordinary4xxresponses. These are treated as transient — a bad deploy afternoon doesn’t get you suspended. - What suspension means: a suspended endpoint receives nothing. Events aren’t queued for it and aren’t replayed once it’s re-activated — they’re dropped for that endpoint entirely while it’s suspended.
- Recovery is manual, not automatic. There’s no health probe and no auto-resume. Contact support to re-activate a suspended endpoint once you’ve fixed the underlying issue. Re-activating an endpoint that’s still broken simply suspends it again once the same failure pattern recurs.
Reconciliation job
Webhooks are the primary signal, not the only one you should rely on. Because delivery can be delayed, retried, or (if your endpoint was suspended) missed entirely, run a periodic reconciliation job as a backstop:- For transaction
ids you already stored (from create responses or prior webhooks) that you haven’t heard a terminal outcome for, pollGET /v1/transactions/{id}/status. RadiumOne has no list-by-order_referenceendpoint, so this only works againstids you’ve already recorded. For settlement batches, use Retrieve a settlement batch. - Compare their current state against your own records.
- Treat a mismatch — a transaction you expected to be
CAPTUREDthat your records still show as pending, or a settlement batch your records never saw — as a signal to investigate, not just to log.
Test your integration
See Test your integration for simulated retry, duplicate-delivery, and out-of-order scenarios.Go-live notes
- Make your handler idempotent on event
idbefore you go live — a retried or duplicate delivery must never double-process an order. - Set up a reconciliation job (see above) rather than treating webhooks as infallible.
- Review the full go-live checklist.
Next steps
Webhooks overview
Endpoint setup and the handler steps these guarantees assume.
Webhook event types
Every event and its payload shape.