apex-spec v1.5.0

The Apex Spec

The event vocabulary your app fires through the snippet or SDK. Templates, journeys, and conversions read these names. Fireuser_signed_up when a person creates an account,waitlist_joined when they join a waitlist.

Your app

Events

119 declared

What your customer-facing app fires. Commerce, identity, engagement, communication — the vocabulary you stand up day one.

apex.track('user_signed_up', { method, referrer })

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_completed is 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 when order_placed exists.

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 metric

User 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 metric

User began the checkout flow.

value
number
259.98
currency
string
USD
item_count
number
2
cart_id
string
cart_9f2e1a

checkout_completed

Primary metric

Client-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
products
array
items
array
cart_id
string
cost
number
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 metric

Revenue 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
products
array
items
array
is_restored
boolean
false
cost
number
subtotal
number
total
number
tax
number
shipping
number
handling
number
discount
number
coupon
string
account_id
string

purchase_refunded

Primary metric

A 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 metric

Subscription 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 metric

A 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 metric

A 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 metric

A 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 metric

A 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 metric

An 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
products
array
cost
number
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_expiring

Primary metric

A trial is about to end (Stripe-style trial_will_end). Distinct from trial_expired, which fires after.

plan
string
atlas_pro
days_remaining
number
3
value_summary
string
built real momentum

trial_expired

Primary metric

A trial ended without converting (distinct from trial_expiring, which fires BEFORE).

plan
string
atlas_pro

invoice_paid

Primary metric

An 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 metric

A 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 metric

A 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

Templates

subscription_downgraded

Primary metric

A 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, waitlist, invite, sign-in, and identity stitching.

user_invited

Someone invited a person to join.

inviter_name
string
Sarah Chen
invitee_email
string
alex@example.com
role
string
admin
accept_url
string
https://app.example.com/invite/accept

Where this is used

password_reset_requested

A person requested a password reset.

email
string
ada@acme.com
reset_url
string

Where this is used

user_signed_in

User authenticated into the app.

method
string
email

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

Primary metric

First install of the app on this device.

No payload fields required.

app_open

Primary metric

App 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 metric

A customer churned (lapsed/cancelled past the win-back window). Drives win-back.

reason
string
stopped_using

user_reactivated

Primary metric

A 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_view

Legacy 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
twitter

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

A click the snippet or SDK recorded. Prefer `ui_action` when you know the control's name. The snippet auto-fires this for outbound links.

target
string
button#hero-cta
href
string
https://partners.example.com/apply
text
string
Apply now

ui_action

A named in-product control was used. One event for buttons, tabs, nav, widget chrome — distinguish with `action`, `element_type`, `name`, and `location`. Do not invent a new event per button.

action*
string
click
element_type
string
button
name*
string
Wire it in Cursor
location
string
setup.experiments
href
string

engagement

End-of-page composite: time on page and max scroll depth. Auto-fired by the web snippet on hide. Prefer `ui_action` / `page_view` for a readable journey.

duration
number
42
scroll_depth
number
75

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

A click that produced no observable effect after a short wait (no URL change, no mutation on the clicked node). Frustration signal. Not a click on a table row that then navigates.

selector
string
div.banner-image
text
string
Decorative hero
x
number
y
number

goal_conversion

Primary metric

User completed a defined conversion goal.

goal_id*
string
demo_booked
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

Where this is used

feature_used

User used a specific product feature. Powers expansion + adoption comms.

feature_name*
string
advanced_reports
count
number
1

webinar_registered

Primary metric

User 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 metric

User 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 metric

User 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 metric

A 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 metric

A 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 metric

An 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

report_ready

A report is ready. Distinct from report_viewed, which is the person opening it.

report_type
string
Monthly performance
report_id
string
rpt_8821
period
string
May 2026
highlights
string
revenue up 12%

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

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

Smart banner

Apex smart banner impressions, clicks, dismissals.

smart_banner_impression

Apex smart banner was shown on a mobile web page.

No payload fields required.

smart_banner_click

User clicked the smart banner CTA.

No payload fields required.

smart_banner_dismiss

User dismissed the smart banner.

No payload fields required.

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)

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

