Build audience segments from product usage and push to Loops

A self-serve screen where marketers define an audience from real product usage, preview exactly who matched, and send it to Loops without an engineer.

App
Loops.soPostHogGoogle SheetsMarketingProductEmail AutomationData Sync
PromptCreate

Build me a segment builder app that my growth and lifecycle marketers open to define an audience from real product behaviour in PostHog and push it into Loops themselves. Today that job needs an engineer to write API calls, so the whole app is designed for a marketer: nothing requires writing code, every write is previewed and confirmed first, and the app never assumes a push succeeded.

Screen one is the segment builder. It offers two ways to define an audience, side by side as tabs. Cohort mode: call PostHog List Cohorts to populate a picker of existing cohorts, and when one is selected call List Cohort Persons to resolve its members. Query mode: a visual criteria composer where the marketer stacks rules such as event name, how many times it happened, the time window, person property filters, and negative rules like did not do event X. Compile those rules into HogQL and run them with Execute HogQL Query. Show the generated HogQL in a collapsible panel underneath the composer so a curious marketer or a passing engineer can read exactly what will run, but never require anyone to edit it.

Both modes feed one live preview panel that is always visible: the matched person count in large type, and a sample table of up to 50 matched people showing email and the person properties used by the criteria. Re-resolve the preview whenever the criteria change, but debounce it and never fire on keystroke. PostHog limits HogQL queries to roughly 240 per minute with 3 concurrent queries and a 10 second execution ceiling, so serialize preview runs, cancel superseded ones, and show a clear message if a query times out or is rate limited rather than an empty state that looks like zero matches.

Screen two is the push panel, which is where this pays off. Call Loops List Mailing Lists to populate a mailing list picker and Loops List Contact Properties to populate a property editor where the marketer chooses which contact properties to set and what value each gets for this segment. Include an inline New property form that calls Loops Create Contact Property so a marketer can define a brand new property without leaving the app, then immediately use it. Offer two push modes. Mode one writes per person with Loops Update Contact, which is an upsert: send mailingLists as an object mapping mailing list ID to boolean where true subscribes and false unsubscribes, for example { "cm1234abcd": true }, plus arbitrary camelCase top level keys as custom properties whose values may be string, number, boolean, or ISO-8601 date. Mode two fires a sequence for the whole segment with Loops Send Event using an event name the marketer picks. Send a fresh UUID Idempotency-Key header per person per push so a retried batch does not double fire, and treat the 409 that comes back from reusing a key within 24 hours as already sent rather than a failure. Offer Loops Find Contact as a per-row inspect action so a marketer can check what one person looks like in Loops before committing.

Safety is the point, because this is used by marketers rather than engineers. Dry run is a toggle that defaults to on, and a dry run resolves the segment and renders the exact payload that would be written for a sample of people while writing absolutely nothing. Turning dry run off and pressing push must open a confirmation dialog that states the person count, the target mailing list name, the event name if firing a sequence, and the full list of property changes, and requires an explicit confirm. Cap the batch with a configurable maximum, defaulting to 2000 people, and refuse to push past the cap without an explicit override. Loops allows 10 requests per second per team, so throttle the per person loop to around 5 requests per second with bounded concurrency, read the x-ratelimit headers, and back off with jitter on a 429 and retry. There is no bulk contact write in Loops, so the push is a throttled per person loop by design. Branch on HTTP status, not just the success boolean in the response body. Run the push server side with a live progress bar and running success and failure counts, and end on a result view listing every person with their status and failure reason plus a Retry failed only button that touches nobody who already succeeded.

Every push, including dry runs, appends one row to a Google Sheet with Append Values: timestamp, who pushed it, segment name, the segment definition as either the cohort ID or the HogQL text, person count, push mode, mailing list ID and name, the properties and values that were set, the event name if any, the dry run flag, success count, failure count, and free text notes. A Sync history tab reads that sheet back with Get Values and renders it newest first, so the team can see which audience was last pushed. Selecting a history row lets the marketer open the full definition, rerun it by loading the definition back into the builder prefilled, or diff it by re-resolving the segment now and showing how many people were added, removed, and unchanged against the recorded count.

