Event Schema Templates: 12 Core Properties Every SaaS Should Track

The 12 properties every SaaS event should fire with — copy-paste tracking plan template included. Built for lifecycle, not just analytics.

Event Schema Templates: 12 Core Properties Every SaaS Should Track

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.

TL;DR

  • Twelve base properties on every event give the lifecycle team a working foundation for triggers, segments, and attribution.
  • The 12 break into three groups: identity (4), context (4), and user state (4).
  • Most schemas miss account_id, signup_date, days_since_signup, and referrer_source — the user-state properties that make segmentation easy.
  • The template below is copy-paste-ready for Segment Protocols, Avo, or a Notion tracking plan.
  • AI Decisioning in Customer.io improves substantially when these properties are reliably present, because the model has more behavioral context per profile.

The 12 properties

Identity (4)

  1. user_id — authenticated user identifier, generated server-side at signup. Never changes for the life of the account.
  2. anonymous_id — pre-signup identifier, generated client-side and persisted via cookie or device storage. Used for stitching pre-signup behavior to the authenticated profile.
  3. account_id — for B2B, the workspace or organization the user belongs to. For B2C with no account concept, this can be null.
  4. session_id — current session identifier, regenerated on idle timeout (typically 30 minutes).

Context (4)

  1. timestamp — UTC, millisecond precision, source-emitted at the moment the event occurred. Not the time the server received the event.
  2. event_id — unique per event, used for deduplication. UUID is the standard.
  3. app_version — semantic version of the app that emitted the event. Critical for diagnosing instrumentation regressions and bucketing users by feature availability.
  4. platform — web, ios, android, api, etc. Belongs in a property, not the event name.

User state (4)

  1. plan_tier — current subscription tier at the time of the event. Must be the value at the moment the event fired, not the current value.
  2. signup_date — date the user first authenticated, on every event. Persistent.
  3. days_since_signup — calculated, on every event. Equivalent to event_timestamp minus signup_date. Adding it as a stored property avoids joining at query time.
  4. referrer_source — how the user originally arrived (paid search, organic, referral, direct, etc.), persisted from first session.

Why these 12

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.

Event-specific properties: layer on top of the 12

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.

Implementation pattern

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.

What this enables in Customer.io

A complete property set unlocks specific campaign patterns that are difficult or impossible without it:

  • Cohort-based activation triggers. "Users in days 3-7 post-signup who came from paid search and have not activated" is one filter, not three joins.
  • Cross-platform behavior triggers. "Users who started on mobile but switched to web" requires platform on every event.
  • AI Decisioning with rich features. The model uses base properties as input features. More properties means better decisions about message, channel, and timing.
  • Account-level B2B campaigns. account_id is what makes the workspace-level message possible.

Without the 12, every one of these patterns requires custom engineering work or warehouse intermediation.

What to do next

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.

Key takeaways

  • Twelve base properties on every event: 4 identity, 4 context, 4 user state.
  • The user-state properties are the most commonly missed and the most valuable for segmentation.
  • Set them once in SDK initialization, layer event-specific properties on top.
  • A tracking plan template makes the schema enforceable.
  • Customer.io's AI Decisioning depends on these properties being reliably present.