FieldTypeDescriptionExample
idstringStable end-user id passed to apex.identify().u_8c21
emailPIIemailEnd-user email. Required for transactional sends.alex@example.com
email_verifiedbooleanWhether the email has been confirmed.true
first_namestringGiven name. Use in greetings.Alex
last_namestringFamily name.Rivera
full_namestringFull display name.Alex Rivera
usernamestringHandle or login.arivera
phonePIIstringPhone number in E.164 where possible.+14155550100
avatar_urlurlProfile image URL.
titlestringJob title or role.Head of Growth
companystringCompany the user belongs to.Atlas
genderstringSelf-reported gender.
birthdayPIIdateDate of birth.1990-04-12
address_line1PIIstringStreet address line 1.1 Market St
address_line2PIIstringStreet address line 2.Suite 400
citystringCity.San Francisco
regionstringState or province.California
postal_codePIIstringPostal / ZIP code.94105
countrystringCountry display name.United States
country_codestringISO 3166-1 alpha-2 country code.US
latitudePIInumberGeo latitude.37.7749
longitudePIInumberGeo longitude.-122.4194
timezonestringIANA timezone.America/Los_Angeles
localestringLocale or language.en-US
created_atdateWhen the user account was created.2026-01-15
last_seen_atdateMost recent activity timestamp.2026-06-01
planstringSubscription plan or tier.pro
subscription_statusstringBilling/subscription status.active
lifecycle_stagestringMerchant-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_atdateWhen the user's trial expires.2026-07-01
lifetime_valuenumberTotal revenue from this user.480
marketing_opt_inbooleanMarketing email consent.true
referrerstringAcquisition referrer.google
utm_sourcestringAcquisition UTM source.newsletter
utm_mediumstringAcquisition UTM medium.email
utm_campaignstringAcquisition UTM campaign.spring_launch
utm_termstringAcquisition UTM term.
utm_contentstringAcquisition UTM content.
marketplace_sidestringWhich side(s) of the marketplace this user is on: buyer, seller, or both.seller
is_sellerbooleanTrue when the user sells on the marketplace.true
is_buyerbooleanTrue when the user buys on the marketplace.true
store_namestringThe seller's storefront display name.Atlas Outfitters
seller_idstringThe marketplace's stable seller identifier.sel_4821
payout_methodstringHow the seller receives payouts. One of: stripe, paypal, bank_transfer, other — never account details.stripe

account

FieldTypeDescriptionExample
idstringStable account / org id.acct_42
namestringAccount or company name.Atlas Inc
websiteurlAccount website.https://atlas.example.com
domainstringEmail/company domain.atlas.example.com
planstringAccount plan or tier.enterprise
mrrnumberMonthly recurring revenue.2400
arrnumberAnnual recurring revenue.28800
seat_countnumberNumber of licensed seats.25
employee_countnumberCompany headcount.120
industrystringIndustry or vertical.SaaS
countrystringAccount country.United States
created_atdateWhen the account was created.2025-11-02
trial_ends_atdateWhen the account trial expires.2026-07-01
renewal_datedateNext renewal date.2027-01-01
owner_emailPIIemailAccount owner email.owner@atlas.example.com

order

FieldTypeDescriptionExample
idstringOrder id or number.ord_1009
totalnumberOrder grand total.129.99
subtotalnumberOrder subtotal before tax/shipping.119.99
taxnumberTax amount.10.00
shippingnumberShipping cost.5.00
discountnumberDiscount amount applied.15.00
costnumberOrder-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
currencystringISO 4217 currency code.USD
statusstringOrder / fulfillment status.shipped
item_countnumberNumber of line items.3
coupon_codestringCoupon / promo code used.SPRING20
payment_methodstringPayment method.card
created_atdateWhen the order was placed.2026-05-20

product

FieldTypeDescriptionExample
idstringProduct id.prod_77
namestringProduct name.Atlas Trail Runner
skustringStock-keeping unit.ATR-42
brandstringBrand or vendor.Atlas
pricenumberUnit price.129.99
unit_costnumberPer-unit cost of goods (COGS) — optional. Send it on EVERY line item of a purchase and Apex computes true gross profit (net revenue − cost × quantity) and reports LTGP:CAC alongside LTV:CAC. An order with an uncosted line is treated as cost-unknown rather than partially costed, so a half-instrumented catalog never inflates margins. Must be PER UNIT — Apex multiplies it by quantity. If you only know the total cost of the order, send `cost` at the order level instead. Opt-in; never inferred or defaulted.48.50
currencystringISO 4217 currency code.USD
categorystringProduct category.footwear
variantstringVariant / option.size-10
quantitynumberQuantity.1
image_urlurlProduct image URL.
product_urlurlProduct 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.

Already firing events with different names? Map them to canonical in your workspace \u2014 every Apex surface picks up the alias automatically.