10+ years · 3x UK Search Awards

Blog

The GA4 Audience Framework for Repeat-Purchase Ecommerce: 25 Lists, 6 Layers, 3 API Limits

Blog |Tracking|2026-08-01|~16 min

Tracking · 2026-08-01 · ~16 min

What's in this post

Twenty-five GA4 audiences, six pillars, and three things the Admin API flatly refuses to do. This is the complete framework — every list, every configuration, every workaround — not a teaser for a gated download.

25

lists: 24 targeting audiences + 1 exclusion helper

6

pillars, one naming convention

3

API limits that shape the whole build

2-4 wks

before a new list is actually usable

I built this out through the GA4 Admin API for a UK skincare retailer I work with — a multi-brand account, twenty-five lists, and the part that turned out to matter most wasn't any single audience definition. It was what the API refuses to do. Three limits kept showing up, in different disguises, on almost every list I tried to build the "obvious" way, and once I understood them the whole structure got simpler, not more complicated.

Everything is below: the full list of twenty-five audiences with their exact GA4 configuration, the naming convention that keeps them sane once you have that many, the three API limits and how I work around each one, and the build order I actually follow on a live account. Nothing here is gated. If you want the executable version — markdown files you can drop straight into Claude or ChatGPT, plus a PDF — that's linked at the end, but the framework itself is the whole post.


The count: 25 lists, 6 pillars, 1 helper

Say "25 audiences" to most people and they picture 25 things you can point ads at. That's not what this is. The count that matters: 25 lists in the property = 24 targeting audiences across 6 pillars, plus 1 exclusion helper.

The helper — LCY_ALL_ActiveCustomers_45d — is not a targeting audience. It exists purely so you can subtract it from replenishment lists inside Google Ads. Counted as a definition it is one list, but you clone it onto whichever windows your combinations need: a full build of this framework ends up with two more copies of it (25 days for the supplement cycle, 120 days for the at-risk value tier), so the property holds 27 audience objects for 25 list definitions. Worth knowing before you count rows in the GA4 interface and think something went wrong.

The counting rule: 24 target audiences plus 1 helper list make 25 definitions, and the helper cloned to the 45d, 25d and 120d windows makes 27 audiences in the property
24 target lists plus one helper. The helper gets cloned, so the property shows 27.

Naming convention

Every list follows the same pattern:

{PILLAR}_{SCOPE}_{Segment}_{Window}

Pillar is one of six three-letter codes. Scope is either ALL (whole account) or a brand/category tag (BR1, BR2, MOI, SUP, SPF). Window is the membership duration or the target range the list is built to catch (90d, 540d, 45-120d).

Diagram of the naming convention PILLAR_SCOPE_SEGMENT_WINDOW mapped to the real example LCY_ALL_CartAbandoners_14d
Four segments, always in this order, separated by underscores.

The reason the convention exists at all: once a property has 25 lists, prefix search is the only way to know what's what three months from now. Sort by name and every pillar groups itself. Skip the convention and you'll be opening list definitions one by one to remember which Browsers_60d is which.

The six layers of the GA4 audience framework: LCY lifecycle, VAL value and RFM, INT intent, BRD brand affinity, RPL replenishment, PRD predictive
Six pillars and the list count in each. Detailed tables for every pillar follow below.

How audiences fill, and the delivery thresholds

Two mechanics decide whether any of this actually reaches anyone, and both catch people off guard.

Filling: a GA4 audience starts filling from the moment you create it, plus roughly 30 days of backfill for users who already qualify at creation time. There is no retroactive fill beyond that window. The practical consequence: a list you build today is usable in 2-4 weeks, not tomorrow. The best moment to build audiences is before you need them - the worst is the week a campaign launches.

Timeline showing a GA4 audience filling only from the day it is created, with roughly 30 days of backfill, and becoming usable 2 to 4 weeks later
A list only starts filling the day you create it. Backfill is roughly 30 days.

