Amplitude learning guide
By the end of this chapter
  • You will know which fields a tracking plan row should contain.
  • You can set up a consistent naming convention.
  • You can build a loop that validates the plan before release and protects it after.

Why the plan comes first

In projects without discipline, the number of event names grows over time while the number of questions does not. The same action arrives under three names, each shows up separately in charts, and nobody knows which is right.

Distinct event names, month by month. sample data In the unplanned project every release adds new names (spelling variants, platform variants, test events). In the planned project the count only grows when a new question appears.

The plan loop

Every new event starts with a question and returns to the loop through monitoring Questionwhich decision? Planevent + properties DevelopmentSDK / API Validationtest project Releaseproduction key Monitoringunplanned events? back to the plan if wrong new question or unplanned data
Does an error found in validation fix the plan or the code? If the plan is wrong, go back to the plan; if the code is wrong, back to development. The plan always remains the single source of truth.

What a plan row contains

FieldExampleWhy it's needed
Event nameCheckout CompletedOne name on every platform
TriggerWhen the payment confirmation screen first appears, once per orderDeveloper and analyst mean the same moment
SourceServer (HTTP API), after the backend verifies paymentPrevents double counting
Event propertiesorder_id string, revenue number, currency string (ISO 4217)Type and format are fixed
User properties updatedorders_count add 1Prevents ordering mistakes
PlatformsiOS, Android, webA missing platform becomes visible
Question it servesCart-to-payment conversion, revenue analysisUnnecessary events get cut
Adjust counterpartEvent token abc123 (S2S)Consistency between the two tools is tracked

Naming convention

Which convention you choose matters less than choosing one. A common, readable choice: event names as Object + past-tense verb in Title Case (Product Viewed); property names in snake_case (product_id).

One action, three events

  • product_view (Android)
  • ProductView (iOS)
  • viewed product (web)
  • Product Viewed - Shoes, Product Viewed - Bags (category in the name)

One event, rich properties

  • Product Viewed on every platform
  • category: "shoes" as a property
  • Fixed value list: shoes, bags, accessories
  • Platform comes from the SDK automatically, not repeated in the name
Tip

The few-events, rich-properties principle also makes charts easier to build: "product views by category" is one breakdown on one chart. With one event per category, every new category means a code change and a new chart.

Example plan: an e-commerce app

EventTriggerSourceEvent propertiesUser property effect
Onboarding Step ViewedEach onboarding screen shownSDKstep_number number, step_name string–
Signup CompletedAccount createdSDKmethod stringsignup_date setOnce
Search PerformedSearch results listedSDKquery_length number, results_count number–
Product ViewedProduct detail screen openedSDKproduct_id, category, price number, source string–
Product Added to CartAdd to cart succeededSDKproduct_id, category, price, quantity–
Checkout StartedPayment screen openedSDKcart_value number, items_count number–
Checkout CompletedPayment verified on the backendHTTP APIorder_id, revenue, currency, payment_methodorders_count add 1
Push OpenedNotification tappedSDKcampaign_id string–
Subscription StartedFirst subscription verifiedHTTP APIplan, period, revenueplan set (before the event)
Subscription RenewedStore renewal notification receivedHTTP APIplan, period, revenue–

Properties like source (where the user came to the product from: search, home, push) make funnel and path analysis much stronger. The question to ask while writing the plan: "Along which dimensions will I want to split this event?"

Validation checklist

Before every new release, run these checks in the test project:

  • The event name matches the plan exactly (including case and spaces).
  • All properties arrive with the right types (numbers as numbers, booleans as booleans).
  • The event fires at the moment written in the plan and the expected number of times (one order, one event).
  • The user property update happens before or after the event as the plan says.
  • user_id is correct after login and is reset after logout.
  • Server events attach to the right user and are not double-counted on resend.
  • The production build uses the production API key and the test build the test key.
  • The Adjust counterpart of the same event also fires (where needed).

These boxes reset when the page reloads; copy them into your own checklist.

After release: governance

Unplanned data will still arrive: old versions, forgotten test events, typos. Amplitude's data management tools let you do four things with them:

ActionWhat it doesWhen
HideHides the event in the UI; data staysEvents no longer used but whose history should be kept
BlockStops processing this event in futureTest or broken events
Merge / transformShows different names as one event in analysisHistorical spelling variants like product_view and Product Viewed
Validate against the planFlags events and properties outside the planOngoing quality monitoring
Verify

The current names of these actions in Amplitude, which ones apply retroactively and which plan they are in can change. In particular, check whether "block" touches historical data before telling a client.

On the Adjust side

In Adjust, the event token list is already a natural tracking plan: you can't send an event without a token. In Amplitude you have to maintain that list yourself. The most practical way is to keep both tools' events in the same table: one column for the Amplitude name and properties, one for the Adjust token and parameters. That way an event added to one tool and forgotten in the other is visible immediately.

Exercise

Starting from a client's current Adjust event list, draft a tracking plan with the template above. Fill in the "question it serves" column for each event. Events where you can't fill that column may not be worth moving to Amplitude.