PostHog Handbook Library / Marketing

1,606 words. Estimated reading time: 8 min.

# Onboarding and lifecycle emails

Auto TL;DR

## At a Glance

This long page covers these main areas. The list is generated from the article headings, so it updates with every handbook rebuild.

1. How the system works
2. Segments come in families
3. The core flows
4. The Waitlist, Alpha, Beta onboarding flow
5. The personalized "next steps" block
6. Launching a new product: the checklist
7. Adding a product to the personalized recommendations
8. Rules of practice

How PostHog's automated onboarding and lifecycle emails work in Customer.io, and what to do when you launch a new product. Aimed at product marketers. These are the patterns we use today — conventions, not hard rules. Build something new when a launch calls for it.

> Launching something, or want a second pair of eyes? Joe Martin owns customer comms — loop him in early.

This is about marketing onboarding (emails new users get automatically), not the Sales/CS onboarding program. For the underlying email setup — topics, unsubscribes, sending addresses — see email marketing.

### How the system works

Four layers, stacked:

1. Data — events and attributes synced from PostHog (`user signed up`, `user showed product intent`, activation events).
2. Segments — saved groups built from that data ("signed up but not activated", "interested in flags").
3. Campaigns — the automated flows: triggered by data, branched by segments, and they exit people on conversion.
4. Subscription topics — the consent category each campaign sends under ("Welcome emails", "Changelog updates").

Two data concepts drive most of the logic, and both are owned by Growth Engineering — so if they don't exist for your product yet, that's step one:

- Product intent — which product someone actually came for (primary, secondary, or basic), from the `user showed product intent` event.
- Activation — whether they got value, defined per product by a qualifying event or set of events.

#### Segments come in families

There are hundreds; you only need the families. Before building one, check it doesn't already exist — duplicates are the biggest source of mess. Prefer dynamic (auto-updating) over static lists.

| Family | Purpose | | --- | --- | | Hygiene / deliverability ("Unsubscribed", "Valid Email Address") | Protect deliverability — almost every flow excludes these | | Instance & geography ("All Cloud Users", "Self-hosted Users") | Who can be messaged, and how | | Lifecycle / recency ("New Signups", "Logged in last 30 days") | Where someone is in their journey | | ICP / role ("High ICP", "Org owners or admins") | Tailor by fit and seniority | | Product intent ("Primary Intent: Session Replay") | Route people to content for the product they care about | | Activation ("Activated – Replays") | Know who succeeded, so we stop nudging them | | Beta ("Beta Users – Error Tracking") | Follow up with beta participants | | Programs ("Startups & YC") | Power program-specific flows |

#### The core flows

| Flow | Trigger | What it does | Goal | | --- | --- | --- | --- | | Onboarding 8.0 (flagship) | `user signed up` | 130+ emails that branch on product intent and behavior to tailor the first-run experience | Activate within 7 days | | Long-running onboarding | `user signed up` | Slower, spaced-out nurture over a longer window | Logs in again | | Waitlist, Alpha, Beta onboarding | `$feature_enrollment_update` | Branches on `$feature_enrollment_stage`: waitlist confirmation (concept), rough-edges warning (alpha), or a feedback ask after 5 days (beta) — you get this free for every early access feature | Collects feedback, activates a product | | Startups & YC | enters a segment | Program-specific content (credits, job board, integrations) | Activation |

The idea behind the flagship: it's intent-aware and activation-aware — it sends people content about the product they came for, and exits the moment they activate. (Avoid Customer.io's legacy "behavioral" campaign type for anything new — it silently excludes existing and backfilled people.)

### The Waitlist, Alpha, Beta onboarding flow

Every early access feature gets lifecycle emails automatically. When someone joins a waitlist or opts in to a feature preview — in the app, or via a waitlist form on posthog.com — posthog-js fires a `$feature_enrollment_update` event carrying `$early_access_feature_name` and `$feature_enrollment_stage`. These events reach Customer.io through the "Send events to Customer.io" data pipeline destination, and any `$feature_enrollment_update` with both properties present triggers the flow.

The flow immediately segments on `$feature_enrollment_stage`:

- `concept` — an immediate, simple confirmation that they're on the waitlist.
- `alpha` — an immediate email warning of rough edges and asking for feedback.
- `beta` — a 5-day wait, then an email asking for feedback on the beta.

When a feature's stage changes from `concept` to `alpha` or `beta`, everyone who registered interest is automatically opted in to the new stage and PostHog fires a `user moved feature preview stage` event (with `from` and `to` properties) for each enrolled person. When `from` is `concept` and `to` is `alpha` or `beta`, we send an email letting them know the feature is enabled and now available, and asking for feedback.