Delivery thresholds are Google's hard minimums, not a suggestion. Search remarketing (RLSA) and Shopping need 1,000 active users in the last 30 days; Display, YouTube and Demand Gen need 100. Below the bar, a list sits in Observation - you see its data, it does not affect delivery.

Two cards comparing GA4 audience size thresholds: 1,000 members minimum for Search remarketing (RLSA) and 100 members minimum for Display, YouTube and Demand Gen
Below the threshold an audience does not serve. The same 1,000 floor applies to Shopping.

This is where most "we tried audiences, they didn't work" stories end before they start: five lists, none crosses the bar, and the conclusion writes itself. The good news is that nearly every store with real traffic clears the 100-member bar for Display, YouTube and Demand Gen - so remarketing starts there while the Search lists grow.


Pillar 1 — Lifecycle (LCY)

Six lists that track where a customer sits in the relationship, from first visit to repeat buyer. This is the foundation pillar — everything else references one of these lists as an exclusion at some point.

Two columns of audiences: lifecycle (first time buyers, repeat buyers, active customers, lapsed buyers, engaged non buyers, new visitors) and value (top 10 percent, top 25 percent, top 25 percent at risk, one time low value)
The first two pillars in one view, with simplified names. Exact definitions and windows are in the tables below.
NameDefinitionGA4 configurationMembershipWhat it's for
LCY_ALL_FirstTimeBuyers_180dExactly 1 purchase ever, most recent within 180 daysInclude: purchase event count = 1, at any point in time, AND purchase within a 180-day period180 daysThe second order is the KPI that decides whether the brand is growing — this is the only list aimed at it directly
LCY_ALL_RepeatBuyers_540d2+ purchasesInclude: purchase event count > 1, at any point in time540 daysCore value segment — bid boost, Similar/lookalike seed
LCY_ALL_ActiveCustomers_90dPurchased in the last 90 daysInclude: purchase (at least once)90 daysExclusion from acquisition campaigns, plus the base for cross-sell
LCY_ALL_Purchasers_365dPurchased at any point in 365 daysInclude: purchase (at least once)365 daysRaw material for win-back: in Ads, this list MINUS ActiveCustomers_90d = lapsed
LCY_ALL_EngagedNonBuyers_30d2+ sessions in 30 days, never purchasedInclude: session_start event count > 1 (UI: within a 30-day period; API: at any point in time, the window carried by membership) · Exclude: purchase, at any point in time30 daysProspecting seed for Demand Gen and lookalike logic
LCY_ALL_NewVisitors_7dFirst visit within 7 days, no purchaseInclude: first_visit · Exclude: purchase, at any point in time7 daysSoft remarketing while memory is fresh — the short membership is deliberate

Pillar 2 — Value / RFM (VAL)

Four lists that layer customers by value rather than recency. This is where the first Admin API limit shows up directly — LTV percentile is a UI-only concept, so two of these four lists have both a UI route and an API workaround. I cover why in the API limits section; here's the configuration either way.

NameDefinitionGA4 configurationMembershipWhat it's for
VAL_ALL_Champions_Top10_540dTop 10% by valueUI route: suggested audience template with LTV percentile (top 10%) · API route: frequency proxy — purchase event count > 2, at any point in time540 daysProtection, Similar seed, and the rule that these people never see a discount message
VAL_ALL_HighValue_Top25_540dTop 25% by valueUI: LTV percentile top 25% · API: purchase event count > 1, at any point in time540 daystROAS boost, remarketing priority
VAL_ALL_AtRisk_HighValue_120dHigh value, hasn't purchased in 120 daysSame definition as HighValue_Top25 above, membership 120 days — "hasn't purchased" is resolved in Ads (MINUS ActiveCustomers_120d)120 days"Can't lose them" — the most expensive loss in the account
VAL_ALL_OneTimeLowValue_365d1 purchase, bottom half by valueInclude: purchase event count = 1, at any point in time (UI: intersect with LTV bottom 50%)365 daysExcluded from expensive remarketing — not every buyer deserves the same bid

Pillar 3 — Intent / funnel (INT)

