|
| 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. |
0 commit comments