Event catalog
This is the complete list of every event registered in the platform’s central
event registry (contracts/src/events). One line per event is the whole
point: an event that is not in the registry cannot be published or subscribed
to, and the built-must-be-wired rule fails any registered event with no live
consumer.
Most of these are internal bus events — they travel the in-process dispatcher between modules and never leave the process. Exactly one is deliverable to a merchant endpoint over the network. This page tells you which, and gives a self-contained payload summary for each so you never have to call back into the producing module to use one.
Only commerce.order.placed.v1 is deliverable to merchants via webhooks
today. To receive it, register an endpoint with your fdk_ credential (scope
manage:own_webhooks) — see Webhooks. Every other event
below is internal to the platform.
The envelope
Every event travels in a common envelope. tenant_ref is REQUIRED — an event
without a tenant is unconstructible, not merely discouraged.
| Field | Type | Meaning |
|---|---|---|
id | string | The event id. Unique per event. |
name | string | The event name, e.g. commerce.order.placed.v1. |
tenant_ref | string | The owning tenant. Always present. |
occurred_at | string | ISO-8601 instant, from an injected clock (never Date.now() in domain code). |
payload | object | The event-specific body, summarized per event below. Self-contained. |
The webhook delivery envelope is a separate, network-facing shape (id,
type, tenant_ref, created_at, data) — see Webhooks.
Do not confuse the two: the internal bus envelope above is what modules
publish/consume in-process; the webhook envelope is what arrives at your HTTP
endpoint for the one deliverable event.
Versioning rule
The version suffix (.v1) is part of the event name. Schema evolution is
additive within a version: a new optional field may be added, and an older
publisher that omits it means consumers see null/absent — never a parse
failure. A breaking change is a new .vN file (e.g. .v2); a shipped
payload is never mutated in place. Parsers reject a present-but-malformed field
(a half-stated block is malformed, not partially accepted).
Deliverable versus internal
| Category | Events | Where they go |
|---|---|---|
| Merchant-deliverable | commerce.order.placed.v1 | Delivered to your webhook endpoint. The allowlist is pinned in edges/outbound-webhooks (MERCHANT_DELIVERABLE_EVENTS) to its own list, so a new internal event never silently widens the merchant surface. |
| Reserved test event | platform.test.v1 | Not in the registry and not subscribable. Used only by POST /v1/merchant/webhooks/:id/test; the type IS the test flag (payload also carries test: true). |
| Internal bus | everything else below | In-process dispatcher only. Never crosses a network. |
The API rejects any webhook subscription naming an event outside the
deliverable allowlist with a 400, so you can never silently subscribe to
something that will not fire.
Commerce
| Event | Deliverable | Payload summary |
|---|---|---|
commerce.order.placed.v1 | Yes (webhook) | An order was placed (payment captured). order_id, order_number, customer_ref, status, the money breakdown (subtotal_cents, discount_cents, shipping_cents, tax_cents, total_cents, currency), coupon_code (nullable), and the full priced items[] (product_id, variant_id, sku, product_name, quantity, unit_price_cents, line_total_cents). Additive-within-v1 fields: referral_code, customer_contact_email, is_first_order (all nullable), and an optional subscription block (renewalAmountCents, renewalInterval, manageSubscriptionsUrl) when the order starts a subscription. |
commerce.order.refunded.v1 | No (internal) | A refund settled for real (never on an idempotency replay). tenant_ref, order_id, order_ref, refund_id, charge_id, amount_cents, currency, reason (nullable), refunded_total_cents, order_status. This is the money-movement event affiliates/commerce consume for reversal. |
commerce.order.cancelled.v1 | No (internal) | An order was cancelled before fulfillment (audit signal, not the money one). tenant_ref, order_id, order_number, reason (nullable), refunded, refund_id (nullable), refunded_cents, reservations_released, order_status. |
commerce.order.returned.v1 | No (internal) | An approved return was received and settled (RMA lifecycle/audit signal). tenant_ref, order_id, return_id, status, refund_id (nullable), refunded_cents, order_status, and per-line lines[] (order_item_id, sku, quantity, line_refund_cents, restocked). |
commerce.order.status_changed.v1 | No (internal) | A bare operator state-machine transition (no checkout flows run). Reconciliation signal. tenant_ref, order_id, order_number, from, to, reason (nullable), actor_type. |
commerce.product.searched.v1 | No (internal) | Emitted on every non-empty public catalog-search query — fire-and-forget analytics signal. tenant_ref, query, result_count, limit, offset. |
Payments
| Event | Deliverable | Payload summary |
|---|---|---|
payment.charged.v1 | No (internal) | A payment intent was successfully captured. charge_id, intent_id, tenant_ref, customer_ref (nullable), amount_cents, currency, provider, provider_charge_ref (opaque — never assume a Stripe shape), charged_at. |
Accounting
| Event | Deliverable | Payload summary |
|---|---|---|
accounting.transaction.posted.v1 | No (internal) | A balanced transaction posted. transaction_id, tenant_ref, type, external_ref (nullable), entries[] (account_id, amount_cents, memo), posted_at. |
accounting.transaction.reversed.v1 | No (internal) | A posted transaction was reversed. original_transaction_id, reversal_transaction_id, tenant_ref, reason (nullable), entries[], reversed_at. |
Affiliates
| Event | Deliverable | Payload summary |
|---|---|---|
affiliate.commission.posted.v1 | No (internal) | A commission was created (order-attribution, upline, or post-consultation). commission_id, tenant_ref, affiliate_id, order_ref, amount_cents (the payable amount), commission_rate_bps, commission_level, source, posted_at. |
affiliate.commission.reversed.v1 | No (internal) | A commission was reversed because its order was refunded. commission_id, tenant_ref, affiliate_id, order_ref, amount_cents, reason, reversed_at. |
Cash (store credit)
| Event | Deliverable | Payload summary |
|---|---|---|
cash.granted.v1 | No (internal) | Store credit was granted. grant_id, account_id, tenant_ref, user_ref, amount_cents, source, granted_at. |
cash.spent.v1 | No (internal) | Store credit was spent. entry_id, account_id, tenant_ref, user_ref, amount_cents, reason, spent_at. |
Fulfillment
| Event | Deliverable | Payload summary |
|---|---|---|
fulfillment.cogs.captured.v1 | No (internal) | Emitted once per shipped order line, carrying the landed unit cost so a biller can turn it into COGS. order_ref, sku, canonical_item_id (nullable), qty, unit_cost_cents, mode (dedicated | allocated | dropship), source_ref (durable per-line ship reference; the idempotency key for fact ingestion). |
Inventory
| Event | Deliverable | Payload summary |
|---|---|---|
inventory.unit.shipped.v1 | No (internal) | A reservation shipped (commit). reservation_id, canonical_item_id, sku_root, internal_lot, order_ref, qty. |
Comms
| Event | Deliverable | Payload summary |
|---|---|---|
comms.email.sent.v1 | No (internal) | A transactional email was sent. Ids only, never the recipient (PII discipline): send_id, template_id, dedup_key, provider, sent_at. |
comms.email.suppressed.v1 | No (internal) | A send was suppressed. send_id, template_id, dedup_key, suppressed_at. |
Marketing
| Event | Deliverable | Payload summary |
|---|---|---|
marketing.message.engaged.v1 | No (internal) | A provider engagement landed for a send. engagement_event_id, provider, event_type (delivered | opened | clicked | bounced | complained), provider_event_type, campaign_id/enrollment_id/step_order/person_id/template_id (all nullable when unattributed), recipient_email, occurred_at. |
marketing.campaign.enrolled.v1 | No (internal) | A person entered a campaign. campaign_id, enrollment_id, person_id, recipient_email, entered_via. |
marketing.message.sent.v1 | No (internal) | A campaign step actually sent through comms. campaign_id, enrollment_id, step_order, template_ref, comms_send_id (nullable), person_id (nullable), recipient_email. |
marketing.campaign.converted.v1 | No (internal) | An order attributed (last-touch) to a campaign. conversion_id, order_ref, campaign_id, enrollment_id (nullable), person_id (nullable), recipient_email, model (last_touch), touch_type (click | open | send), order_total_cents. |
Persons
| Event | Deliverable | Payload summary |
|---|---|---|
person.created.v1 | No (internal) | A person came into existence in the CDP (operator create, shopper first login, or lead capture — never the backfill sweep). person_id, email (normalized identity axis), display_email (as typed), name (nullable), source (the create path). |
Subscriptions
| Event | Deliverable | Payload summary |
|---|---|---|
subscription.cancelled.v1 | No (internal) | A subscription reached canceled. subscription_id, person_id, plan_ref, reason (requested | dunning_exhausted — distinguishes a deliberate cancel from an involuntary one). |
Stores
| Event | Deliverable | Payload summary |
|---|---|---|
store.provisioned.v1 | No (internal) | A store was provisioned. store_ref, display_name. |
Beacon
| Event | Deliverable | Payload summary |
|---|---|---|
beacon.event.dispatched.v1 | No (internal) | Terminal dispatch outcome for an egress beacon delivery. tenant_ref, event_id, event_type, destination_key, status (delivered | skipped | dead_lettered), occurred_at. |
Webhooks (inbound)
| Event | Deliverable | Payload summary |
|---|---|---|
webhook.received.v1 | No (internal) | The inbound gateway accepted a third-party delivery (verified, deduped, stored). provider, provider_event_id, tenant_ref, webhook_event_id, event_type, raw_payload (the body rides along so a consumer needs no callback hop). |
Count
There are 26 registered events. Exactly one
(commerce.order.placed.v1) is merchant-deliverable via webhooks; the reserved
platform.test.v1 type is used only for test fires and is not in the registry;
the other 25 are internal-only bus events.
Related
- Webhooks — the delivery envelope, signature verification, retries, and the test endpoint for the one deliverable event.
- Tenant-facing API — registering webhook subscriptions.