MICROMARKETING Book Free Consult
← AI & Automation

Building Post-Purchase Funnels in PostHog With GPT-Assisted Labels

By August 16, 2026, PostHog has become a workable command center for post-purchase marketing because it can hold product events, Stripe revenue data, cohorts, surveys, and realtime exports in one place. That matters when you are buying Google Ads, publishing SEO pages, and sending lifecycle emails from Klaviyo or Customer.io on the same Tuesday. I […]

By August 16, 2026, PostHog has become a workable command center for post-purchase marketing because it can hold product events, Stripe revenue data, cohorts, surveys, and realtime exports in one place. That matters when you are buying Google Ads, publishing SEO pages, and sending lifecycle emails from Klaviyo or Customer.io on the same Tuesday.

I build these funnels for one blunt reason. The purchase event is not the finish line. For a $79/month SaaS plan, the money is usually made between payment day and day 30, when the buyer either gets value, invites a teammate, books a setup call, files a refund ticket, or disappears. For a Shopify store selling a $148 skincare bundle, the next useful event might be second_order_started within 42 days. Same shape. Different clock.

PostHog is good at this because its funnels can show conversion steps, time to convert, historical trends, breakdowns, and drop-offs. Its cohorts can group people by events or properties, then feed dashboards, surveys, feature flags, and experiments. The AI piece is not magic. GPT labels the messy middle so your funnel stops saying pageview, email_opened, session_recording_viewed, and starts saying needs onboarding, price anxious, integration blocked, or ready for expansion.

Start With Four Post-Purchase States

I try to keep the first version small. Four labels are enough for most teams doing under $250k/month in revenue: activated, stalled, support_risk, and expansion_signal.

A B2B example makes this less airy. In March 2026, a 14-person payroll startup I worked with had 1,842 trial-to-paid conversions in PostHog, 611 Stripe subscriptions on the $49 starter plan, and a day-30 logo retention rate sitting at 71%. Their checkout funnel looked fine. Their post-purchase path was mud. The biggest leak was not failed payments or bad ad targeting. Buyers paid, opened the app twice, never connected QuickBooks, and ignored three emails that all said some version of finish setup.

So we defined the states by behavior. activated meant subscription_created, then integration_connected, then first_report_generated within 7 days. stalled meant payment happened, but no key setup event after 72 hours. support_risk meant a buyer hit docs search 3 or more times, opened chat, or visited /billing/cancel. expansion_signal meant they invited 2 teammates, viewed the usage page, or crossed 80% of a plan limit.

PostHog’s funnel docs call out a useful detail here: step order can be sequential, strict, or any order. For post-purchase work, I use sequential for activation and any order for risk signals, because a frustrated customer will not follow your tidy lifecycle diagram.

Capture The Events Before Asking GPT For Labels

Bad labels come from thin events. Full stop.

For web apps, I want posthog-js on the front end and posthog-node on the server. As of the npm listings I checked on August 16, 2026, posthog-js showed version 1.409.5 and posthog-node showed version 5.46.0 on npm. Those numbers will move, but pinning a version in your notes saves future debugging when a teammate asks why autocapture behaved differently in April.

The minimum event set for a SaaS funnel is checkout_started, subscription_created, onboarding_started, integration_connected, first_value_action, invite_sent, upgrade_viewed, support_opened, and cancel_clicked. For ecommerce, I swap in order_completed, shipment_delivered, review_requested, review_submitted, subscription_offer_viewed, second_order_started, and return_started.

Attach the source data too. UTM source, campaign name, first landing page, SKU, plan, coupon code, Stripe customer ID, product category, and sales-assist owner all belong on the event or person profile. PostHog says cohorts depend on person properties, so identified events matter. Anonymous purchase blobs make weak segments later.

Tiny detail. Use boring names.

I have inherited funnels with events called Trial Converted, new_sub, paid_success, and stripe_checkout.session.completed in the same project. Nobody trusted the dashboard. Pick one event vocabulary, write it in a tracking-plan.md, and use actions in PostHog only when you need to group several raw events into the same marketing concept.

Bring Revenue And Campaign Context Into PostHog

Post-purchase funnels need money. A buyer who pays $19 once and a buyer who signs a $12,000 annual contract should not sit in the same nurture lane.

PostHog’s Data Warehouse supports Stripe, PostgreSQL, Snowflake, and BigQuery sources, and the Stripe path can create revenue views for lifetime value, revenue by cohort, and churn analysis. That is enough for a lean operator. You can join Stripe subscription status with product events, then ask a cleaner question: did users from google / pmax / integrations who bought the $149 plan create the first dashboard within 10 days?

For a founder running paid and organic together, I would add one table outside PostHog: a daily campaign spend table from Google Ads, Meta Ads, LinkedIn Ads, and your content channel. Even a CSV uploaded every Monday works for the first month. In one ecommerce setup, we used 92 landing pages, 37 Meta ad sets, and 11 SKU bundles. The winning post-purchase segment was not the highest ROAS group at checkout. It was buyers from two comparison pages who reordered at day 31 to day 45.

That hurt a little. Good data does that.

Use GPT To Label Intent, Friction, And Next Best Move