Four lists that catch drop-off at each funnel stage. These are also the fastest way to test whether your event tracking is actually complete — see the build-order check below.

NameDefinitionGA4 configurationMembershipWhat it's for
INT_ALL_CartAbandoners_14dadd_to_cart in 14 days, no purchaseInclude: add_to_cart within a 14-day period · Exclude (temporarily): purchase within a 14-day period14 daysThe hottest layer in the account, highest bid
INT_ALL_CheckoutAbandoners_7dbegin_checkout in 7 days, no purchaseInclude: begin_checkout within a 7-day period · Exclude (temporarily): purchase within a 7-day period7 daysUrgent layer — runs parallel to the email flow, not instead of it
INT_ALL_ProductViewers_NoATC_30dview_item in 30 days, no add-to-cartInclude: view_item within a 30-day period · Exclude (temporarily): add_to_cart within a 30-day period30 daysMid layer — cheaper bid, higher volume
INT_ALL_SearchUsers_30dUsed on-site search in 30 daysInclude: view_search_results (or search) within a 30-day period30 daysThe most overlooked signal — someone typing into your search bar already knows what they want

Note the "temporarily" on three of the four exclude conditions. That word is doing real work — I explain exactly what it means and where it stops working in the API limits section below.


Pillar 4 — Brand affinity (BRD)

Five lists, and only relevant if you run a multi-brand store. The BR1 / BR2 scope tags are your two brands by revenue. Single-brand store? Skip this pillar and replace it with product categories instead — SER for serum, CLE for cleanser, whatever your catalog splits into. The logic doesn't change, only the scope tag does.

Check this before you build any of it

Before building any BRD list, confirm that item_brand is actually populated in GA4. On plenty of stores it's empty or inconsistent. If it is, fall back to a page_location pattern (URL contains the brand slug) or item_category.

NameDefinitionGA4 configurationMembershipWhat it's for
BRD_BR1_Purchasers_365dPurchased the primary brandInclude: purchase where item-scoped dimension item_brand = BR1365 daysCore of the biggest brand
BRD_BR1_StepUp_Purchasers_365dPurchased a more advanced line of that brandInclude: purchase where item_name contains the line token365 daysBuyer entering a subscription pattern — the best candidate for value growth
BRD_BR1_Browsers_NoBuy_60dViewed BR1, didn't purchaseInclude: view_item with item_brand = BR1 within 60 days · Exclude: purchase with item_brand = BR1, at any point in time60 daysBrand-specific remarketing — a message that knows what it's talking about
BRD_BR2_Purchasers_365dPurchased the second brand by revenueSame as BR1_Purchasers above, with BR2365 daysSecond core
BRD_BR2_Browsers_NoBuy_60dViewed BR2, didn't purchaseSame as BR1_Browsers above, with BR260 daysRemarketing

Pillar 5 — Replenishment (RPL) — the one nobody builds

Three lists, and this is the pillar that gets the most weight in this post, because it's the one I almost never see built anywhere else. Most accounts have lifecycle and intent audiences. Almost none have replenishment, and for a repeat-purchase consumable business it carries the most weight of the six — it's the difference between remarketing that reacts to browsing and remarketing that predicts when someone is about to run out.

Consumption windows for moisturiser, supplements and SPF on a 120 day scale, with a red marker at day 55 where the replenishment ad should land
Day 55 is roughly 80 percent of the shortest cycle. A reminder, not an interruption.

The name carries the target window (45-120d), but GA4 can only build the upper bound — "purchased within the last 120 days" — as a membership window. The lower bound, "and nothing in the last 45 days", has to be built as an exclusion in Google Ads, not inside the GA4 list itself. That's API limit #3 below, and it's the reason the helper list exists on more than one window.