Add a Build this segment from a description button in the builder that starts a background agent. The marketer types something like "trial users who hit the integrations page twice but never connected one, in the last 14 days". The agent explores the project schema by running small discovery queries with Execute HogQL Query to learn the real event names and person properties available, writes candidate HogQL for the description, runs it, and iterates if the result is empty or implausible. It then writes back into a review card in the builder containing the final HogQL, the matched person count, a plain language explanation of who matched and, just as importantly, who was deliberately excluded and why, and a concrete proposal for the property values to set and the event name to send. The agent writes nothing to Loops. Everything it produces is held for human review, and accepting the proposal simply loads it into the builder and push panel so it goes through the same dry run and confirmation path as a hand built segment.

Persist saved segments so a marketer can reopen a named audience with its definition and default push configuration, and remember each user's last used mailing list and dry run preference. The Google Sheet is the durable shared log. Lay the app out as a dense but legible two column workspace: the definition on the left, the live preview and push panel on the right, with Sync history as its own tab. Keep the person count visible at all times, since it is the number a marketer is judging the whole segment on.

What does this prompt do?

  • Pick an existing PostHog audience or compose one from product behavior, then see the exact number of people who match plus a sample of their emails and properties before anything happens.
  • Push the audience into a Loops mailing list, set contact properties on each person, or fire an email sequence for the whole group, after a dry run and a confirmation that shows the person count.
  • Describe the audience in plain English and a background assistant builds it for you, explains who matched and who was left out, and proposes exactly what to set, all held for your approval.
  • Every push is logged to a Google Sheet, and a Sync history tab shows which audience went out last so you can rerun it or compare it against today.

What do I need to use this?

  • A PostHog account where your product usage is already being tracked
  • A Loops account with at least one mailing list set up
  • A Google account and a Google Sheet to keep the push history in
  • Someone on the team who knows which product events matter, though no coding is required

How can I customize it?

  • Change the default batch cap and the pace of the push if your Loops plan allows a higher send rate.
  • Adjust which contact properties are offered by default, or define a brand new one from inside the app.
  • Point the history log at a different Google Sheet, or add columns like campaign owner and notes.

FAQs

Do I need an engineer to use this?
No. You build the audience by picking an existing group from your product analytics or choosing behavior criteria on screen. If you would rather just describe the audience in a sentence, the built-in assistant writes the query for you and shows you what it found before anything is sent.
Can it accidentally email the wrong people?
Dry run is on by default and writes nothing at all. Turning it off requires confirming a dialog that shows the exact person count, the target mailing list, and the property changes that will be applied.
What happens if part of the push fails?
You get a per-person result with success and failure counts plus the reason each one failed, and a retry option that only touches the people who did not go through. The same counts are written to the history sheet so nothing is silently lost.
Will this work with the mailing lists and properties I already have in Loops?
Yes. The app reads your live mailing lists and contact properties every time you open the push panel, and you can define a new contact property from inside the app without switching tabs.
Can I see what was pushed last week?
Yes. The Sync history tab reads the log sheet, so you can see the audience definition, when it went out, how many people matched, and whether it was a dry run. You can reload any past push into the builder to rerun it or compare it with who matches today.

Related templates

Call overdue Xero customers with an AI collections agent

Every weekday at 10am, an AI voice agent phones your most overdue Xero accounts, logs what each customer promised, and reports back to finance in Slack.

LiveKit
Xero
Deepgram
+2
Agentic Task
Local listing health board for every location you manage

See every Google Maps listing you manage on one screen, ranked worst first, with an audit button that writes the fix list for you.

Local Business Data
Google Sheets
App
Let support send one-off Loops emails without an engineer

Your team picks a template, finds the customer, checks they are safe to email, then sends it, with every send logged where the whole team can see it.

Loops.so
Stripe
Google Sheets
App
Stop cold emails to anyone with a live deal in Pipedrive

Every night at 2am, pull the contacts on your open and won deals and block them from your cold outreach before the next send goes out.

Mailshake
Pipedrive
Google Sheets
Deterministic Code
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.

Loops.so
Stripe
PostHog
App
iMessage campaign console with pre-flight checks and delivery board

Build every text campaign in one screen: check who is actually reachable, see a realistic send plan, then watch delivery land row by row.

LoopMessage
Google Sheets
HubSpot
App

Stop filing engineering tickets to build an audience.

Give your growth and lifecycle team one screen where they define an audience from real product usage and push it to Loops themselves.