Consuming events

The two ways to react to platform events — an App handler that runs inside Revenue Cloud, or a Webhook delivered to your own endpoint.

You react to the event stream in one of two ways. Both subscribe by topic to the same event stream; the difference is where your code runs, and what the delivery looks like when it gets there.

Runs in Revenue CloudRuns on your infrastructure
MechanismApp event handlerWebhook destination
You provideA function in your appAn HTTPS URL
Best forAn app's own lifecycle, such as seeding defaults on installReacting in your own systems
DeliveryNot settled (as of 2026-09); write for duplicates, reordering and lossAt least once, retried for about 8.5 hours
VerificationHandled by the platformYou verify the signature, once Cockpit shows the signing secret; until then, re-read before acting

Option 1 — handle events inside an App

If the reaction is part of a commerce app you're building, subscribe inside the app. You declare the topics in the manifest and the platform invokes your handler when one of them is published. Nothing leaves the platform, so there's no endpoint to host and no signature to check. Today only app.installed and app.uninstalled are verified for App handlers (as of 2026-09).

Declare the subscription in manifest.json:

manifest.json
{
  "events": {
    "listens": ["app.installed", "app.uninstalled"]
  }
}

app.installed and app.uninstalled are the events shipped apps subscribe to today. Handle each one in your app's code; Events you receive has a working handler. See the App manifest reference for the events block and the access register, and Apps for the runtime model. Use this for the app's own lifecycle, such as seeding defaults when it is installed. For a business event such as an order placed, use a webhook or an Integration Studio workflow. The install event does not reliably fire on a Marketplace install, so back it with an idempotent route you call once.

Option 2 — receive events at your own endpoint

If the reaction lives in your own infrastructure — an ERP, a data warehouse, a notification service — register a Webhook. You give the platform an HTTPS URL and a list of topics in Cockpit, and it POSTs each matching event to you as JSON.

The body of a delivery is the event's data only; the event id and topic arrive as headers. Deliveries are signed, but Cockpit does not show the signing secret yet (as of 2026-09), so for now treat a delivery as a notification and re-read the entity through the API before acting on it. The scheme and what to do meanwhile are in Webhook security.

Receiver
# the body is the event's data object; id and topic arrive as headers
def handle(request):
    event_id = request.headers["X-Revenexx-Event-Id"]
    topic = request.headers["X-Revenexx-Topic"]
    if already_processed(event_id):     # at-least-once: dedupe on the event id
        return 200
    record(event_id, topic, request.body)  # acknowledge fast, work later
    return 200                          # 2xx tells the platform to stop retrying

Make handlers idempotent

Webhook deliveries are at least once, so the same event can arrive twice — after a retry, or a network hiccup that dropped your acknowledgement. Delivery to an App handler is not settled enough to promise anything (as of 2026-09), so assume duplicates there too, along with reordering and loss.

Key off the event id, which is stable across every retry of the same event (for a webhook it arrives in the X-Revenexx-Event-Id header; how an App handler receives it is not documented yet, as of 2026-09). Record the ids you've handled and skip one you've seen before. Acknowledge fast: return success as soon as you've safely recorded the event, and do slow work afterward, so a delivery isn't retried just because your processing was slow.

When an event isn't the right tool

Events are fire-and-forget reactions to something that already happened. They're the wrong choice when:

  • You need an answer now — call the API directly instead.
  • The reaction must run a durable, multi-step process against an external system — use an Integration Studio workflow, which adds persistence and retries around the whole flow.

Where to go next

Was this page helpful?