Custom events
Track anything that isn't a pageview — clicks, signups, downloads, plan changes.
Anatomy of an event
Every event has three parts:
- Type — almost always
eventfor custom events. The other types (pageview,identify,conversion) are handled by dedicated calls. - Name — a short stable string. Use snake_case (
signup,add_to_cart,video_play). Names are case-sensitive; don't mixSignupwithsignup. - Properties — optional bag of up to 50 key/value pairs. Values can be strings, numbers, or booleans.
From the browser
window.oa('event', 'signup', {
plan: 'pro',
source: 'pricing_page'
});
window.oa('event', 'add_to_cart', {
product_id: 'sku_123',
price: 29.99,
quantity: 1
});
From your backend
Use the REST API; see the Server-side tracking guide for PHP and Node.js examples.
Identify users
identify links the current anonymous user to a stable identifier (typically your internal user ID). All future events from this user across sessions and devices will be associated together.
window.oa('identify', 'user_42', { plan: 'pro' });
Hash or pseudonymize the identifier before sending. Do not send raw emails or any data that would let a third party identify the user without your DB.
Naming guidelines
- Verb + noun:
add_to_cart,open_modal,complete_signup. - One event name per concept. Use properties for variations:
video_playwith{quality:'1080p'}beatsvideo_play_1080p. - Keep the cardinality of names low. Hundreds of distinct names is fine; thousands gets unwieldy.
- Avoid PII in event names or property keys — names appear in dashboards and exports.
Quota
Every event call counts toward your monthly event quota. Pageviews, custom events, identify calls, conversions, and server-side events all count equally. Session start/end and replay chunks do not count.