ReferenceEvents

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.

FieldTypeMeaning
idstringThe event id. Unique per event.
namestringThe event name, e.g. commerce.order.placed.v1.
tenant_refstringThe owning tenant. Always present.
occurred_atstringISO-8601 instant, from an injected clock (never Date.now() in domain code).
payloadobjectThe 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

CategoryEventsWhere they go
Merchant-deliverablecommerce.order.placed.v1Delivered 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 eventplatform.test.v1Not 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 buseverything else belowIn-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

EventDeliverablePayload summary
commerce.order.placed.v1Yes (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.v1No (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.v1No (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.v1No (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.v1No (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.v1No (internal)Emitted on every non-empty public catalog-search query — fire-and-forget analytics signal. tenant_ref, query, result_count, limit, offset.

Payments

EventDeliverablePayload summary
payment.charged.v1No (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

EventDeliverablePayload summary
accounting.transaction.posted.v1No (internal)A balanced transaction posted. transaction_id, tenant_ref, type, external_ref (nullable), entries[] (account_id, amount_cents, memo), posted_at.
accounting.transaction.reversed.v1No (internal)A posted transaction was reversed. original_transaction_id, reversal_transaction_id, tenant_ref, reason (nullable), entries[], reversed_at.

Affiliates

EventDeliverablePayload summary
affiliate.commission.posted.v1No (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.v1No (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)

EventDeliverablePayload summary
cash.granted.v1No (internal)Store credit was granted. grant_id, account_id, tenant_ref, user_ref, amount_cents, source, granted_at.
cash.spent.v1No (internal)Store credit was spent. entry_id, account_id, tenant_ref, user_ref, amount_cents, reason, spent_at.

Fulfillment

EventDeliverablePayload summary
fulfillment.cogs.captured.v1No (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

EventDeliverablePayload summary
inventory.unit.shipped.v1No (internal)A reservation shipped (commit). reservation_id, canonical_item_id, sku_root, internal_lot, order_ref, qty.

Comms

EventDeliverablePayload summary
comms.email.sent.v1No (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.v1No (internal)A send was suppressed. send_id, template_id, dedup_key, suppressed_at.

Marketing

EventDeliverablePayload summary
marketing.message.engaged.v1No (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.v1No (internal)A person entered a campaign. campaign_id, enrollment_id, person_id, recipient_email, entered_via.
marketing.message.sent.v1No (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.v1No (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

EventDeliverablePayload summary
person.created.v1No (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

EventDeliverablePayload summary
subscription.cancelled.v1No (internal)A subscription reached canceled. subscription_id, person_id, plan_ref, reason (requested | dunning_exhausted — distinguishes a deliberate cancel from an involuntary one).

Stores

EventDeliverablePayload summary
store.provisioned.v1No (internal)A store was provisioned. store_ref, display_name.

Beacon

EventDeliverablePayload summary
beacon.event.dispatched.v1No (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)

EventDeliverablePayload summary
webhook.received.v1No (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.

  • Webhooks — the delivery envelope, signature verification, retries, and the test endpoint for the one deliverable event.
  • Tenant-facing API — registering webhook subscriptions.