GPT-assisted labels work best when the model sees a small packet, not your whole customer history. I usually send the last 20 events, the first landing page, the paid plan, the last 3 support or survey text fields, and 5 revenue fields from Stripe. Keep the schema tight.

OpenAI introduced Structured Outputs on August 6, 2024, with JSON Schema matching for supported models such as gpt-4o-2024-08-06 and gpt-4o-mini-2024-07-18 in the API announcement at openai.com. For this workflow, that means your labeler should return a fixed object with state, confidence, reason, suggested_channel, and do_not_contact_until. If the output cannot fit that object, reject it and retry once.

The labels I trust are operational labels, not personality guesses. integration_blocked is useful. ambitious founder is fan fiction. price_anxious can be useful if it comes from a coupon hunt, pricing page revisits, and a billing question. high_intent is too vague unless it maps to a move, like sending a founder-written onboarding email within 2 hours.

One plausible rule for a B2B SaaS account: if GPT returns integration_blocked with confidence above 0.75 and plan is pro or business, send the user to Customer.io with a webhook and create a HubSpot task for the owner. If the account is self-serve starter at $29/month, send a 3-email help sequence and suppress sales outreach. Different treatment. Same label.

Build The Funnel In PostHog

My first dashboard has 5 views. The main funnel runs from subscription_created to first_value_action to repeat_value_action to upgrade_or_second_purchase. The second view breaks activation by GPT state. The third shows time to convert. The fourth lists drop-offs saved as cohorts. The fifth is a table of revenue by label.

PostHog lets you break funnels down by event properties, person properties, and cohorts. I use the GPT label as a person property when it should drive routing, and as an event property when I need a point-in-time audit trail. That distinction saves arguments later. If a user is labeled stalled on day 3 and activated on day 5, you want both the current state and the old decision record.

Cohorts are where the operating system starts to hum. PostHog docs say cohorts can target feature flags, experiments, and surveys, and they can filter dashboards and replays. They also warn that cohorts used in CDP destination filters need person-property-only criteria. I take that warning seriously. If I need realtime routing to Klaviyo, Braze, HubSpot, or a webhook, I push the GPT state onto the person profile and filter on that property.

One catch: dynamic cohorts update once every 24 hours, according to PostHog’s cohort FAQ. That is fine for weekly reporting. It is too slow for a day-0 rescue email. For fast action, use realtime destinations.

Route Actions Without Turning The Funnel Into Soup

PostHog’s realtime destinations can send data as it arrives, filter by event types, properties, or SQL, and post to tools such as Customer.io, HubSpot, Intercom, Klaviyo, Slack, webhooks, Google Ads, Meta Ads, and Reddit Ads. I route only 3 moments in version one: rescue, educate, and expand.

Rescue fires when a paid user is stalled for 72 hours. Educate fires when a user hits one high-friction feature twice, then completes it. Expansion fires after an account has 3 active users, 2 value events in 14 days, and plan usage above 80%. For one SaaS team with a $99 pro plan, that third route created 48 sales tasks in the first 30 days. Seven converted to annual contracts. The sample was small, but the motion was worth keeping.

Do not send every label everywhere. That is how founders end up with 17 lifecycle branches and no clean read on what worked. PostHog should own measurement and routing logic. Your email platform should own templates, send windows, unsubscribe rules, and channel fatigue.

QA The Labels Like A Media Buyer

I sample 50 labeled users before turning on automation. Ten from paid search, 10 from paid social, 10 from organic search, 10 from direct, 10 from sales-assisted accounts. Then I read the event trails. If 8 out of 50 labels look wrong, the prompt is not ready. If 3 are wrong but harmless, ship it behind a manual review step for the first week.

The fastest failure I see is stale labels. A buyer gets marked support_risk, solves the issue 18 minutes later, then still receives a worried email the next morning. Fix this with a label_expires_at property. For most B2B onboarding labels, I use 7 days. For ecommerce return risk, I use 14 days after delivery. For expansion, I use 30 days because account growth has a longer pulse.

Add a holdout too. Ten percent is enough at low volume. In PostHog, build a cohort or feature flag rule that excludes a random slice from GPT-routed messaging. Compare activation, refund rate, second order, or expansion revenue after 30 days. If the routed group wins by 6 points on activation but loses on refunds, you learned something expensive before it became normal.

The Setup I Would Ship This Week

For a founder or operator starting fresh on August 16, 2026, I would ship a 10-day version. Day 1 is event cleanup. Day 2 is Stripe or subscription data. Day 3 is the first PostHog funnel. Day 4 is the GPT labeler with Structured Outputs. Day 5 is a 50-user QA pass. Days 6 and 7 are Customer.io or Klaviyo routing. Days 8 through 10 are holdout setup, dashboard polish, and a written decision log.

The dashboard should answer one question by Friday afternoon: after someone buys, what behavior predicts the next dollar?

For a SaaS company, that might be integration_connected within 7 days. For a course business, it might be lesson 2 watched within 48 hours. For a subscription box, it might be a product quiz completed before the first shipment lands. GPT helps name the reasons customers drift between those events. PostHog tells you whether the labels make money.

That pairing is the useful part.