Concepts
Event taxonomy
The single source of truth for every event you fire and every property you attach. Without it, your tracking drifts.
A robust analytics implementation depends on one document: the event taxonomy. It's the single source of truth for every event you fire and every property you attach. Without it, your tracking drifts: events get added inconsistently, properties mean different things in different places, and nobody knows what's actually being tracked.
You don't need a taxonomy to install the SDK and capture page views. You need one the moment you start tracking custom events.
What a taxonomy contains
Think of it as a spreadsheet. Each row is one event. Each column captures one fact about that event:
| Column | What it answers |
|---|---|
| Event name | The exact name fired in code (e.g., Sign-up completed) |
| Trigger | When exactly this event fires (e.g., "when the server returns 200 on the sign-up endpoint") |
| Event properties | What context is attached (e.g., method, referral_source) |
| User properties | Which properties get set/updated when this event fires |
| Source | Whether this fires client-side or server-side |
If you want it more elaborate, you can add columns for owner, status (active/deprecated), example payload, or notes. But the five above are the non-negotiable minimum.
Example row
| Field | Value |
|---|---|
| Event name | Sign-up completed |
| Trigger | Fires when the user successfully completes registration and a new account record is created in the database. |
| Event properties | method ("Email", "Google", "SSO"), referral_source ("Friend", "Ads") |
| User properties | Set: email, customer_id, account_type · Set once: initial_signup_date |
| Source | Server |
The trigger description is the most important field. Vague triggers ("when the user signs up") lead to ambiguous implementations. Precise triggers ("when the server confirms the account was created") make the event unambiguous to implement and to interpret later.
Why this matters
Without a taxonomy, three things go wrong.
Duplicate events. One developer ships user_signup. Six months later, someone else adds Signed Up for a different surface. A third developer creates UserSignedUp in the mobile app. Now you have three events that may or may not represent the same thing, and anyone analyzing the data has to investigate which is which.
Property drift. The plan_type property might mean "pro" in one event and "Pro" in another, or "premium" in a third. Filters in Amplitude become a guessing game.
Trigger ambiguity. Was Trial started fired when the user clicked the button, or when the trial actually started in the database? If you don't know, you don't know what your conversion rate measures.
The taxonomy isn't bureaucracy. It's the contract between the people defining events and the people implementing them.
Tools for managing it
A shared spreadsheet (Google Sheets, Notion table, Airtable) works fine for most teams. It's editable by non-engineers, easy to share, and obvious to maintain.
If you want more rigor:
- Amplitude Data (called "tracking plan" in the UI) lets you define your taxonomy inside Amplitude itself. Events and properties not on the plan can be flagged or blocked. Useful if you have a large team and need enforcement.
- Ampli is Amplitude's CLI tool that generates a type-safe tracking library from your plan. Your code calls
ampli.signUpCompleted({ method: "email" })instead oftrack("Sign-up completed", { method: "email" }), catching typos at compile time. Worth it if you have a stable taxonomy and want compile-time guarantees.
Either of these is overkill for an early-stage SaaS. Start with a spreadsheet. Move to a managed tool when you have more than ten engineers touching tracking code or when drift becomes a recurring problem.
When to update the taxonomy
Update it before you implement, not after. The flow:
- Someone proposes a new event ("we should track when users export their data")
- The proposal goes into the taxonomy as a draft row: name, trigger, properties, source
- The team reviews — does the name match conventions? Are the properties right? Does this duplicate an existing event?
- Once agreed, the event gets implemented to match the row exactly
- The row moves from draft to active
If the taxonomy gets edited after implementation, drift creeps in. If implementation happens before the taxonomy is updated, you've got an event in production that nobody can explain.
What goes in the taxonomy
Only events you control. The auto-captured events your SDK fires (page views, sessions) don't strictly need to be in the taxonomy — you don't control their trigger logic. Focus the taxonomy on the custom events you're building.
That said, if your team includes non-engineers who'll be analyzing data, listing the auto-captured events in a separate tab is helpful as reference.