The 12 properties every SaaS event should fire with — copy-paste tracking plan template included. Built for lifecycle, not just analytics.
.png)
Every event in a lifecycle-grade schema should fire with a base set of 12 properties, on top of whatever event-specific properties it carries. These 12 are the foundation that makes cross-event analysis, cross-event triggering, and cross-platform identity resolution possible. Most schemas have four or five of them. The gap between a working schema and a struggling one is usually the missing seven.
Identity (4)
Context (4)
User state (4)
Identity properties make cross-device, cross-channel orchestration possible. Without account_id, B2B segmentation collapses. Without anonymous_id propagated post-authentication, pre-signup behavior is orphaned.
Context properties make the event auditable. event_id lets the data team detect duplicate events from misbehaving SDKs. app_version lets the lifecycle team isolate users on the latest version when shipping a new trigger. platform is what lets you ask whether the welcome flow performs differently on mobile versus web.
User-state properties are the ones most schemas miss. They are not properties of any single event — they are properties of the user that ride along on every event. Without them, every segment definition becomes a join. With them, a campaign that targets "users 3-7 days post-signup who came from paid search and have not activated" is a one-line filter in Customer.io.
The 12 are the base. Every event also carries event-specific properties that describe what happened. For feature_activated, those might include feature_name, time_to_activate_seconds, and activation_path (the sequence of steps that led to activation). For subscription_upgraded, they might include from_tier, to_tier, upgrade_reason, and mrr_change.
The pattern: the 12 fire on every event automatically (set up once in the SDK initialization). Event-specific properties are passed in the event call.
For a Segment-based stack feeding Customer.io, the implementation is: an identify call at signup sets the persistent user-state properties (account_id, signup_date, plan_tier, referrer_source). Subsequent track calls inherit them automatically. The track call passes only event-specific properties. Customer.io receives both the event and the full property context, and any campaign trigger can filter on any combination of base and event-specific properties.
For platforms that do not have this default-property pattern (some custom instrumentation, some legacy setups), the 12 have to be passed explicitly on every event call. Tedious, but the alternative — missing properties — is worse.
A complete property set unlocks specific campaign patterns that are difficult or impossible without it:
Without the 12, every one of these patterns requires custom engineering work or warehouse intermediation.
If you are starting a new schema, build it with the 12 from day one. If you have an existing schema, audit which of the 12 are present on which events. The gaps are your fix list.
The lifecycle program built on a schema with all 12 ships campaigns in days. The lifecycle program built on a schema missing four of them ships campaigns in weeks and ships them buggy.