NameDefinition (effective)GA4 configurationMembershipAds exclusionWhat it's for
RPL_MOI_Due_45-120dPurchased moisturiser 45-120 days ago, nothing sinceInclude: purchase where item_category (or item_name) contains the moisturiser token120 daysMINUS LCY_ALL_ActiveCustomers_45dMoisturiser lasts 60-90 days; the ad arrives as the jar is running dry
RPL_SUP_Due_25-75dPurchased a supplement 25-75 days agoInclude: purchase where category = supplements75 daysMINUS LCY_ALL_ActiveCustomers_25d (clone of the helper list)A 60-capsule pack runs about two months
RPL_SPF_Due_45-120dPurchased SPF 45-120 days agoInclude: purchase where category = SPF120 daysMINUS LCY_ALL_ActiveCustomers_45dConsumption cycle plus a seasonal factor

How to set the window

The logic is the same for any consumable: work out how long a pack lasts, then start advertising at roughly 70-80% of that cycle — while there's still time for the ad to land before the shelf is empty, not after. A moisturiser that lasts 60-90 days starts at 45. A 60-capsule supplement that runs about two months starts at 25-30.

If you don't know your cycle length, don't guess it — pull it from your own purchase data. Take the average gap between a customer's first and second purchase in the same category. That gap is your cycle, and it's specific to your product and your customers in a way a generic "skincare replenishes every 60 days" assumption never will be.


Pillar 6 — Predictive (PRD)

Two lists, and the only pillar that's conditional on your property qualifying at all.

NameDefinitionConfigurationMembershipWhat it's for
PRD_ALL_LikelyPurchasers_7dGoogle ML prediction of purchase within 7 daysGA4 UI → Audiences → suggested → Predictive → "Likely 7-day purchasers." Does not exist through the API.30 daysFuel for tROAS
PRD_ALL_ChurnRisk_7dML prediction of churnSame route, "Likely 7-day churning purchasers"30 daysEmail list, not an ad list — churn is treated with a message, not a bid

The condition for predictive metrics: the property needs enough positive and negative examples — Google requires on the order of 1,000 users who did and 1,000 who didn't complete purchase within a 28-day window — and the model has to stay "eligible." Small stores simply don't qualify here. That's not a setup mistake, it's a volume floor, and there's no configuration workaround for it.

The helper list (not a pillar, not a targeting audience)

ListDefinitionGA4 configurationMembershipWhat it is for
LCY_ALL_ActiveCustomers_45dpurchased at least once in the last 45 daysInclude: purchase, at least once45 daysExclusion only, never a target. Clone it onto 25 days for the supplement cycle and 120 days for the at-risk value tier.

The three Admin API limits

This is the part that came from actually building the thing through the API, not from reading documentation. Every one of these limits will bite you if you try to build the "obvious" version of a list, and every one of them has a workaround that changes how you should think about the list, not just how you configure it.

Three GA4 Admin API limits paired with workarounds: lifetime value unavailable in filters, count filters without rolling windows, and no way to express has not purchased in N days
Three things the API refuses to do, and what you do instead.

1. lifetimeValue doesn't pass through in audience filters via the API

LTV percentile only exists as a UI suggested-audience template. Try to filter on it through the API and you get an error — there is no equivalent field to fall back on.

Workaround: a frequency proxy. Champions become "3+ purchases" (eventCount > 2), High Value becomes "2+ purchases." It isn't the same as actual spend, but it correlates well enough to make the bidding decision better than having no value signal at all. If you need real value-based segmentation, build it in your CRM and import it as Customer Match instead of forcing GA4 to do a job it can't do through the API.

2. Count filters have no rolling windows

eventCount conditions only work with atAnyPointInTime: true — meaning "ever," never "in the last N days." You cannot ask GA4 for "2+ purchases in the trailing 90 days" as a count condition.

Workaround: move the window onto membership duration instead of the count condition. "2+ purchases in 540 days" becomes "2+ purchases ever" plus a 540-day membership window. The result is close but not identical — a customer who made two purchases three years ago will re-enter the list the moment they revisit the site, since the count condition itself has no time boundary.

3. "Hasn't purchased in the last N days" can't be built inside GA4

This is the limit that undermines half of every win-back and replenishment idea you'll sketch out on a whiteboard. A GA4 exclude condition is tied to the membership window of the list itself, so "temporarily exclude purchasers" only works when the include and exclude windows match — which is exactly why it works for the INT lists above and nowhere else.