All beta feedback is centralized to the `beta-feedback@posthog.com` Google Group. Replies to this address are relayed into the #posthog-feedback Slack channel for everyone to see. PMs and team leads are encouraged to respond to and action this feedback for their alpha and beta releases, and to give merch credits as a thank you where appropriate.

### The personalized "next steps" block

Inside the onboarding emails is an email with a block that recommends each person's best next product, based on what they've already activated and shown intent in. One quirk shapes how it's built: Customer.io's Liquid can't read segments or event history — inside an email you only get the person's profile attributes. So we copy segment membership onto attributes first:

> Segments → "Attr sync" campaigns → attributes → email content. For each Activated/Intent segment, a tiny `seg_attr` campaign fires when someone enters it and runs one Update attributes action — no email, it just writes data. They share an `Attr sync` name prefix so they group together.

| Attribute | Set when the person enters | Example | | --- | --- | --- | | `activated_[product]` | "Activated – [product]" | `"true"` | | `activated_mcp` | "Activated: MCP" | `"true"` | | `intent_primary_product` | "Primary Intent: [product]" | `"session_replay"` | | `intent_secondary_product` | "Secondary Intent: [product]" | `"feature_flags"` |

The email's Liquid reads these to pick the person's top un-activated product (biased toward their primary, then secondary intent) and personalizes the bullets, subject line, headline, CTA, and a closing "ask PostHog AI this" prompt — all tied to that same product. The editable copy lives in aligned lists at the top of the snippet, which lives in the email in Customer.io (ask Joe Martin for the current version).

> If you edit the Liquid: variables are per-block (include the logic in every block/field that uses it — including the subject), and use single quotes only (code blocks HTML-encode double quotes and break Liquid).

### Launching a new product: the checklist

Not every step applies to every launch, but this is the path of least surprise:

1. Confirm intent + activation exist (Growth Engineering owns these). Without them the system is blind — do this before public beta.
2. In beta, lean on what's there. The Waitlist, Alpha, Beta onboarding flow already collects feedback for every opt-in, for free. Want more? Build a "Beta Users – [product]" segment and a small, single-purpose flow.
3. Decide: extend or build new.

- Extend Onboarding 8.0 for a core product — add your intent branch and a few product emails to the main flow. Usually the right call.
- Build a standalone flow for a distinct audience or behavior — event trigger for "when X happens", segment trigger for "everyone who is X".

1. Build the segments you need (intent, activation, plus any launch-specific audience).
2. Wire up the flow — trigger, entry filters, delays and send windows, branches, a real conversion goal, exit-on-conversion, subscription topic, and keep message limits on.
3. Add it to the personalized recommendations, if it should appear there (see below).
4. Test, then launch — preview and test-send every message, sanity-check the branches, move from draft to live, then watch conversion to activation.

#### Adding a product to the personalized recommendations

1. Source segments must exist — an "Activated – [product]" segment and "Primary/Secondary Intent: [product]" segments (from step 1 above).
2. Create the "Attr sync" campaigns — one `seg_attr` campaign per segment that sets the attribute (`activated_[product] = "true"`, or `intent_primary_product = "[product]"`). Launch each with backfill so people already in the segment get the attribute, not just new entrants.
3. Add the product to the snippet — its key, display name, app URL, and recommendation sentence to the aligned lists (keep them the same length and order), its `activated_[product]` check, and its PostHog AI question.
4. Test against a profile with the new attributes set.

It's fiddly and easy to get subtly wrong (misaligned lists, or a campaign that wasn't backfilled) — loop in Joe Martin rather than guessing.

### Rules of practice

- Respect consent — pick the right subscription topic, and never email unsubscribed users.
- Always exit on conversion — stop the moment someone activates.
- Set a real conversion goal (almost always activation) so you can tell if the flow works.
- Keep message limits on — people are in several flows at once.
- Prefer extending the main flow over rebuilding.
- Name things clearly, and check for an existing segment/campaign before creating a near-duplicate.
- Test before you launch.

These are conventions, not a cage — launches often need something the structure doesn't quite cover, and that's expected. For anything substantial (a new flow, a big change to the main campaign), talk to Joe Martin first.

Canonical URL: https://posthog.com/handbook/marketing/onboarding-and-lifecycle-emails

GitHub source: contents/handbook/marketing/onboarding-and-lifecycle-emails.md

Content hash: `916352d650052615`

Static reader notes

- `MDX_COMPONENT_STATIC_ADAPTER`: Adapted interactive MDX components for static reading: TeamMember.