# Customer lifecycle inspector for Loops, Stripe and PostHog

> Open one screen each morning to see a paying customer's billing, product activity and email history, then send the right next email without leaving it.

- Workflow type: app
- Services: Loops.so, Stripe, PostHog
- Categories: Operations, Marketing
- Published: 2026-08-31

## What it does

- Lists your paying customers down the left side, pulled from your Stripe subscriptions, with a search box to find anyone by email or name
- Opens a full customer picture on the right: their marketing profile and which mailing lists they are on, whether their email is currently suppressed, their invoice and payment history, and what they have actually been doing in the product over the last 30 days
- Lets your team act on the spot: switch mailing list subscriptions on or off, edit profile fields, start a lifecycle email sequence, and restore email delivery for someone who was suppressed
- Includes a 'Write a lifecycle brief' button that hands the customer to a background assistant, which reads the billing history, product usage and email profile, judges what stage they are at and how likely they are to churn, recommends the specific next email to send, and saves that judgement back onto the customer profile so your future audiences can use it

## What you'll need

- A Loops account with an API key, plus at least one mailing list and one event-triggered email sequence set up
- A Stripe account where your paying customers and their subscriptions live
- A PostHog project that tracks your product usage, with events identified by the same email address you use in Loops and Stripe
- Customer email addresses that match across all three tools, since email is what links a Stripe customer to a Loops contact to a PostHog user

## Prompt

Build me a customer lifecycle inspector that my customer success manager and lifecycle marketing manager open every morning to answer two questions about a specific paying customer: what is going on with them, and what email should they get next. Loops has no customer history view of its own, so this app is the missing 360 view that sits on top of it. It is a two pane layout: a roster of paying customers on the left, and a full detail pane for the selected customer on the right.

Important design constraint to build around: Loops has no operation that lists or pages through all contacts. The only way to read a contact is Find Contact by email or userId. So the roster must be built from Stripe, and Loops data is fetched one contact at a time for whoever is selected. Do not try to build a paginated Loops audience browser, it is not possible.

Left pane, the roster. Populate it with Stripe List Subscriptions filtered by status, defaulting to active and trialing, and expand or follow through to the customer so each row can show the customer name, email, plan or price nickname, subscription status and current period end. Show subscription status as a small colored badge, and let the user switch the status filter to include past_due, canceled and unpaid. Add a search box at the top that runs Stripe Search Customers so someone can jump straight to a customer by email or name instead of scrolling. Selecting a row loads the detail pane and the selected customer should be reflected in the URL so a manager can share a link to a specific customer.

Right pane, the 360 detail view for the selected customer, organized into clear sections. Their Loops contact record from Find Contact using the Stripe customer email, showing first and last name, user group, subscribed status, and all custom properties. Their mailing list memberships: the Loops contact record returns mailingLists as an object mapping mailing list IDs to booleans such as { "cm1234abcd": true }, so call List Mailing Lists and join on the IDs to render readable list names with a toggle next to each one. Their suppression status from Get Contact Suppression Status, shown as a prominent warning banner when the contact is suppressed, and include the remaining monthly removal quota that operation returns so the manager knows what they are spending. Their billing history from Stripe List Invoices and List Charges filtered to that customer, rendered as a combined dated timeline with amounts, invoice status and whether each charge succeeded or failed, so failed payments are obvious at a glance. Their product activity from PostHog Execute HogQL Query, running a HogQL query against the events table matched on the customer email or distinct_id to return last seen date plus a count of key events over the last 30 days, displayed as a short list of event names with counts and the date last seen.

The manager must be able to act from this pane without leaving the app. Toggling a mailing list calls Loops Update Contact with mailingLists set to the changed list ID mapped to true or false. Editing contact properties uses Update Contact as well, with the field picker populated from List Contact Properties so the manager picks from properties that actually exist rather than typing raw keys. A control to fire a lifecycle sequence calls Send Event with an event name the manager chooses or types, which is how a Loops email workflow gets triggered for that contact. When the contact is suppressed, the warning banner carries a button that calls Remove Contact From Suppression List to lift it, with a confirmation step since removals draw down a monthly quota. Every action should optimistically update the pane and then refetch the affected section so the manager sees the true server state.

Add a "Write a lifecycle brief" button in the detail pane that starts a background agent for the selected customer. The agent reads that customer's Stripe billing history via List Invoices and List Charges, their product activity via PostHog Execute HogQL Query, and their Loops contact record via Find Contact. It then reasons about what actually changed rather than restating the numbers: is spend growing or shrinking, have invoices started failing, has product usage dropped off compared with the earlier part of the window, is the contact engaging with email or drifting. From that it judges a lifecycle stage and a churn risk level, and recommends the specific next email to send with a one line reason why that email and not another. The brief is written back into the app so it appears in the detail pane for that customer with a timestamp, and previous briefs stay visible so the team can see how a customer's read has shifted over time. As its final step the agent calls Loops Update Contact to stamp lifecycleStage and churnRisk onto the contact as custom properties, so future Loops segments and audiences can filter on them.

A few Loops details to bake in. Update Contact is an upsert, so it creates a contact if none matches the email, which is fine here since every roster row is a real paying customer. Update Contact accepts arbitrary camelCase top level keys and treats them as custom properties, which is exactly how the agent writes lifecycleStage and churnRisk. A contact can only hold a single user group value, so prefer custom properties over user groups for anything the agent produces and never overwrite the existing user group. Email query parameters must be URI encoded when finding a contact or checking suppression. Handle the case where a Stripe customer has no matching Loops contact gracefully by showing an empty state with a button to create the contact via Update Contact rather than an error.

## How to customize

- Which customers appear in the roster: filter by subscription status such as active only, or include trialing, past due and cancelled customers
- Which product events count as meaningful activity in the 30 day panel, and how far back the activity window reaches
- The lifecycle stages and churn risk levels the brief is allowed to choose from, so they match the labels your team already uses in its audiences

## FAQ

### Why not just do this inside Loops?

Loops does not have a customer history view. It can send excellent email, but there is no single place to see one person's billing, product usage and past engagement side by side, which is exactly what this screen gives you.

### Does this change anything in Stripe or PostHog?

No. Billing history and product activity are read only. The only tool this app writes to is Loops, when you edit a profile, change mailing lists, start a sequence, restore email delivery, or let the assistant save its lifecycle judgement.

### How does the lifecycle brief decide someone is at risk?

It looks at what actually changed rather than a single number: whether payments are still going through, whether invoices have started failing, whether product usage has dropped off compared with earlier, and how the person has been engaging with email. It then explains its reasoning in the brief so you can disagree with it.

### Will the assistant overwrite fields my team already uses?

It only sets two fields on the profile, one for lifecycle stage and one for churn risk. Everything else on the contact is left untouched, and your team can still edit any field by hand from the same screen.

### Can I use this without PostHog?

Yes. The billing history, email profile, mailing lists and suppression status all still work, and the product activity panel simply stays empty. Connect PostHog later and that panel starts filling in.

### Who on the team is this for?

It is built for customer success and lifecycle marketing managers who start the day asking what is going on with a specific customer and what should be sent to them next, without needing an engineer to pull the data.

Use this prompt in General Input: https://www.generalinput.com/prompts/customer-lifecycle-inspector-for-loops-stripe-and-posthog