Workaround: build it in Google Ads, not GA4 — as a combination of a target list MINUS an active-customers list. That single move is why the helper ActiveCustomers definition gets cloned onto several windows (45d, 25d, 120d — alongside the 90d list that already exists in the lifecycle pillar): each replenishment or win-back combination needs its own exclusion window.

Bonus, if you're going through the API yourself

The filter schema is always andGroup → orGroup → leaf. Only GREATER_THAN exists as a comparison operator — there is no GREATER_THAN_OR_EQUAL, so "3+" has to be written as > 2. And list descriptions are capped at roughly 150 characters, which is tighter than it sounds once you're documenting a 25-list system.


Build order, with checks

I don't build all 25 lists in one sitting, and you shouldn't either. Each wave has a check attached, and the check exists because building on top of broken tracking just produces 25 broken lists instead of one obvious problem.

Eight build waves each with its own check: tracking prerequisite, lifecycle, intent as the stop rule, value, brand, replenishment, predictive, and a review after two weeks
Eight waves, each with its own check. Wave 2 is the only stop rule: no add_to_cart signal, no further building.
0
Prerequisite — ecommerce events actually fire

view_item, add_to_cart, begin_checkout, purchase all need to be reaching GA4, the property needs to be linked to the Google Ads account, and Google signals should be on if you need Display reach. Check: GA4 → Realtime, run a test purchase, confirm purchase shows up with a value.

1
Wave 1 — helper and lifecycle lists

Build the helper and the core lifecycle lists first (ActiveCustomers_90d, Purchasers_365d, the exclusion helper, then FirstTimeBuyers, RepeatBuyers, EngagedNonBuyers, NewVisitors). Check: each list exists, the membership window is correct, the description is filled in.

2
Wave 2 — intent lists

Build the four INT lists. Check: after 48 hours, CartAbandoners has members. If it doesn't, add_to_cart isn't reaching GA4 — and that's where you stop.

3
Wave 3 — value lists

Build the four VAL lists — UI route if you have the LTV template available, API route with the frequency proxy if you don't.

4
Wave 4 — brand lists

Build the five BRD lists, but only after checking item_brand. Check: run an Explore report by item_brand over 30 days — do values exist, and are they consistent across products?

5
Wave 5 — replenishment

Build the three RPL lists. Check: do the category tokens in your Merchant Center feed match the category tokens in GA4? A mismatch here silently produces an empty or wrong list.

6
Wave 6 — predictive

Build these two manually in the UI, and only if the model shows as eligible.

7
After two weeks

Check list sizes, switch qualifying lists on as Observation, and note which ones have crossed the delivery threshold.

Stop rule

If wave 2 doesn't work — if CartAbandoners stays empty after 48 hours — further list-building is wasted time. Audiences don't fix tracking. Fix the event first, then come back to wave 3.


Activation: Observation, exclusions, GA4 + CRM

Building the lists is half the job. How you turn them on determines whether they help or quietly waste budget.

Three activation steps: Observation first, then excluding active customers from acquisition, then mirroring the segments in the CRM for Customer Match
Activation order. Bid decisions come only after the lists have filled.
  1. Everything starts as Observation. Every list goes onto Shopping and Search campaigns as Observation first — zero impact on delivery, but after two weeks you have your own numbers instead of borrowing someone else's benchmark.
  2. Exclusions turn on as soon as a list crosses threshold. ActiveCustomers_90d comes out of acquisition flows, OneTimeLowValue comes out of expensive remarketing.
  3. Bid adjustments come last — only after a list has filled and only on lists that have real volume behind them.
  4. GA4 is breadth, CRM is precision. The same segments in your email tool give you real RFM figures — actual order counts, actual spend — so that's where they belong for Customer Match. A GA4 list is an approximation built from event counts and membership windows; a CRM list is a fact.

Put together, the target-minus-exclusion combinations in Google Ads look like this:

