Skip to content

Commit 3a18341

Browse files
Add onboarding & lifecycle emails handbook page (#17429)
* docs(handbook): add onboarding & lifecycle emails architecture page Document how our automated onboarding and lifecycle email flows are architected in Customer.io, aimed at product marketers. Covers the data → segments → campaigns → subscription-topics model, the core flows (Onboarding 8.0, long-running onboarding, beta onboarding, Startups & YC), the anatomy of a flow, conventions/rules of practice, and a playbook for launching a new product. Adds a nav entry under Marketing → Product marketing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(handbook): document segment-driven email personalization Add a section to the onboarding & lifecycle emails page explaining how segment membership is mirrored onto profile attributes via Attr sync campaigns, how the email Liquid reads those attributes to build personalized recommendations, and the steps to add a new product to the next-steps block. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(handbook): condense onboarding emails page; lead with actionable checklists Compress the mental-model/reference material into scannable tables (segment families, core flows), foreground the launch checklist and the add-a-product-to-recommendations runbook, and tighten throughout (~229 -> ~103 lines). Replace bare <product> placeholders with [product] for MDX safety. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 304b764 commit 3a18341

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: Onboarding and lifecycle emails
3+
sidebar: Handbook
4+
showTitle: true
5+
---
6+
7+
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.
8+
9+
> **Launching something, or want a second pair of eyes?** <TeamMember name="Joe Martin" photo /> owns customer comms — loop him in early.
10+
11+
This is about *marketing* onboarding (emails new users get automatically), not the Sales/CS [onboarding program](/handbook/onboarding/onboarding-program). For the underlying email setup — topics, unsubscribes, sending addresses — see [email marketing](/handbook/marketing/email-comms).
12+
13+
## How the system works
14+
15+
Four layers, stacked:
16+
17+
1. **Data** — events and attributes synced from PostHog (`user signed up`, `user showed product intent`, activation events).
18+
2. **Segments** — saved groups built from that data ("signed up but not activated", "interested in flags").
19+
3. **Campaigns** — the automated flows: *triggered* by data, *branched* by segments, and they *exit* people on conversion.
20+
4. **Subscription topics** — the consent category each campaign sends under ("Welcome emails", "Changelog updates").
21+
22+
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:
23+
24+
- **[Product intent](/handbook/growth/growth-engineering/product-intents)** — which product someone actually came for (primary, secondary, or basic), from the `user showed product intent` event.
25+
- **[Activation](/handbook/growth/growth-engineering/per-product-activation)** — whether they got value, defined per product by a qualifying event or set of events.
26+
27+
### Segments come in families
28+
29+
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.
30+
31+
| Family | Purpose |
32+
| --- | --- |
33+
| Hygiene / deliverability ("Unsubscribed", "Valid Email Address") | Protect deliverability — almost every flow excludes these |
34+
| Instance & geography ("All Cloud Users", "Self-hosted Users") | Who can be messaged, and how |
35+
| Lifecycle / recency ("New Signups", "Logged in last 30 days") | Where someone is in their journey |
36+
| ICP / role ("High ICP", "Org owners or admins") | Tailor by fit and seniority |
37+
| Product intent ("Primary Intent: Session Replay") | Route people to content for the product they care about |
38+
| Activation ("Activated – Replays") | Know who succeeded, so we stop nudging them |
39+
| Beta ("Beta Users – Error Tracking") | Follow up with beta participants |
40+
| Programs ("Startups & YC") | Power program-specific flows |
41+
42+
### The core flows
43+
44+
| Flow | Trigger | What it does | Goal |
45+
| --- | --- | --- | --- |
46+
| **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 |
47+
| **Long-running onboarding** | `user signed up` | Slower, spaced-out nurture over a longer window | Logs in again |
48+
| **Beta onboarding** | `$feature_enrollment_update` | One feedback email after someone joins *any* beta — you get this free for every beta | Activates a product |
49+
| **Startups & YC** | *enters a segment* | Program-specific content (credits, job board, integrations) | Activation |
50+
51+
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.)
52+
53+
## The personalized "next steps" block
54+
55+
Inside the onboarding emails is 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:
56+
57+
> **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.
58+
59+
| Attribute | Set when the person enters | Example |
60+
| --- | --- | --- |
61+
| `activated_[product]` | "Activated – [product]" | `"true"` |
62+
| `activated_mcp` | "Activated: MCP" | `"true"` |
63+
| `intent_primary_product` | "Primary Intent: [product]" | `"session_replay"` |
64+
| `intent_secondary_product` | "Secondary Intent: [product]" | `"feature_flags"` |
65+
66+
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 <TeamMember name="Joe Martin" photo /> for the current version).
67+
68+
> **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).
69+
70+
## Launching a new product: the checklist
71+
72+
Not every step applies to every launch, but this is the path of least surprise:
73+
74+
1. **Confirm intent + activation exist** (Growth Engineering owns these). Without them the system is blind — do this *before* public beta.
75+
2. **In beta, lean on what's there.** The beta flow already collects feedback for every opt-in, for free. Want more? Build a "Beta Users – [product]" segment and a small, single-purpose flow.
76+
3. **Decide: extend or build new.**
77+
- *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.
78+
- *Build a standalone flow* for a distinct audience or behavior — event trigger for "when X happens", segment trigger for "everyone who is X".
79+
4. **Build the segments** you need (intent, activation, plus any launch-specific audience).
80+
5. **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.
81+
6. **Add it to the personalized recommendations**, if it should appear there (see below).
82+
7. **Test, then launch** — preview and test-send every message, sanity-check the branches, move from draft to live, then watch conversion to activation.
83+
84+
### Adding a product to the personalized recommendations
85+
86+
1. **Source segments must exist** — an "Activated – [product]" segment and "Primary/Secondary Intent: [product]" segments (from step 1 above).
87+
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.
88+
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.
89+
4. **Test** against a profile with the new attributes set.
90+
91+
It's fiddly and easy to get subtly wrong (misaligned lists, or a campaign that wasn't backfilled) — loop in <TeamMember name="Joe Martin" photo /> rather than guessing.
92+
93+
## Rules of practice
94+
95+
- **Respect consent** — pick the right [subscription topic](/handbook/marketing/email-comms), and never email unsubscribed users.
96+
- **Always exit on conversion** — stop the moment someone activates.
97+
- **Set a real conversion goal** (almost always activation) so you can tell if the flow works.
98+
- **Keep message limits on** — people are in several flows at once.
99+
- **Prefer extending the main flow over rebuilding.**
100+
- **Name things clearly**, and check for an existing segment/campaign before creating a near-duplicate.
101+
- **Test before you launch.**
102+
103+
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 <TeamMember name="Joe Martin" photo /> first.

src/navs/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,10 @@ export const handbookSidebar = [
10941094
name: 'Email marketing',
10951095
url: '/handbook/marketing/email-comms',
10961096
},
1097+
{
1098+
name: 'Onboarding & lifecycle emails',
1099+
url: '/handbook/marketing/onboarding-and-lifecycle-emails',
1100+
},
10971101
{
10981102
name: 'In-app messaging',
10991103
url: '/handbook/marketing/in-app',

0 commit comments

Comments
 (0)