Event types

How topics are named, how payloads are versioned, and where to find the exact event catalog for your tenant.

Every event carries a topic that names what happened. This page explains how topics are structured, what's in a payload, and how to find the precise list of events your tenant emits.

How topics are named

A topic is a dot-separated, lowercase name, and it names the action in the past tense — created, settled, activated. (A version suffix can follow it; see below.)

vendor.app.resource.action — namespaced. This is what real producers publish, core services and custom Apps alike. Every segment is a slug, so two publishers can never clash on a name, and it is the form to use for anything you publish yourself.

namespaced
revenexx.inventories.stock_level.low
acme.billing.invoice.settled

The short resource.action part, such as invoice.settled, is the name an App declares in its manifest. It is not the topic. Whether the platform accepts a bare two-segment topic anywhere is not something we can confirm (as of 2026-09), so don't subscribe with one: use the exact topic string the catalog lists, rather than assuming a form.

When you subscribe — from an App manifest or a Webhook destination — you name the topics you want. You receive those and nothing else.

Which order event to subscribe to

To act on a new order, such as handing it to an ERP or sending the confirmation, subscribe to order.placed. The Orders app emits it when the order is placed: numbered, with its positions and computed totals. order.placed is the event's name; the topic you subscribe to puts the vendor and the app in front of it, revenexx.orders.order.placed. Hand an order to the ERP builds the hand-off.

Two other order events sound close, and neither tells you an order is ready to act on:

Event nameWhen it firesUse it for
order.placedThe order is placed, with positions and totalsActing on a new order
order.createdThe order row is written, before any position exists, and for a quote request tooNothing that needs the order's contents
order_event.createdEvery entry in an order's trail, whatever happenedOne feed of everything, in place of the named topics

Beside order.placed, the Orders app emits a named topic for each step of an order's life: requested, acknowledged, cancelled, item cancelled, shipment created, completed, payment status changed, held, unheld, and four for returns. Subscribe to those or to order_event.created, never both, or you process every change twice.

An order that has to wait for sign-off emits order.requested instead of order.placed, with an approval_reason of permission or value_threshold. If your hand-off must also see orders while they wait for approval, subscribe to order.requested as well.

The trail entry for a placed order carries number, grand_total, currency, item_count and cart_id. For the exact topic string to subscribe to and the event's data, read the catalog: GET /v1/events/catalog lists every event your tenant's apps declare, with a sample and a data_schema for each.

Webhook and workflow-trigger delivery is at least once and not in order (App handlers: not settled, as of 2026-09), so key your handler on the event id. See Events.

What's in a payload

The data object holds the payload, and its fields depend on the topic. An order.placed event carries order fields; a revenexx.inventories.stock_level.low event carries the stock row it is about. Treat each topic's data shape as a contract: the publisher adds fields over time, but won't remove or repurpose existing ones without changing the topic.

Payload
{
  "tenant_id": "acme-eu",
  "topic": "revenexx.orders.order.placed",
  "id": "evt_01jc8m4yq2…",
  "data": {
    "number": "A-10482",
    "grand_total": 185.16,
    "currency": "EUR",
    "item_count": 3,
    "cart_id": "…"
  },
  "metadata": {},
  "time": "2026-05-31T10:00:00Z"
}
The exact data fields for each topic are defined per tenant. Browse the live catalog and payload schemas for your tenant in the API Explorer rather than hard-coding a field list from an example.

How payloads change over time

Payloads evolve additively. A topic's data only ever gains fields; existing fields keep their meaning. So a handler written against order.placed today keeps working when new fields appear — read the fields you need and ignore the rest.

A change that would break that rule — removing a field, changing a type — ships as a new topic, not a silent change to the old one. The convention is a version suffix:

versioned topic
order.placed         # original
order.placed.v2      # breaking change — a separate topic you opt into

The original topic keeps its meaning, so migrating is something you opt into rather than a flag day.

Finding the catalog for your tenant

The set of topics is determined by your tenant: the core commerce capabilities emit a standard set, and any custom App you install adds its own. An app declares the events it publishes in its manifest (events.emits), which makes those names part of the app's public contract.

To see the topics available right now and inspect their payloads, call GET /v1/events/catalog, or open it in the API Explorer for your tenant.

To plan a subscription before you have a tenant, the Event catalog lists the business events the revenexx commerce apps publish.

Where to go next

Was this page helpful?