GoalTarget listMINUS (exclusion)
Win back lapsed customersLCY_ALL_Purchasers_365dLCY_ALL_ActiveCustomers_90d
At-risk high valueVAL_ALL_AtRisk_HighValue_120dLCY_ALL_ActiveCustomers_120d
Moisturiser replenishmentRPL_MOI_Due_45-120dLCY_ALL_ActiveCustomers_45d
Supplement replenishmentRPL_SUP_Due_25-75dLCY_ALL_ActiveCustomers_25d
SPF replenishmentRPL_SPF_Due_45-120dLCY_ALL_ActiveCustomers_45d
Pure acquisition(no target list)LCY_ALL_ActiveCustomers_90d
Demand Gen prospectingLCY_ALL_EngagedNonBuyers_30dLCY_ALL_Purchasers_365d

One caveat that applies everywhere in this table: audiences are a signal, not a fence. In Performance Max and Demand Gen especially, treat these lists as an input the algorithm weighs, not a guarantee of who actually sees the ad.


Frequently asked questions

Why are my audiences stuck at zero?
Either the list hasn't crossed the delivery threshold yet, the event it depends on isn't reaching GA4, or the membership window is shorter than actual customer behaviour. Check in that order — threshold, then event, then window.
How long should I wait before using a new audience?
Two to four weeks. Before that, the data sitting in Observation doesn't have enough members to mean anything.
Do I need the Admin API, or does the UI work fine?
The UI works for everything except scale. At 25 lists, the API saves hours and gives you repeatability, but the UI can do two things the API can't: LTV percentile targeting and predictive audience templates.
What's the maximum membership window?
540 days. There is no longer option in GA4, no matter how long your actual purchase cycle runs.
What if I only sell one brand?
Replace the brand affinity pillar with product categories instead. The logic stays identical — only the scope tag changes.
Does this work for lead gen, not just ecommerce?
The lifecycle, intent, and value layers carry over. Replenishment doesn't, because there's no consumption cycle to anchor it to — and that pillar is arguably half of this framework's value for a repeat-purchase business.
Can these audiences go into Performance Max?
As a signal, yes. As a targeting guarantee, no. PMax uses an audience as an input the algorithm weighs, not as a fence around who sees the ad.
What if my item_brand field is empty?
Fall back to a page_location pattern or item_category. Check this before you build the brand affinity lists, not after.

Conclusion

GA4 audiences for ecommerce are not a list of 25 items to type in - they are a system with three rules that carry everything else. Lists fill from the day you create them, so you build ahead of need, not in the week a campaign launches. Delivery thresholds decide where each list is allowed to work, so smaller accounts start from the 100-member bar on Display, YouTube and Demand Gen, which almost any store clears. And the things GA4 will not do - value in filters, rolling windows, "has not purchased recently" - are solved by subtracting lists inside Google Ads, not by fighting the API.

If you take one action from this post, make it this: build the lifecycle and intent lists today and let them fill while you work on something else. In two to four weeks you have a first-party data layer no platform update can take away - and campaigns that know exactly who they are talking to.

Want the executable version?

The free GA4 Audience Framework download packages all 25 list definitions as markdown files you can drop straight into Claude or ChatGPT, plus a PDF reference. Email only, nothing else to fill in.

Get the framework

Related guides

Free video audit

Get a Personalised Video Audit of Your Google Ads Account

I'll record a 15-minute walkthrough of your campaigns showing exactly where you're losing money and what to fix first.

Book a free consultation

Free personalised video audit

Want a video walkthrough of your Google Ads account?

I'll personally record a 15-minute video walking through your campaigns, showing you where you're losing money and giving you 3 specific things to fix immediately. No sales pitch — just value.

What you get:

  • 15-min personalised video analysis
  • 3 specific quick wins to implement
  • Budget & bidding recommendations

Requirements:

  • Ad spend: €1,500+/month (or £1,500+)
  • Active account for 3+ months
  • eCommerce or Lead Gen business

Limited to 5 audits per month. Response within 48 hours.