Delivery
Once an endpoint is registered, the platform delivers each subscribed event to it as an HTTP POST. This page covers what counts as success, how retries work and when they stop, what to assume about ordering, and how to recover events your endpoint missed.
What your endpoint must return
Respond with any 2xx status code within 5 seconds. That budget covers the whole attempt, including reading your response. A 2xx is the platform's signal that you've taken responsibility for the event; it stops retrying.
- A status of
400or above, a connection error, or a timeout counts as a failed attempt and is retried. Every4xxis retried,410 Goneincluded, so returning an error does not make the platform give up sooner. - Answer at the URL you registered. Don't redirect a delivery to another address.
- Acknowledge first, work later. Record the event, return
2xx, then do slow processing out of band. Heavy work before responding can trip the timeout and trigger a needless retry.
Retries and backoff
Delivery is at least once. A failed attempt is retried on a fixed schedule: the first attempt plus up to 10 retries, the first retry 30 seconds later, with the gap doubling each time. The last attempt comes about 8.5 hours after the first. After that, the platform stops trying that event for that endpoint, and it is not sent again. An outage longer than about 8.5 hours therefore loses events for that endpoint, and only an API re-read gets them back; see below.
Because an attempt can be retried, the same event can reach you more than once. Make your handler idempotent: dedupe on the X-Revenexx-Event-Id header, which is stable across every attempt for the same event. The body is the event's data and does not repeat the id, so the header is the identifier to key on.
An endpoint is not switched off automatically when it keeps failing: every event gets its full retry schedule. You can switch an endpoint off and on yourself in Cockpit, but while it is off, its events and any pending retries are dropped, and switching it back on does not resend them.
Ordering
Order is best-effort, not guaranteed. Retries and backoff mean a retried event can arrive after a later one. Don't assume order.acknowledged always follows order.placed on the wire.
When sequence matters, reconstruct it from the entity rather than from arrival order: use the entity's own state and timestamps in data, or re-read it through the API. The X-Revenexx-Timestamp header is when that attempt was sent, not when the event happened. Handlers that are commutative, where the end state is the same regardless of order, are the easiest to get right.
Delivery attempts, and recovering missed events
In Cockpit, an endpoint's page lists every delivery attempt: when it ran, the topic, whether it succeeded, the HTTP status your endpoint returned, and which attempt it was. Use it to see whether events are reaching you and what your endpoint answered. It does not show the response body.
There is no manual redelivery. An event whose attempts ran out is not sent again, from Cockpit or through the API. To recover after an outage or a handler bug, re-read the affected entities through the API for the window you missed. Incremental sync walks through closing such a gap.
Where to go next
- Security — the signature scheme, and what to do until the signing secret is available.
- Webhooks overview — register an endpoint and choose topics.
- Consuming events — the App-handler alternative to webhooks.