Event naming guide
An AI tool reads your events and answers questions about them, so event names are the vocabulary it works with. Consistent names give precise answers.
The rules
- Object first, then action:
report_exported, notexported_report. - Lowercase snake_case only: no spaces, capitals, dots or dashes.
- Past tense, because it has happened:
invite_sent, notsend_invite. - One name per thing on web, mobile and backend.
- Describe what the user did, not the UI:
plan_upgraded, notblue_button_clicked. - Put the variation in properties, not in the name.
Good and bad names
| Instead of | Use | Why |
|---|---|---|
SignupCompleted |
signup_completed |
One casing everywhere |
clicked export button |
report_exported |
The outcome, not the click |
export_pdf, export_csv |
report_exported with a format property |
One event, variation as a property |
signup |
signup_started, signup_completed |
Say which step |
ios_app_opened |
app_opened with a platform property |
Platform is a property |
An event name is 1 to 128 characters.
Properties
Properties carry the detail that lets one event answer many questions. They are the properties object of the event. Use the same name across events, keep each one the same type every time, keep them flat, and put units in the name when they are not obvious (duration_ms, amount_eur).
Do not send personal data you do not need: no names, email addresses, phone numbers, free text, passwords or tokens.
Users and identity
Send the same user_id for the same person from every platform, and make it an id that never changes: your database id, not an email. Send a session_id with the events of one visit or app session: it is optional, and it is what groups a visit's events together, so it is recommended.
For visitors who are not signed in, send an anonymous_id property, and send both ids on the signup event. For B2B products, add an account_id property to every event.
Starter tracking plan
| Event | When it fires | Key properties |
|---|---|---|
signup_started |
The signup form is opened | source |
signup_completed |
The account is created | source, method |
onboarding_completed |
The last onboarding step is done | duration_ms |
project_created |
The user creates a project | template |
invite_sent |
The user invites teammates | count |
report_exported |
A core output is produced | format |
plan_upgraded |
The plan changes upward | from, to |
subscription_cancelled |
The subscription is cancelled | reason |
Changing events
Never rename an event in place: history under the old name stops matching questions asked with the new one. To rename, send both names for one release, then stop sending the old one. To change what an event means, give it a new name.
Prompt for your coding agent
Paste this into Claude Code, Cursor or Codex in your product's repository.
Add Tuumo event tracking to this codebase.
- Send one event per request with POST https://api.tuumo.fi/v1/events,
authenticated with the TUUMO_KEY environment variable.
Never hard-code the key.
- Each event has a name. Send a session_id too when the request or
app session has one.
- Create one small tracking module and call it everywhere.
- Name events object_action in snake_case and past tense.
- Start with signup_started, signup_completed and the five most
important user actions you can find in this product.
- Retry 408, 429 and 503 responses, after the Retry-After seconds
when there is one. Stop sending on 402, and do not retry 400, 401
or 413.
- Write the final list to docs/tracking-plan.md.
Full reference: https://docs.tuumo.fi/llms.txt