checkout_started · plan=projust nowcheckout_started · plan=team3s agocheckout_started · plan=pro11s agocheckout_started · plan=free24s ago// events
Autocapture covers the basics the moment you install an SDK. Then you add the handful of events that describe your product, with typed properties you can slice on for years.
acme-production · eventsStreamingtrack('checkout_started', { plan: 'pro', billing_period: 'annual', amount_cents: 27600, currency: 'usd'})signup_completedjust nowemail_verified2s agoproject_created5s agocheckout_started8s agopurchase_completed12s agoerror_occurred17s agoThe two are not a choice. Autocapture fills the dashboard on day one; explicit events are what you build funnels and answers on six months later.
Page views, screen views, sessions, clicks on anything with a stable selector, and basic device and source context — all captured from the two lines that install the SDK. You get traffic, retention and source breakdowns before you have written a single custom event.
It is a switch, not a trap. Turn autocapture off per SDK, or block individual selectors and paths, and nothing is sent.
import { init } from '@alitycs/browser'init({ apiKey: 'pk_live_…', autocapture: true, maskSelectors: ['.pii']})One call, one event, whatever properties describe it. Numbers stay numbers, so you can sum revenue and take a median without casting; strings become breakdown dimensions automatically.
Types are inferred the first time a property is seen and then enforced. If a release starts sending amount_cents as a string, the schema view flags the conflict instead of quietly coercing it and ruining the chart.
Server-side calls work the same way — same event names, same properties, one user identity across web, mobile and backend.
track('checkout_started', { plan: 'pro', billing_period: 'annual', amount_cents: 27600, currency: 'usd', seats: 12})An event name tells you something happened. Properties tell you who, on what, for how much — and that is what every question you will ask later is actually about.
A name, an identity, a timestamp, and a flat bag of properties. Nothing else is required, and nothing else is inferred behind your back.
Name events after what happened, not where the click was: checkout_started, never pricing_page_cta_click. Use lower snake case, an object followed by a past-tense verb, and push the variable part into a property — one checkout_started with a plan property beats four events named after each plan.
Ten well-named events will answer more questions than two hundred accidental ones, and you only have to agree on them once.
{ "event": "checkout_started", "user_id": "u_8f21c4", "timestamp": "2026-08-04T09:12:41Z", "properties": { "plan": "pro", "amount_cents": 27600, "seats": 12 }}These eight cover signup, activation and revenue for almost every product. Instrument them first, in this order, and the funnels build themselves.
| Event | Send it when | Key properties |
|---|---|---|
signup_completed | The moment the account exists, before any onboarding screen | source, referrer, plan |
email_verified | When the verification link is used, not when it is sent | hours_since_signup |
project_created | The first real object a user makes in your product | project_id, template |
teammate_invited | Invite sent — track acceptance as its own event | role, invite_count |
activated | Your own definition of value delivered, decided once and written down | days_since_signup, path |
checkout_started | Plan picker submitted, before the payment processor takes over | plan, billing_period, currency |
purchase_completed | Payment confirmed by the processor, sent from your server | plan, amount, currency |
error_occurred | Any failure a user can see, including handled ones | code, screen, sdk_version |
Tying those events to real accounts is a separate, one-line job — see identifying users.
The slowest part of instrumentation is usually finding out whether it worked. The live stream removes that wait entirely.
Open the events tab, filter to the event name you just shipped, and watch it arrive. Each row expands into the full payload — every property, the resolved user, the SDK and version that sent it, and the exact time it was received.
Filter by any property while the stream is running, so you can confirm not just that the event fires but that it fires with the right values. Add debug: true to the SDK init and events are tagged as debug traffic, visible in the stream but excluded from reports.
If nothing shows up, the troubleshooting guide walks the four usual causes in order.
checkout_started · plan=projust nowcheckout_started · plan=team3s agocheckout_started · plan=pro11s agocheckout_started · plan=free24s agoOne meter: events ingested per month. Retention is how far back you can query them, and it is generous enough to see a year-long cohort on a startup budget.
| Plan | Included volume | Retention | Live stream history | Above the cap |
|---|---|---|---|---|
| Free | 1M events / month | 30 days | Last 24 hours | Storage stops at the cap until the next period |
| Pro | 10M events / month | 12 months | Last 7 days | $3 per additional million |
| Team | 50M events / month | 24 months | Last 30 days | $3 per additional million |
| Enterprise | Custom volume | Custom, up to 7 years | Custom | Committed volume, invoiced annually |
Plan prices and the full comparison live on the pricing page.
Three short reads that cover everything between installing an SDK and having a schema your team can rely on.
Naming rules, property types, batching, and the mistakes that are expensive to undo later.
Read the tracking guideTie anonymous activity to a real account at signup without losing the sessions that came before it.
Read the identity guideBrowser, iOS, Android, Node, Python, Go and the plain HTTP API — with install snippets for each.
Browse the SDKsInstall the SDK, send a single track() call, and the live stream will show it within seconds.
1M events a month on the free plan, no credit card.