apex-spec v1.3.0
The Apex Spec
The canonical event vocabulary your app and Apex's platform speak. Templates, journeys, audiences, and conversion goals all read field names from this catalog \u2014 so naming a payload the spec way means everything you wire up afterward just snaps together.
Customer SDK
App events
112 declaredWhat your customer-facing app fires through the snippet or SDK. Commerce, identity, engagement, communication \u2014 the canonical vocabulary you stand up day one.
apex.track('add_to_cart', { product_id, value, currency })Apex platform
Platform events
65 declaredWhat Apex's dashboard fires as merchants use it. Invitations, integrations, experiments, portfolio access, billing transitions. Templates and journeys wire up these out of the box.
trackApexInternal({ eventName: 'user_invitation_accepted', \u2026 })Three nouns, one vocabulary
- The Apex Spec — the global contract on this page: every canonical event + attribute, shared by all merchants.
- Schema — your workspace's slice of the Spec: the events + attributes you've wired, plus any you define yourself.
- PLG event catalog — a convenience set of lifecycle events the SDK helps you fire; each one maps to a canonical Spec event.
Which revenue event do I use?
Several events carry a money value. Pick by where the truth lives, not by what's easiest to fire:
- Web / server commerce →
order_placed(the money-truth lane; fire it from your server). This is the dollar source of record. - Mobile in-app purchase →
in_app_purchase(store-verified). checkout_completedis the client-side mirror — great for funnel/UX analysis, but it can duplicate or be blocked, so don't use it as the revenue source of record whenorder_placedexists.
App events
What your customer-facing app fires. Field names are flat snake_case (e.g. product_id, order_id).
Commerce
Cart, checkout, and revenue. Drives attribution + abandonment journeys.
add_to_cart
Primary metricUser added a product to their cart.
- product_id*
- string
- prod_atlas_runner_blue_42
- product_name
- string
- Atlas Trail Runner
- value
- number
- 129.99
- cart_value
- number
- currency
- string
- USD
- quantity
- number
- 1
- item_count
- number
- cart_id
- string
- cart_9f2e1a
remove_from_cart
User removed a product from their cart.
- product_id*
- string
- prod_atlas_runner_blue_42
- product_name
- string
- Atlas Trail Runner
- value
- number
- 129.99
- currency
- string
- USD
- quantity
- number
- 1
- cart_id
- string
- cart_9f2e1a
product_view
User viewed a product detail screen.
- product_id*
- string
- prod_atlas_runner_blue_42
- product_name
- string
- Atlas Trail Runner
- category
- string
- Footwear / Running
- value
- number
- 129.99
- currency
- string
- USD
add_to_wishlist
User added a product to a wishlist or saved-for-later list.
- product_id*
- string
- prod_atlas_runner_blue_42
- product_name
- string
- Atlas Trail Runner
- value
- number
- 129.99
- currency
- string
- USD
cart_view
User viewed their cart. The funnel stage between add_to_cart and checkout_started (GA4's view_cart).
- value
- number
- 259.98
- currency
- string
- USD
- item_count
- number
- 2
- cart_id
- string
- cart_9f2e1a
cart_snapshot
Full cart state at a point in time — powers abandoned-cart recovery journeys with the exact items to recover.
- items*
- array
- value
- number
- 259.98
- currency
- string
- USD
- item_count
- number
- 2
- cart_id
- string
- cart_9f2e1a
checkout_started
Primary metricUser began the checkout flow.
- value
- number
- 259.98
- currency
- string
- USD
- item_count
- number
- 2
- cart_id
- string
- cart_9f2e1a
checkout_completed
Primary metricClient-side checkout success. The browser/app-side completion signal — `order_placed` (server) and `in_app_purchase` (IAP) remain the money-truth lanes when both exist.
- order_id
- string
- ord_2024_03_45891
- value*
- number
- 259.98
- currency*
- string
- USD
- item_count
- number
- 2
- items
- array
- cart_id
- string
- subtotal
- number
- 244
- total
- number
- 259.98
- tax
- number
- 15.98
- shipping
- number
- 0
- handling
- number
- discount
- number
- coupon
- string
- account_id
- string
in_app_purchase
Primary metricRevenue event: user completed a purchase inside the app.
- order_id*
- string
- ord_2024_03_45891
- value*
- number
- 259.98
- currency*
- string
- USD
- product_id
- string
- prod_atlas_runner_blue_42
- product_name
- string
- Atlas Trail Runner
- transaction_id
- string
- txn_stripe_3PqXyZ
- items
- array
- is_restored
- boolean
- false
- subtotal
- number
- total
- number
- tax
- number
- shipping
- number
- handling
- number
- discount
- number
- coupon
- string
- account_id
- string
purchase_refunded
Primary metricA prior purchase was refunded.
- order_id*
- string
- ord_2024_03_45891
- value*
- number
- 129.99
- currency*
- string
- USD
- reason
- string
- Customer requested refund within return window
- product_id
- string
- prod_atlas_runner_blue_42
- account_id
- string
subscription_event
Primary metricSubscription lifecycle transition (start, renew, cancel, trial conversion, etc).
- product_id*
- string
- atlas_pro_annual
- action*
- string
- start
- amount
- number
- 299
- currency
- string
- USD
- period_type
- string
- annual
- transaction_id
- string
- txn_stripe_3PqXyZ
- expires_at
- string
- 2027-05-21T00:00:00Z
- is_trial
- boolean
- false
- seat_count
- number
- 25
- account_id
- string
subscription_started
Primary metricA subscription began (first activation, including trial start). Renewals and plan changes flow through subscription_event.
- product_id*
- string
- atlas_pro_annual
- amount
- number
- 299
- currency
- string
- USD
- period_type
- string
- annual
- transaction_id
- string
- is_trial
- boolean
- false
- account_id
- string
subscription_canceled
Primary metricA subscription was canceled by the user or by billing failure. The churn moment win-back journeys trigger on.
- product_id*
- string
- atlas_pro_annual
- reason
- string
- user_canceled
- expires_at
- string
- 2027-05-21T00:00:00Z
- account_id
- string
payment_failed
Primary metricA subscription/invoice payment attempt failed. Triggers the dunning (payment-recovery) journey.
- invoice_id*
- string
- in_3PqXyZ
- amount*
- number
- 299
- currency*
- string
- USD
- subscription_id
- string
- sub_3PqXyZ
- transaction_id
- string
- txn_stripe_3PqXyZ
- attempt_number
- number
- 1
- next_retry_at
- string
- 2026-06-22T00:00:00Z
- update_payment_url
- string
- https://billing.example.com/update
- account_id
- string
payment_recovered
Primary metricA previously-failed payment succeeded on retry or after the customer updated billing. The dunning journey's goal/exit event.
- invoice_id*
- string
- in_3PqXyZ
- amount*
- number
- 299
- currency*
- string
- USD
- subscription_id
- string
- sub_3PqXyZ
- transaction_id
- string
- txn_stripe_3PqYZ2
- account_id
- string
order_placed
Primary metricAn order was placed (server-confirmed purchase). The money-truth lane: this is the dollar source of record for revenue and order-confirmation comms. Fire it from your server, not the browser.
- order_id*
- string
- ord_2024_03_45891
- value*
- number
- 129.99
- currency
- string
- USD
- item_count
- number
- 2
- product_name
- string
- Atlas Trail Runner
- order_url
- string
- /orders/ord_2024_03_45891
- subtotal
- number
- total
- number
- tax
- number
- shipping
- number
- handling
- number
- discount
- number
- coupon
- string
- account_id
- string
Where this is used
first_sale_completed
A marketplace seller's first sale completed. Drives the seller-activation comm.
- order_id
- string
- ord_2024_03_45891
- value
- number
- 49.99
- currency
- string
- USD
- buyer_name
- string
- Alex Rivera
- product_name
- string
- Vintage Film Camera
- payout_days
- number
trial_expired
Primary metricA trial ended without converting (distinct from trial_expiring, which fires BEFORE).
- plan
- string
- atlas_pro
invoice_paid
Primary metricAn invoice was paid successfully (normal billing success; distinct from payment_recovered).
- invoice_id*
- string
- in_3PqXyZ
- amount*
- number
- 299
- currency*
- string
- USD
- subscription_id
- string
- sub_3PqXyZ
- next_billing_date
- string
- 2026-07-20
subscription_renewed
Primary metricA subscription renewed for another period. The renewal moment (was subscription_event action=renew).
- product_id
- string
- atlas_pro_annual
- amount
- number
- 299
- currency
- string
- USD
- period_type
- string
- annual
- transaction_id
- string
subscription_upgraded
Primary metricA subscription moved to a higher plan or more seats (expansion). Carry the NEW recurring amount so MRR expansion is computable.
- product_id
- string
- atlas_pro_annual
- from_plan
- string
- Starter
- to_plan
- string
- Pro
- amount
- number
- 299
- currency
- string
- USD
- period_type
- string
- annual
- seat_count
- number
- 25
- account_id
- string
Where this is used
subscription_downgraded
Primary metricA subscription moved to a cheaper plan or fewer seats (contraction). Carry the NEW recurring amount so MRR contraction is computable.
- product_id
- string
- atlas_starter_monthly
- from_plan
- string
- Pro
- to_plan
- string
- Starter
- amount
- number
- 49
- currency
- string
- USD
- period_type
- string
- monthly
- seat_count
- number
- 5
- reason
- string
- seat_reduction
- account_id
- string
Where this is used
Identity
Sign-up, sign-in, and identity stitching.
user_signed_up
Primary metricA new user account was created.
- method
- string
- referrer
- string
- https://google.com/search?q=atlas+running
user_signed_in
User authenticated into the app.
- method
- string
user_signed_out
User signed out of the app.
No payload fields required.
user_identified
Anonymous visitor was linked to a known user identity.
- user_id*
- string
- usr_atlas_8f3a92
- traits
- object
Lifecycle
Install, open, background, uninstall. Session foundation.
app_install
First install of the app on this device.
No payload fields required.
app_open
Primary metricApp was foregrounded by the user. Foundational session signal.
- source
- string
- push_notification
app_background
App was backgrounded.
No payload fields required.
app_uninstall
App was uninstalled from the device (server-inferred from push silent failure).
No payload fields required.
app_crash
The native app crashed. A harm signal for mobile experiment guardrails.
- message
- string
- NSInvalidArgumentException
- stack
- string
- fatal
- boolean
- true
app_reinstall
App was reinstalled within the reinstall window.
No payload fields required.
user_churned
Primary metricA customer churned (lapsed/cancelled past the win-back window). Drives win-back.
- reason
- string
- stopped_using
user_reactivated
Primary metricA churned customer came back. Drives reactivation-welcome comms.
- inactive_days
- number
- 92
- changes_summary
- string
- New mobile app + faster checkout
Session
Explicit session boundaries with duration.
session_start
Beginning of a session (gap from last event > session timeout).
- session_id
- string
- sess_2026_05_21_abc123
session_end
End of a session (background or timeout).
- session_id
- string
- sess_2026_05_21_abc123
- duration_ms
- number
- 187320
Engagement
Page views, screens, searches, content interactions.
page_view
User viewed a screen or page. Canonical name across web and mobile.
- path
- string
- /products/atlas-runner
- title
- string
- Atlas Runner — Atlas Athletics
- referrer
- string
- https://google.com/search?q=atlas+running
pageview
Deprecated · use page_viewLegacy web pageview. Prefer `page_view` for new integrations.
- path
- string
- /products/atlas-runner
- title
- string
- Atlas Runner — Atlas Athletics
- referrer
- string
- https://google.com/search?q=atlas+running
screen_view
Mobile screen render. Equivalent to `page_view` for native screens.
- screen_name*
- string
- ProductDetail
- previous_screen
- string
- ProductList
search
User executed a search query.
- query*
- string
- trail running shoes
- results_count
- number
- 24
share
User shared content to an external surface.
- content_id
- string
- prod_atlas_runner_blue_42
- channel
- string
content_view
User viewed a piece of content (article, video, etc).
- content_id*
- string
- blog_2026_05_running_form_guide
- content_type
- string
- article
- duration_ms
- number
- 42500
form_submit
Form was submitted by the user.
- form_id
- string
- newsletter_signup
click
Generic click event.
- target
- string
- button#hero-cta
engagement
Composite engagement signal (web only — replaced by individual events on mobile).
No payload fields required.
heartbeat
Periodic heartbeat indicating the user is still active on a page.
No payload fields required.
rage_click
Multiple rapid clicks on the same element — frustration signal.
- target
- string
- button#submit-disabled
dead_click
Click that produced no observable effect — frustration signal.
- target
- string
- div.banner-image
goal_conversion
Primary metricUser completed a defined conversion goal.
- goal_id*
- string
- signup_completed
- value
- number
- 25
Where this is used
onboarding_step_completed
User finished one step of a guided onboarding / activation flow. A proximal funnel signal — emit one per step from the client where the step happens.
- step_id
- string
- connect_data_source
- step_index
- number
- 2
- step_name
- string
- Connect a data source
feature_used
User used a specific product feature. Powers expansion + adoption comms.
- feature_name*
- string
- advanced_reports
- count
- number
- 1
webinar_registered
Primary metricUser registered for a webinar. A campaign conversion signal.
- webinar_topic
- string
- Scaling growth experiments
- webinar_date
- string
- 2026-07-10
survey_started
User began a survey (e.g. NPS).
- survey_id
- string
- nps_2026_q2
survey_completed
Primary metricUser completed a survey. A campaign conversion signal.
- survey_id
- string
- nps_2026_q2
- score
- number
- 9
report_viewed
User viewed a report or dashboard. A core SaaS engagement signal.
- report_id
- string
- rpt_8821
- report_name
- string
- Weekly performance
content_viewed
User viewed a piece of content (article, video, screen). A core engagement signal for content + mobile apps.
- content_id
- string
- cnt_4410
- content_type
- string
- video
task_completed
User completed a task / unit of work. A depth-of-use engagement signal.
- task_id
- string
- tsk_5567
- task_type
- string
- onboarding_step
api_request_completed
User's integration made a successful API request. The core active signal for API-first / developer products.
- endpoint
- string
- /v1/messages
- count
- number
- 1
Product
Product-led-growth outcomes: onboarding completion and activation.
onboarding_completed
User finished the onboarding flow. Source-of-truth milestone — emit server-side when onboarding state flips to complete.
- duration_ms
- number
- 420000
- steps_completed
- number
- 4
activated
Primary metricUser reached the activation / 'aha' milestone (the moment they got first value). The PLG north-star outcome. Emit server-side when the activation criterion is met.
- criterion
- string
- connected_first_integration
project_created
User created their first/Nth project or workspace. A common SaaS + agency activation milestone.
- project_id
- string
- prj_2231
- project_name
- string
- Q3 Launch
Marketing
Merchant-fired triggers that prompt a comm (price drop, restock, review request). Not goal-tier events.
price_dropped
Price dropped on a product a customer viewed or saved. Drives price-drop alerts.
- product_id
- string
- prod_atlas_runner_blue_42
- product_name*
- string
- Atlas Trail Runner
- old_price
- number
- 129.99
- new_price
- number
- 99.99
- discount_percent
- number
- currency
- string
- USD
- product_url
- string
- /products/atlas-trail-runner
restock_due
A back-in-stock / restock reminder is due for a product. Drives restock comms.
- product_id
- string
- prod_atlas_runner_blue_42
- product_name*
- string
- Atlas Trail Runner
- days_since_purchase
- number
- product_url
- string
- /products/atlas-trail-runner
review_request_due
A post-purchase review request is due. Drives review-request comms.
- product_id
- string
- prod_atlas_runner_blue_42
- product_name*
- string
- Atlas Trail Runner
- order_id
- string
- ord_2024_03_45891
- days_ago
- number
- review_url
- string
- /orders/ord_2024_03_45891/review
Fulfillment
Post-purchase shipping + delivery. Drives shipping + review-request comms.
order_shipped
A placed order shipped. Drives shipping-notification comms.
- order_id*
- string
- ord_2024_03_45891
- carrier
- string
- UPS
- tracking_url
- string
- https://ups.com/track?n=1Z999
- delivery_estimate
- string
- 2026-06-24
- shipped_at
- string
order_delivered
A shipped order was delivered. Drives review-request + post-purchase comms.
- order_id*
- string
- ord_2024_03_45891
- delivered_at
- string
- 2026-06-24T18:02:00Z
return_requested
A buyer asked to send goods back. Starts the returns story — distinct from purchase_refunded (money back).
- order_id*
- string
- ord_2024_03_45891
- product_id
- string
- prod_atlas_runner_blue_42
- reason
- string
- wrong_size
- quantity
- number
- 1
return_completed
Returned goods were received back. The return-rate numerator; fire purchase_refunded separately when money moves.
- order_id*
- string
- ord_2024_03_45891
- product_id
- string
- prod_atlas_runner_blue_42
- reason
- string
- wrong_size
- condition
- string
- resellable
- refunded
- boolean
- true
Marketplace
Seller + buyer lifecycle: signups, listings, payouts, reviews, trust badges.
seller_signup
Primary metricA seller joined the marketplace. The marketplace-side activation conversion.
- seller_id
- string
- sel_4821
- store_name
- string
- Atlas Outfitters
listing_created
A seller created a listing. Drives first-listing + activation nudges.
- listing_id
- string
- lst_99213
- product_name
- string
- Atlas Trail Runner
- price
- number
- 129.99
- currency
- string
- USD
buyer_review_requested
A buyer is due to review a marketplace purchase.
- order_id
- string
- ord_2024_03_45891
- product_name
- string
- Atlas Trail Runner
- seller_name
- string
- Atlas Outfitters
payout_sent
A seller payout was sent. Drives payout-confirmation comms.
- amount*
- number
- 482.5
- currency*
- string
- USD
- payout_id
- string
- po_8841
- transaction_count
- number
- 12
- payment_method
- string
- bank_transfer
- processing_days
- number
- 2
trust_badge_earned
A seller earned a trust badge (e.g. Top Rated).
- badge_name*
- string
- Top Rated Seller
listing_viewed
A buyer viewed a marketplace listing. A demand-side engagement signal.
- listing_id
- string
- lst_99213
- product_name
- string
- Atlas Trail Runner
message_sent
A user sent a message (buyer↔seller). A liquidity + engagement signal for marketplaces.
- thread_id
- string
- thr_7781
offer_submitted
A buyer submitted an offer / bid on a listing. A high-intent demand signal.
- listing_id
- string
- lst_99213
- amount
- number
- 110
- currency
- string
- USD
transaction_completed
Primary metricA marketplace transaction closed (buyer + seller). The two-sided activation/outcome moment.
- transaction_id
- string
- txn_55621
- amount
- number
- 129.99
- fee_amount
- number
- 15.6
- cost_amount
- number
- 4.1
- currency
- string
- USD
- buyer_id
- string
- u_buyer_812
- seller_id
- string
- sel_4821
- listing_id
- string
- lst_99213
- category
- string
- footwear
- geo
- string
- US
- price_band
- string
- 100-250
seller_viewed
A buyer viewed a seller's profile/storefront. A demand-side trust signal.
- seller_id
- string
- sel_4821
- store_name
- string
- Atlas Outfitters
item_saved
A buyer saved/favorited a listing. A mid-funnel demand signal.
- listing_id
- string
- lst_99213
- product_name
- string
- Atlas Trail Runner
inquiry_started
A buyer opened an inquiry/conversation about a listing. High-intent demand.
- listing_id
- string
- lst_99213
- thread_id
- string
- thr_7781
match_created
Supply and demand matched (offer accepted / booking confirmed) before payment. The liquidity moment for negotiated marketplaces.
- listing_id
- string
- lst_99213
- buyer_id
- string
- u_buyer_812
- seller_id
- string
- sel_4821
- amount
- number
- 110
- currency
- string
- USD
transaction_canceled
A marketplace transaction was canceled before fulfillment. The cancellation-rate numerator.
- transaction_id
- string
- txn_55621
- reason
- string
- out_of_stock
- canceled_by
- string
- seller
review_submitted
A post-transaction review was submitted. Powers average rating + review coverage (trust metrics).
- transaction_id
- string
- txn_55621
- listing_id
- string
- lst_99213
- rating
- number
- 5
- reviewer_side
- string
- buyer
dispute_opened
A buyer or seller opened a dispute on a transaction. The dispute-rate numerator (trust metric).
- transaction_id
- string
- txn_55621
- reason
- string
- item_not_as_described
- opened_by
- string
- buyer
Agency
Client lifecycle: onboarding, campaign milestones, renewals, new capabilities.
client_onboarded
Primary metricAn agency onboarded a new client. The agency-side activation conversion.
- client_id
- string
- cli_2231
- client_name
- string
- Northwind Co
- manager_name
- string
- Jordan Lee
campaign_milestone_reached
A client campaign hit a milestone. Drives results/update comms.
- campaign_id
- string
- cmp_5521
- campaign_name
- string
- Spring Launch
- milestone
- string
- 100 conversions
- business_impact
- string
- +$24k pipeline
contract_renewal_approaching
A client contract renewal is approaching. Drives renewal comms.
- contract_id
- string
- ct_7781
- days_remaining
- number
- 30
- renewal_date
- string
- 2026-07-20
- contract_period
- string
- annual
new_capability_launched
The agency launched a new capability/service. Drives announcement comms.
- capability_id
- string
- cap_312
- capability_name
- string
- Paid Social
- capability_description
- string
- Full-funnel paid social management
task_updated
An agency team member updated a task. A core agency activity signal.
- task_id
- string
- tsk_5567
- status
- string
- in_progress
asset_uploaded
A team member uploaded an asset/deliverable. A core agency activity + activation signal.
- asset_id
- string
- ast_3312
- asset_type
- string
- creative
comment_added
A user added a comment / collaboration note. A depth-of-use signal.
- target_id
- string
- ast_3312
time_logged
A team member logged time against a client/project. A core agency activity signal.
- minutes
- number
- 90
- project_id
- string
- prj_2231
client_report_viewed
A client viewed an agency results report. A retention + value-delivery signal.
- report_id
- string
- rpt_8821
- client_id
- string
- cli_2231
Loyalty
Loyalty + usage milestones that prompt reward and celebration comms.
loyalty_milestone_reached
A customer hit a loyalty milestone (points/tier). Drives reward comms.
- points
- number
- 5000
- reward
- string
- $50 credit
- milestone
- string
- Gold tier
usage_milestone_reached
A customer crossed a usage milestone. Drives celebratory + expansion comms.
- milestone
- string
- 1,000 events tracked
- percentile
- number
- 95
Communication
Push, email, in-app message delivery + interaction.
push_received
Device received a push notification (delivery confirmation).
- message_id
- string
- msg_2026_05_21_abc
- campaign_id
- string
- cmp_atlas_spring_2026
push_opened
User tapped/opened a push notification.
- message_id
- string
- msg_2026_05_21_abc
- campaign_id
- string
- cmp_atlas_spring_2026
- deep_link
- string
- atlas://product/atlas-runner
email_opened
Email open tracked via pixel.
- message_id
- string
- msg_2026_05_21_abc
- campaign_id
- string
- cmp_atlas_spring_2026
email_clicked
Link in email was clicked.
- message_id
- string
- msg_2026_05_21_abc
- campaign_id
- string
- cmp_atlas_spring_2026
- link
- string
- https://atlasathletics.com/products/atlas-runner
unsubscribed
Recipient unsubscribed from a message/list. A harm signal for messaging experiment guardrails.
- message_id
- string
- msg_2026_05_21_abc
- campaign_id
- string
- cmp_atlas_spring_2026
- list_id
- string
in_app_message_seen
In-app message was rendered to the user.
- message_id
- string
- msg_2026_05_21_abc
- campaign_id
- string
- cmp_atlas_spring_2026
in_app_message_clicked
User interacted with an in-app message CTA.
- message_id
- string
- msg_2026_05_21_abc
- campaign_id
- string
- cmp_atlas_spring_2026
- cta
- string
- upgrade_now
Deep links
Deferred + direct deep-link opens with attribution context.
deep_link_open
App opened via a deep link.
- url*
- string
- atlas://product/atlas-runner
- source
- string
- campaign_id
- string
- cmp_atlas_spring_2026
- referrer
- string
- https://atlasathletics.com
Attribution
Reattribution and reengagement signals.
reattribution
A re-install was matched to a prior install.
- partner_id
- string
- partner_facebook_ads
- original_install_id
- string
- inst_2025_11_xyz
reengagement
A returning user opened the app after a period of inactivity.
- partner_id
- string
- partner_email_winback
- inactive_days
- number
- 30
System
Custom events and internal lifecycle transitions.
custom
Custom event type. Stored with the original event name preserved in `data.eventName`. Use canonical events when possible.
No payload fields required.
lifecycle_transition
Internal Apex lifecycle/level transition event (not user-generated).
No payload fields required.
js_error
JavaScript runtime error captured by the web SDK.
- message
- string
- ReferenceError: window.atlas is not defined
- stack
- string
- at fn (https://atlasathletics.com/app.js:123:45)
Platform events
What Apex itself fires as merchants use the dashboard. Useful when you build agent automations on top of the platform.
Invitations
Team invite lifecycle from Apex's dashboard.
user_invitation_created
An organization owner/admin invited a new teammate. Drives the invite email + reminder branch.
- inviter_name*
- string
- Sarah Chen
- inviter_email
- string
- sarah@hypernova.inc
- org_name*
- string
- Hypernova Inc
- org_id*
- string
- org_hypernova_8f3a
- invitee_email*
- string
- alex@example.com
- role*
- string
- admin
- accept_url*
- string
- https://app.apex.inc/invite/accept?token=inv_4f8a2b7c9d3e1f6a
- invitation_token
- string
- inv_4f8a2b7c9d3e1f6a
- invitation_id
- string
- inv_4f8a2b7c
Where this is used
user_invitation_accepted
A pending invitation was accepted. Notifies the inviter that their teammate joined.
- member_name*
- string
- Alex Rivera
- inviter_name
- string
- Sarah Chen
- inviter_email
- string
- sarah@hypernova.inc
- org_name*
- string
- Hypernova Inc
- role*
- string
- admin
- invitee_email
- string
- alex@example.com
- href
- string
- /dashboard/settings/organization/team
Where this is used
developer_invite_sent
An operator handed SDK wire-up off to a developer with a private integration-guide link.
- inviter_name*
- string
- Sarah Chen
- inviter_role
- string
- admin
- developer_email*
- string
- dev@hypernova.inc
- workspace_name
- string
- Hypernova Production
- note
- string
- Snippet goes in the global layout please.
- handoff_url*
- string
- https://app.apex.inc/onboarding/developer-handoff?token=hof_4f8a2b7c
- signup_url
- string
- https://app.apex.inc/signup
Where this is used
Integrations
Connector connect / sync / failure events Apex fires per merchant.
integration_connected
A data-source integration was authenticated and connected.
- integration_name*
- string
- LinkedIn Ads
- integrations_url
- string
- /dashboard/integrations
Where this is used
integration_sync_completed
A scheduled data import from a connected integration finished successfully.
- integration_name*
- string
- LinkedIn Ads
- row_count
- number
- 1247
- performance_url
- string
- /dashboard/performance
- integrations_url
- string
- /dashboard/integrations
Where this is used
integration_sync_failed
A scheduled data import from a connected integration failed.
- integration_name*
- string
- Google Analytics
- error_message
- string
- Authentication expired — please reconnect.
- integrations_url
- string
- /dashboard/integrations
Where this is used
Experiments
Launches, significance, conclusions, promotion to default.
experiment_launched
An A/B experiment was started.
- experiment_name*
- string
- Homepage CTA Copy Test
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
- hypothesis
- string
- Changing the CTA from 'Get Started' to 'Start Free' lifts signup rate by 15%.
experiment_created
An experiment was created as a draft. Enrolls the operator's lifecycle journey (1h publish-nudge gate).
- experiment_id
- string
- experiment_name*
- string
- Homepage CTA Copy Test
- surface
- string
- web
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
Where this is used
experiment_first_exposure
The first visitor was bucketed into a running experiment (the 'it's alive' moment). Fires once.
- experiment_id
- string
- experiment_name*
- string
- Homepage CTA Copy Test
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
Where this is used
experiment_daily_recap
Daily digest of all active experiments for a workspace admin. Carries an `experiments` array rendered by the recap comm's repeater block.
- count
- number
- 2
- experiments
- string
Where this is used
experiment_projected_underpowered
A running experiment is projected to reach the end of its window without enough traffic to call a result. Fired while there is still time to extend, unlike experiment_window_closed_underpowered which fires after the deadline has passed.
- experiment_id
- string
- experiment_name*
- string
- Welcome subject line
- projection_reason
- string
- too_slow
- exposure_per_arm
- string
- 18
- sample_floor_per_arm
- string
- 50
- days_elapsed
- string
- 7
- days_remaining
- string
- 7
- days_still_needed
- string
- 13
- lift_so_far
- string
- +4.1%
- confidence_so_far
- string
- preview_url
- string
- experiment_url
- string
- /dashboard/experiments/exp_welcome_subject
Where this is used
experiment_window_closed_underpowered
An experiment's evaluation window closed while still underpowered (sample floor unmet). The operator can extend once or let it auto-conclude.
- experiment_id
- string
- experiment_name*
- string
- Homepage CTA Copy Test
- exposure_per_arm
- string
- 48
- sample_floor_per_arm
- string
- 200
- detectable_lift_floor
- string
- grace_days_remaining
- string
- 5
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
Where this is used
experiment_significant
An experiment reached statistical significance.
- experiment_name*
- string
- Homepage CTA Copy Test
- winning_arm
- string
- Start Free
- lift
- string
- +18.3%
- confidence
- string
- 97%
- exposures
- string
- 12,480
- preview_url
- string
- https://apex-avatars-staging.s3.amazonaws.com/experiment-assets/exp_homepage_cta/variant-1.png
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
Where this is used
experiment_concluded
An experiment finished (either by significance or by evaluation-window expiry).
- experiment_name*
- string
- Homepage CTA Copy Test
- result
- string
- winner
- lift
- string
- +18.3%
- confidence
- string
- 97%
- confidence_interval
- string
- safety_verdict
- string
- exposures
- string
- 12,480
- preview_url
- string
- https://apex-avatars-staging.s3.amazonaws.com/experiment-assets/exp_homepage_cta/variant-1.png
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
- result_label
- string
- Significant winner
Where this is used
experiment_promoted
An experiment's winning arm was promoted to the default.
- experiment_name*
- string
- Homepage CTA Copy Test
- winning_arm
- string
- Start Free
- lift
- string
- +18.3%
- confidence
- string
- 97%
- exposures
- string
- 12,480
- preview_url
- string
- https://apex-avatars-staging.s3.amazonaws.com/experiment-assets/exp_homepage_cta/variant-1.png
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
Where this is used
experiment_deploying
A gated experiment's PR merged; the variant is deploying. The test starts counting on the first live visitor.
- experiment_name*
- string
- Homepage CTA Copy Test
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
Where this is used
experiment_graduated
Apex opened a graduation PR to bake the winning variant into the merchant's code and remove the experiment flag.
- experiment_name*
- string
- Homepage CTA Copy Test
- graduation_pr_url*
- string
- https://github.com/acme/site/pull/482
- experiment_url
- string
- /dashboard/experiments/exp_homepage_cta
Where this is used
guardrail_breached
A running experiment significantly hurt a protected metric (a confirmed critical breach). Promotion is blocked.
- experiment_id
- string
- experiment_name*
- string
- Free shipping banner
- experiment_url
- string
- /dashboard/experiments/exp_abc
- href
- string
- /dashboard/experiments/exp_abc
Where this is used
guardrail_autopaused
Apex auto-paused an experiment because a variant hurt a protected metric (auto-pause is on).
- experiment_id
- string
- experiment_name*
- string
- Free shipping banner
- experiment_url
- string
- /dashboard/experiments/exp_abc
- href
- string
- /dashboard/experiments/exp_abc
Where this is used
experiment_invalid
An experiment's traffic split is broken (sample-ratio-mismatch), so its results can't be trusted.
- experiment_id
- string
- experiment_name*
- string
- Free shipping banner
- experiment_url
- string
- /dashboard/experiments/exp_abc
- href
- string
- /dashboard/experiments/exp_abc
Where this is used
experiment_started
An experiment started running (e.g. its gated PR merged).
- experiment_name*
- string
- Above-fold CTA
- experiment_url
- string
- /dashboard/experiments/exp_482
Where this is used
experiment_stale
An experiment is stuck — pending deployment past 30 days, running past its max duration, or live with real traffic but never counting an exposure (a likely broken deploy).
- experiment_name*
- string
- Above-fold CTA
- reason
- string
- pending_deployment_timeout
- conclusion
- string
- Waiting 31 days for its PR to merge.
- experiment_url
- string
- /dashboard/experiments/exp_482
Where this is used
experiment_awaiting_promotion
A manual-promotion experiment reached a confident winner and is waiting for an operator to promote it.
- experiment_name*
- string
- Welcome Email Variant Test
- winning_arm
- string
- Variant B
- confidence
- string
- 96%
- lift
- string
- +12.4%
- exposures
- string
- 8,210
- preview_url
- string
- https://apex-avatars-staging.s3.amazonaws.com/experiment-assets/exp_welcome/variant-b.png
- experiment_url
- string
- /dashboard/experiments/exp_welcome
Where this is used
Portfolio
Investor / partner access requests and share-link acceptances.
portfolio_access_requested
An investor or partner requested access to a portfolio.
- requester_name*
- string
- Sequoia Capital
- requester_email
- string
- partners@sequoia.com
- portfolio_name
- string
- Atlas Athletics — Series B Data Room
- approve_url*
- string
- https://app.apex.inc/portfolio/requests/req_abc/approve
- reject_url
- string
- https://app.apex.inc/portfolio/requests/req_abc/reject
Where this is used
portfolio_access_approved
A portfolio access request was approved by the owner.
- granter_name*
- string
- Atlas Athletics
- scope
- string
- all workspaces
- portfolio_url
- string
- /dashboard/portfolio
- portfolio_name
- string
- Atlas Athletics — Series B Data Room
Where this is used
portfolio_access_rejected
A portfolio access request was rejected by the owner.
- granter_name*
- string
- Atlas Athletics
- portfolio_name
- string
- Atlas Athletics — Series B Data Room
- reason
- string
- Not ready to share yet — let's reconnect after our next board meeting.
Where this is used
portfolio_reconsent_required
A portfolio grant predates the current disclosure and needs re-approval before metrics resume.
- viewer_name*
- string
- Sequoia Capital
- disclosure_text
- string
- Approving shares your business performance with this organization: revenue and recurring revenue, growth, ...
- granted_at
- string
- 2026-02-14
- expires_at
- string
- 2026-08-27
- review_url
- string
- /dashboard/settings/workspace/data-sharing
Where this is used
portfolio_company_flagged
An at-risk reason appeared on this company's portfolio snapshot for the first time, so the investors with access can now see it.
- reasons*
- string
- Revenue down 34% over the last 30 days; Net revenue retention below 100%
- viewer_names
- string
- Northline Capital, Ridgeway Partners
- viewer_count
- number
- 2
- review_url
- string
- /dashboard
Where this is used
portfolio_workspace_added
A new workspace entered an existing all-workspaces portfolio grant and is now included in what investors see.
- workspace_names*
- string
- Atlas Trail
- viewer_names
- string
- Northline Capital
- viewer_count
- number
- 1
- review_url
- string
- /dashboard/settings/workspace/data-sharing
Where this is used
portfolio_share_accepted
A recipient accepted a portfolio share link.
- viewer_email*
- string
- partners@sequoia.com
- portfolio_name
- string
- Atlas Athletics — Series B Data Room
- portfolio_url
- string
- /dashboard/portfolio
- owner_name
- string
- Chris at Atlas
- shared_at
- string
- 2026-05-21T14:30:00Z
Where this is used
Engagement
Page views, screens, searches, content interactions.
adoption_gap_detected
An end-user has not yet adopted a feature within its milestone gap window. Fired by the Adoption Engine evaluator (directly, never via public ingest) to enroll the user in the feature's nudge journey. Nudge journeys filter on `feature_id`.
- name
- string
- Dana
- first_name
- string
- Dana
- feature_id*
- string
- reporting
- feature_name
- string
- Reporting
- nudge_url
- string
- /dashboard/reports
Where this is used
milestone_adopted
An end-user just ACHIEVED an adoption milestone (its adoptedWhen predicate became true). Fired ONCE per (end-user, milestone) by the Adoption Engine evaluator directly (never via public ingest) to enroll the user in the milestone's celebration journey. This is the presence counterpart to `adoption_gap_detected` (absence). Celebration journeys filter on `milestone_id`.
- name
- string
- Dana
- first_name
- string
- Dana
- milestone_id*
- string
- mile_ran_first_report
- feature_id*
- string
- reporting
- milestone_name
- string
- Ran a report
- celebration_url
- string
- /dashboard/reports
Billing
Subscription upgrades, downgrades, and tier-limit nudges.
shared_pool_suspended
A workspace's shared-pool email sending was suspended by the circuit-breaker because its complaint/bounce rate crossed the SES limit. Drives the transactional suspension notice with the resume path (dedicated IP).
- name
- string
- Chris
- first_name
- string
- Chris
- complaint_rate*
- string
- 0.42%
- upgrade_url
- string
- /dashboard/settings/workspace/deliverability
Where this is used
tier_limit_approaching
Workspace is nearing a plan limit; eligible for an upgrade nudge.
- name
- string
- Chris
- first_name
- string
- Chris
- current_tier*
- string
- Starter
- next_tier
- string
- Pro
- feature_count
- number
- 8
- top_feature
- string
- CPWU Attribution
- usage_percent
- number
- usage_current
- number
- usage_limit
- number
- resource_name
- string
- recommended_plan
- string
- upgrade_url
- string
- /dashboard/billing/upgrade
Where this is used
usage_threshold_reached
An org-pooled usage meter crossed a billing threshold (80% or 100% of the free allowance). Fires once per (org, meter, period, threshold). Drives the per-meter usage alert + 'Approaching your limit' journey.
- name
- string
- Chris
- first_name
- string
- Chris
- billing_class*
- string
- communications
- meter_label*
- string
- Messages
- usage_pct*
- number
- 100
- free_limit*
- number
- 10000
- usage_current*
- number
- 10000
- period*
- string
- 2026-06
- cap_kind*
- string
- hard
- overage_rate
- number
- 0.0006
- usage_url
- string
- /dashboard/settings/organization/usage
usage_period_reset
A new calendar-month billing period began; all usage meters reset to zero. Used to exit the 'Approaching your limit' journey.
- name
- string
- Chris
- first_name
- string
- Chris
- period*
- string
- 2026-07
- usage_url
- string
- /dashboard/settings/organization/usage
usage_statement_ready
The monthly usage statement for an org is ready — an itemized, per-meter summary of usage and estimated charges. Transparency statement, not a payment.
- name
- string
- Chris
- first_name
- string
- Chris
- period*
- string
- 2026-06
- est_total
- number
- 336.5
- statement_url
- string
- /dashboard/settings/organization/usage
usage_invoice_estimate
A few days before the period-close cron finalizes an org's usage invoice, this fires for orgs with a nonzero estimated overage that Apex can collect. Drives the pre-charge estimate email so the first invoice is never a surprise.
- name
- string
- Chris
- first_name
- string
- Chris
- org_id*
- string
- org_hypernova_8f3a
- org_name
- string
- Hypernova Inc
- period*
- string
- 2026-06
- estimate_usd*
- number
- 137
- string
- chris@hypernova.inc
usage_invoice_failed
An org's usage invoice exhausted Stripe's smart retries (or a net-terms invoice went past due). The org is marked delinquent; this drives the dunning notice with a link to the hosted invoice to fix payment.
- name
- string
- Chris
- first_name
- string
- Chris
- org_id*
- string
- org_hypernova_8f3a
- org_name
- string
- Hypernova Inc
- amount_due_usd
- number
- 137
- hosted_invoice_url
- string
- https://invoice.stripe.com/i/acct_x/test_y
- string
- chris@hypernova.inc
merchant_payout_shortfall
A merchant's connected Stripe balance was insufficient to cover a scheduled partner payout. Graduated escalation (level 1/2/3) prompts the merchant to top up. Merchant-facing only — never surfaced to the partner.
- name
- string
- Chris
- first_name
- string
- Chris
- workspace_key
- string
- acme-a1b2
- escalation_level*
- number
- 1
- shortfall_usd*
- number
- 240.5
- next_retry_at
- string
- 2026-07-15T02:00:00.000Z
- payouts_url
- string
- /dashboard/settings/organization/payouts
partner_payout_paid
A partner's payout transfer succeeded. Fired synchronously the instant the facilitated Stripe transfer completes, so the partner gets an immediate receipt. Merchant balance/shortfall details are never included.
- name
- string
- Sarah
- first_name
- string
- Sarah
- amount_usd*
- number
- 245.5
- transfer_id
- string
- tr_1TswmU
- batch_id
- string
- pay_9f3a
- payouts_url
- string
- https://partners.apex.inc/account#payouts
partner_payout_failed
A partner's payout could not be completed (e.g. their Stripe account is restricted). Prompts the partner to fix their payout setup. Never exposes the merchant's balance or cash position.
- name
- string
- Sarah
- first_name
- string
- Sarah
- reason
- string
- Your Stripe account needs attention
- payouts_url
- string
- https://partners.apex.inc/account#payouts
rate_change_scheduled
A future-dated price change was scheduled for a rate card. Drives the price-change transparency notice to every platform user. Effective dates are month-granular (takes effect the 1st of the period), so no customer is re-priced mid-cycle.
- name
- string
- Chris
- first_name
- string
- Chris
- org_name
- string
- Atlas
- rate_card*
- string
- Pay-as-you-go
- effective_period*
- string
- 2026-08
- effective_label
- string
- August 2026
- changes_summary*
- string
- Events: $0.00005 → $0.00006 per event
- pricing_url
- string
- /pricing
Where this is used
billing_limit_approaching
A card-less org is approaching its free monthly allowance. Add a payment method to avoid losing dashboard access and paused sends. Fired once on the ok → approaching transition.
- name
- string
- Chris
- first_name
- string
- Chris
- org_name
- string
- Atlas
- usage_pct
- number
- 80
- driver_meter
- string
- web-measurement
- billing_url
- string
- /dashboard/settings/organization/billing
Where this is used
billing_limit_reached
A card-less org hit 100% of its free monthly allowance — analytics views are now locked and non-transactional sends are paused. Add a payment method to restore access instantly. Fired once on the transition into analytics_locked.
- name
- string
- Chris
- first_name
- string
- Chris
- org_name
- string
- Atlas
- driver_meter
- string
- web-measurement
- billing_url
- string
- /dashboard/settings/organization/billing
Where this is used
billing_limit_resolved
A card-less org's billing incident cleared — a payment method was added or usage reset for the new month. Access restored; nothing more to do. Paired resolved confirmation for billing_limit_approaching / billing_limit_reached.
- name
- string
- Chris
- first_name
- string
- Chris
- org_name
- string
- Atlas
- billing_url
- string
- /dashboard/settings/organization/billing
Where this is used
trial_expiring
A workspace trial is approaching expiry. Drives the trial-expiring upgrade nudge.
- name
- string
- Chris
- first_name
- string
- Chris
- days_remaining
- number
- 3
- plan
- string
- Pro
- value_summary
- string
- upgrade_url
- string
- /dashboard/billing/upgrade
Operations
Anomaly alerts, weekly digests, Cognito auth hooks.
account_health_alert
Apex stopped receiving data from a workspace's installed snippet/SDK, or a live experiment isn't rendering. Fired once per health incident (traffic-aware) by the account-health cron.
- name
- string
- Chris
- first_name
- string
- Chris
- workspace_name
- string
- Atlas — Production
- issue_summary*
- string
- your Apex snippet stopped sending data
- issue_detail
- string
- We haven't seen an event or heartbeat from your site in over 24 hours. If you changed your site or removed the snippet, measurement is silently paused.
- diagnose_url
- string
- /dashboard/mobile/health
Where this is used
account_health_resolved
A workspace's data-integrity incident cleared — events/heartbeats are flowing again. Paired resolved confirmation for account_health_alert.
- name
- string
- Chris
- first_name
- string
- Chris
- workspace_name
- string
- Atlas — Production
- health_url
- string
- /dashboard/mobile/health
Where this is used
url_drift_detected
The URL-drift cron detected that a workspace's stored site URL now redirects somewhere new, which can silently break measurement. Fired once per drift incident.
- name
- string
- Chris
- first_name
- string
- Chris
- workspace_name
- string
- Atlas — Production
- stored_url*
- string
- https://atlas.example.com
- suggested_url*
- string
- https://www.atlas.example.com
- drift_url
- string
- /dashboard/settings/workspace/general
Where this is used
url_drift_resolved
A tracked-URL drift cleared (the merchant accepted the new canonical, dismissed it, or the redirect went away). Paired resolved confirmation for url_drift_detected.
- name
- string
- Chris
- first_name
- string
- Chris
- workspace_name
- string
- Atlas — Production
- drift_url
- string
- /dashboard/settings/workspace/general
Where this is used
anomaly_detected
Apex detected a statistically anomalous shift in a tracked metric.
- metric_name*
- string
- Google Ads CPC
- scope
- string
- Atlas Athletics — Production
- delta
- string
- +340% vs. 30-day average
- investigate_url*
- string
- /dashboard/intelligence/anomalies/anom_2026_05_21
- anomaly_url
- string
- /dashboard/intelligence/anomalies
Where this is used
weekly_digest_scheduled
Weekly summary digest was scheduled for delivery.
- name
- string
- Chris
- first_name
- string
- Chris
- period*
- string
- May 14–20, 2026
- digest_url
- string
- /dashboard/digest/2026-05-20
- total_imports
- string
- 4,832
- active_integrations
- string
- 3
- experiments
- string
- 2
Where this is used
cognito_verification_code
AWS Cognito custom-message hook needs a verification-code email rendered.
- code*
- string
- 482915
- code_parameter
- string
- {####}
Where this is used
apex_setup_source_connected
A new Data Source was registered for the workspace (explicitly or lazily on first event).
- source_kind*
- string
- website
- source_id
- string
- ds_website
apex_setup_first_event_detected
The workspace's first real event arrived — the 'Apex is live' activation moment.
- platform
- string
- web
- event_name
- string
- page_view
apex_setup_first_identified_event
The workspace's first contact link was created — a named customer appeared in Apex (the onboarding north-star).
- surface
- string
- web
apex_setup_templates_unlocked
A readiness unlock fired: required traits/events arrived and named templates became Ready to run.
- unlock_id
- string
- unl_8f3a92
- track_id
- string
- identity
- template_count
- number
- 3
apex_setup_first_belief_created
The workspace's first belief was authored — the first-insight → first-belief handoff completed.
- belief_id
- string
- blf_2026_06_09
- source
- string
- first-facts
report_generated
A scheduled report finished generating. Drives the agency/report-ready comm.
- report_type
- string
- Monthly performance
- report_id
- string
- period
- string
- May 2026
- highlights
- string
- Spend down 12%, conversions up 8%.
- report_url
- string
- /dashboard/reports/2026-05
Lifecycle
Install, open, background, uninstall. Session foundation.
user_signup
Apex-internal signup completion event — fires when a new merchant finishes signup in the Apex dashboard. Distinct from the SDK-side `user_signed_up` event which customers fire from their own app.
- name
- string
- Chris Caldwell
- first_name
- string
- Chris
- onboarding_url
- string
- /dashboard
- referring_org_id
- string
- org_atlas_ventures
- referral_source
- string
- portfolio_invite
Where this is used
onboarding_in_progress
A merchant started but hasn't finished onboarding. Drives the onboarding-reminder nudge.
- name
- string
- Chris
- first_name
- string
- Chris
- steps_remaining
- number
- 2
- onboarding_url
- string
- /dashboard?setup=welcome
Where this is used
onboarding_unlock_available
Apex closed a workspace's first loop while the operator was away — a pending onboarding unlock is waiting to be revealed. Fired once when a NEW pending unlock is created.
- name
- string
- Chris
- first_name
- string
- Chris
- outcome
- string
- your first paying customer
- artifact_count
- number
- 3
- reveal_url
- string
- /dashboard
Where this is used
feature_unused_for_7d
A high-value feature has gone unused for 7 days. Drives the feature-nudge comm.
- name
- string
- Chris
- first_name
- string
- Chris
- feature_name*
- string
- Experiments
- cta_url
- string
- /dashboard/experiments
Where this is used
password_reset_requested
A user requested a password reset. Recipient-initiated; drives the transactional reset email.
- name
- string
- Chris
- reset_url*
- string
- https://app.apex.inc/auth/reset?token=rst_4f8a2b7c
Where this is used
Attributes
Identity + entity traits you set via identify() and reference in templates as {{first_name}} or {{order.total}}. Generated from the Spec, so this list never drifts.
user
| Field | Type | Description | Example |
|---|---|---|---|
| id | string | Stable end-user id passed to apex.identify(). | u_8c21 |
| emailPII | End-user email. Required for transactional sends. | alex@example.com | |
| email_verified | boolean | Whether the email has been confirmed. | true |
| first_name | string | Given name. Use in greetings. | Alex |
| last_name | string | Family name. | Rivera |
| full_name | string | Full display name. | Alex Rivera |
| username | string | Handle or login. | arivera |
| phonePII | string | Phone number in E.164 where possible. | +14155550100 |
| avatar_url | url | Profile image URL. | |
| title | string | Job title or role. | Head of Growth |
| company | string | Company the user belongs to. | Atlas |
| gender | string | Self-reported gender. | |
| birthdayPII | date | Date of birth. | 1990-04-12 |
| address_line1PII | string | Street address line 1. | 1 Market St |
| address_line2PII | string | Street address line 2. | Suite 400 |
| city | string | City. | San Francisco |
| region | string | State or province. | California |
| postal_codePII | string | Postal / ZIP code. | 94105 |
| country | string | Country display name. | United States |
| country_code | string | ISO 3166-1 alpha-2 country code. | US |
| latitudePII | number | Geo latitude. | 37.7749 |
| longitudePII | number | Geo longitude. | -122.4194 |
| timezone | string | IANA timezone. | America/Los_Angeles |
| locale | string | Locale or language. | en-US |
| created_at | date | When the user account was created. | 2026-01-15 |
| last_seen_at | date | Most recent activity timestamp. | 2026-06-01 |
| plan | string | Subscription plan or tier. | pro |
| subscription_status | string | Billing/subscription status. | active |
| lifecycle_stage | string | Merchant-defined relationship/funnel stage for this user (e.g. lead, trial, active, churned). Maps to the contact's lifecycle field on a verified identify (last-write-wins). | active |
| trial_ends_at | date | When the user's trial expires. | 2026-07-01 |
| lifetime_value | number | Total revenue from this user. | 480 |
| marketing_opt_in | boolean | Marketing email consent. | true |
| referrer | string | Acquisition referrer. | |
| utm_source | string | Acquisition UTM source. | newsletter |
| utm_medium | string | Acquisition UTM medium. | |
| utm_campaign | string | Acquisition UTM campaign. | spring_launch |
| utm_term | string | Acquisition UTM term. | |
| utm_content | string | Acquisition UTM content. | |
| marketplace_side | string | Which side(s) of the marketplace this user is on: buyer, seller, or both. | seller |
| is_seller | boolean | True when the user sells on the marketplace. | true |
| is_buyer | boolean | True when the user buys on the marketplace. | true |
| store_name | string | The seller's storefront display name. | Atlas Outfitters |
| seller_id | string | The marketplace's stable seller identifier. | sel_4821 |
| payout_method | string | How the seller receives payouts. One of: stripe, paypal, bank_transfer, other — never account details. | stripe |
account
| Field | Type | Description | Example |
|---|---|---|---|
| id | string | Stable account / org id. | acct_42 |
| name | string | Account or company name. | Atlas Inc |
| website | url | Account website. | https://atlas.example.com |
| domain | string | Email/company domain. | atlas.example.com |
| plan | string | Account plan or tier. | enterprise |
| mrr | number | Monthly recurring revenue. | 2400 |
| arr | number | Annual recurring revenue. | 28800 |
| seat_count | number | Number of licensed seats. | 25 |
| employee_count | number | Company headcount. | 120 |
| industry | string | Industry or vertical. | SaaS |
| country | string | Account country. | United States |
| created_at | date | When the account was created. | 2025-11-02 |
| trial_ends_at | date | When the account trial expires. | 2026-07-01 |
| renewal_date | date | Next renewal date. | 2027-01-01 |
| owner_emailPII | Account owner email. | owner@atlas.example.com |
order
| Field | Type | Description | Example |
|---|---|---|---|
| id | string | Order id or number. | ord_1009 |
| total | number | Order grand total. | 129.99 |
| subtotal | number | Order subtotal before tax/shipping. | 119.99 |
| tax | number | Tax amount. | 10.00 |
| shipping | number | Shipping cost. | 5.00 |
| discount | number | Discount amount applied. | 15.00 |
| cost | number | Order-level cost of goods (COGS) — optional. Send when you know the order's total cost but not per-item cost. Apex computes gross profit = net revenue − cost. Opt-in; never inferred. | 62.00 |
| currency | string | ISO 4217 currency code. | USD |
| status | string | Order / fulfillment status. | shipped |
| item_count | number | Number of line items. | 3 |
| coupon_code | string | Coupon / promo code used. | SPRING20 |
| payment_method | string | Payment method. | card |
| created_at | date | When the order was placed. | 2026-05-20 |
product
| Field | Type | Description | Example |
|---|---|---|---|
| id | string | Product id. | prod_77 |
| name | string | Product name. | Atlas Trail Runner |
| sku | string | Stock-keeping unit. | ATR-42 |
| brand | string | Brand or vendor. | Atlas |
| price | number | Unit price. | 129.99 |
| unit_cost | number | Per-unit cost of goods (COGS) — optional. When sent on purchase line items, Apex computes true gross profit (net revenue − cost × quantity) and unlocks exact gross-profit LTV:CAC. Opt-in; never inferred or defaulted. | 48.50 |
| currency | string | ISO 4217 currency code. | USD |
| category | string | Product category. | footwear |
| variant | string | Variant / option. | size-10 |
| quantity | number | Quantity. | 1 |
| image_url | url | Product image URL. | |
| product_url | url | Product page URL. |
Extend + build on the Spec
The Spec is the global contract — but you can extend it, get type-safe SDKs from it, and rely on it to validate your data.
Define your own events
When your business has an event the Spec doesn't cover, govern it: Settings → Workspace → Schema → Custom events, or ask your agent (the define_event MCP tool). A governed event is typed and versioned (SchemaVer model-revision-addition), behaves like a canonical event (trigger/goal-selectable, token-resolvable, validated at ingest), and can be scoped to one workspace or shared across your org. A custom name can never shadow a canonical Spec event.
Type-safe tracking
The TypeScript SDK ships a generated payload map so wrong payloads fail to compile:
import type { ApexEventPayloads } from "@apex-inc/sdk/generated/event-payloads";
const order: ApexEventPayloads["order_placed"] = {
order_id: "ord_123",
value: 129.99, // required — the money-truth lane needs the amount
currency: "USD",
};Validation rules
Spec fields can declare constraints — allowed-value enums, regex patterns, numeric bounds, and formats (e.g. currency must be ISO-4217). At ingest, payloads that violate a constraint are quarantined (or rejected in strict mode), so bad data is caught at the door instead of corrupting reports downstream.