Everything that happens in Ayra is a typed event with a canonical name in the ay: namespace, a customer, a timestamp and a payload. Signals (facts), engine events (opportunities and decisions) and actions (things Ayra did or held) all use the same stream: it is what the customer timeline shows, what Shopify Flow triggers are built from, and what the post-beta API and webhooks will expose. The storefront bundle also dispatches a small set of DOM events so theme code can react without polling.
ay:<domain>.<event> in lower snake case. Domains match modules or the engine (order, customer, points, credit, tier, referral, segment, stage, opportunity, decision, action, review, question, wishlist, price, restock, preorder, subscription, support). Every payload carries customerId, occurredAt, source (shopify, storefront, account_hub, admin, engine, import) and eventId.
| Event | Status | Means |
|---|
ay:customer.created | Live | A Shopify customer record was created or first seen by Ayra |
ay:customer.identified | Live | A guest identity (email, device) was merged into a customer profile |
ay:customer.login | Live | The customer signed in to the storefront or account hub |
ay:order.placed | Live | Order created in Shopify (any channel) |
ay:order.paid | Live | Order financial status became paid; earn rules run here |
ay:order.fulfilled | Live | Order fulfilled |
ay:order.delivered | Live | Delivery confirmed by the carrier (or estimated when no tracking) |
ay:order.refunded | Live | Full or partial refund; reversals run here |
ay:order.cancelled | Live | Order cancelled |
ay:product.viewed | Live | Storefront product view (web pixel) |
ay:support.opened | Planned (integrations) | A support issue was opened for the customer |
ay:support.resolved | Planned (integrations) | The issue was resolved; Trust Recovery releases held actions after the delay |
| Event | Status | Means |
|---|
ay:points.earned | Live | Points added by an earn rule, import or manual grant |
ay:points.spent | Live | Points redeemed (hub or checkout) |
ay:points.expired | Live | Points expired |
ay:points.expiring | Live | Expiry is within the reminder window |
ay:credit.issued | Live | Store credit issued to the customer’s Shopify account |
ay:credit.reversed | Live | Store credit clawed back after a refund or fraud check |
ay:tier.changed | Live | Tier moved up or down |
ay:referral.shared | Live | Referral link or code shared |
ay:referral.clicked | Live | A referral link was opened |
ay:referral.order | Live | An order was placed with a referral code (pending) |
ay:referral.granted | Live | Both rewards granted after the return window |
ay:referral.reversed | Live | Referral reward reversed (refund or Reward Shield) |
| Event | Status | Means |
|---|
ay:stage.changed | Live | Lifecycle stage changed |
ay:segment.entered | Live | Customer entered a segment |
ay:segment.exited | Live | Customer left a segment |
ay:intent.scored | Planned (Wishlist) | Intent score recomputed |
ay:opportunity.created | Live | A pattern worth acting on was detected (type, priority, evidence, expiry) |
ay:opportunity.converted | Live | An order was attributed to the opportunity |
ay:opportunity.expired | Live | The opportunity expired without conversion |
ay:decision.made | Live | The engine chose a next best action (or NO_ACTION) for the customer |
ay:action.sent | Live | An action was executed through a module and channel |
ay:action.held | Live | Journey Guard held an action (cap, quiet hours, conflict, open issue) |
ay:action.dropped | Live | An action was dropped (expired, Incentive Guard) |
ay:action.responded | Live | The customer engaged with the action (open, click, redeem) |
| Event | Status | Means |
|---|
ay:review.requested | Planned (Reviews) | A review request was sent |
ay:review.submitted | Planned (Reviews) | A review was submitted (pending moderation) |
ay:review.published | Planned (Reviews) | A review was published; rating metafields updated |
ay:question.asked | Planned (Reviews) | A question was asked on a product |
ay:question.answered | Planned (Reviews) | A question was answered |
ay:wishlist.added | Planned (Wishlist) | Variant added to a wishlist |
ay:wishlist.removed | Planned (Wishlist) | Variant removed |
ay:price.dropped | Planned (Wishlist) | Price dropped on a wishlisted variant |
ay:restock.registered | Planned (Back in Stock) | Customer registered for a restock alert |
ay:restock.detected | Planned (Back in Stock) | Inventory went from zero to available |
ay:restock.alerted | Planned (Back in Stock) | A restock alert was sent |
ay:preorder.placed | Planned (Pre-Order) | A pre-order was placed |
ay:preorder.fulfilled | Planned (Pre-Order) | A pre-order shipped |
ay:subscription.created | Planned (Subscriptions) | A subscription contract was created |
ay:subscription.skipped | Planned (Subscriptions) | A cycle was skipped |
ay:subscription.cancel_intent | Planned (Subscriptions) | Cancellation flow started; Save Engine runs |
ay:subscription.saved | Planned (Subscriptions) | A save offer (pause, skip, swap) was accepted |
ay:subscription.cancelled | Planned (Subscriptions) | Contract cancelled |
The core bundle dispatches these on window for theme code. Payloads are in event.detail.
| DOM event | When | detail |
|---|
ay:ready | The core bundle has loaded and read the shop settings | { modules, customer: boolean } |
ay:customer | The customer was identified (or confirmed anonymous) | { id, tier, stage } or null |
ay:wallet.updated | Wallet state fetched or changed | { total, points, storeCredit, vouchers } |
ay:block.rendered | A block finished hydrating | { block, element } |
ay:wishlist.changed | Planned (Wishlist) | { variantId, action } |
window.addEventListener('ay:wallet.updated', (e) => {
document.querySelector('[data-points]').textContent = e.detail.points;
});