Platform Retargeting Suppression Onboarding Integrations Pricing Blog Sign in Request Access
How-to

Syncing Behavioral Audiences to Google Ads and Meta Without Writing SQL

Abstract illustration of data syncing from a source to advertising platforms

Build this audience in Segmentloom →

Request access

This is a walkthrough, not a conceptual overview. The goal is to get from "I have product event data" to "I have a live audience in my ad platform" without writing SQL, without opening a data engineering ticket, and without a CSV export that's stale by the time the campaign goes live.

The scenario: a SaaS product tracking events including pricing_page_viewed, trial_started, feature_activated, and subscription_created. The growth team wants to run a high-intent upgrade campaign targeting trial users who have shown pricing interest in the past two weeks. The target destinations are Google Ads (via customer match) and Meta (via custom audiences). No data engineering bandwidth is available.

Step 1: Know Your Events Before You Build Anything

The most common failure mode in behavioral audience building is starting with the audience definition before confirming that the underlying events actually fire the way you think they do. Before building any rules, answer three questions about each event you plan to use:

  1. Does it fire consistently? If pricing_page_viewed fires on every page load (including refreshes and back-navigation), count-based conditions will behave differently than if it fires only once per session. Neither is wrong, but you need to know which is true for your product.
  2. What properties does it carry? Some event tracking setups attach the user's email directly to each event. Others rely on a user_id that must be joined against a profile to retrieve the email. For customer match uploads, you need an email address — knowing how to reach it matters before you build the audience.
  3. What's the schema of any boolean events? An event like subscription_created might be tracked as an event occurrence (you check whether it appears in a user's history) or as a profile property that gets set to true when the event fires. These are logically equivalent but require different condition types in an audience builder.

For the scenario above, assume: pricing_page_viewed fires once per distinct page load with no deduplication, carries user_id as a property. trial_started fires once per user. subscription_created is a profile property set to true when the conversion event fires.

Step 2: Define the Audience Rules

With event behavior confirmed, translate the intent signal into explicit conditions:

  • Condition 1: pricing_page_viewed — count is greater than or equal to 2 — lookback window: last 14 days
  • Condition 2: trial_started — has occurred at least once — lookback window: last 90 days (captures any active or recently lapsed trial user)
  • Condition 3: subscription_created — is false (profile property filter — excludes users who already converted)

These three conditions together define a user who: is or recently was in a trial, has revisited the pricing page multiple times in the past two weeks, and has not yet converted. The audience is, by construction, limited to genuinely high-intent non-customers.

In a no-SQL audience builder, each condition maps to a field selector, an operator, and a value or threshold. The lookback window is a parameter on the event conditions. The profile condition (subscription_created = false) is a static filter. No JOIN required, because the builder handles the relationship between events and profiles internally.

At this point, before committing to a sync, check the audience size estimate. For a product with a few thousand active trial users, an audience matching these conditions might return 200-800 users. That's a meaningful size for customer match — below 100 users, both Google and Meta will decline to build a custom audience from the list, so narrow conditions on small user bases can silently fail. If the count is too low, widen the lookback window on pricing_page_viewed to 21 or 30 days.

Step 3: Configure the Google Ads Customer Match Sync

Google Ads customer match accepts a list of hashed contact information: SHA-256-hashed email addresses, phone numbers (normalized to E.164 format before hashing), or first/last name plus postal code combinations. For most SaaS products, email match is the right approach — your users authenticated with an email address and that's the identifier you have.

The sync pipeline needs to:

  1. Resolve each user_id in the audience to an email address (from the profiles table or identity store)
  2. Normalize email addresses: lowercase, trim whitespace
  3. Hash each email with SHA-256
  4. Format the output as a customer match upload (CSV or API payload)
  5. Call the Google Ads API to create or update the customer match list
  6. Schedule daily refresh so the audience stays current as users enter or exit the behavioral conditions

Steps 2-6 are what a behavioral audience sync tool handles. You define the audience rules in step 2 above; the platform handles the hashing, API authentication, list management, and refresh schedule. From the growth team's perspective, the output is a sync toggle: "push this audience to Google Ads Customer Match, refresh daily."

One practical note: Google typically takes 6-24 hours after upload to process a new customer match list and make it available for campaign targeting. Build this lead time into your campaign launch plan.

Step 4: Configure the Meta Custom Audience Sync

Meta's custom audience API accepts similar hashed contact data — SHA-256 email hashes, phone hashes, and also supports name/date-of-birth combinations for broader matching. For the same SaaS audience, email hashing is again the most reliable approach given that you have clean email data from account creation.

The main difference from Google customer match is that Meta's match rate tends to be somewhat lower for B2B SaaS audiences, because personal email addresses (used for Meta accounts) often differ from work email addresses (used for SaaS signups). If your product allows signup with personal emails, or if your user base skews toward small teams and indie developers who use personal emails for everything, match rates can be reasonable. If your product predominantly handles enterprise work emails, expect Meta match rates in the 40-60% range rather than the 70-85% you might see with consumer audiences.

The sync configuration is parallel to the Google setup: same audience definition, same email hashing, different destination API. Once both syncs are active, you have the same behavioral audience running in both ad platforms from a single source of truth — no manual CSV management, no reconciliation between two independently maintained lists.

Step 5: Set Refresh Cadence and Monitor Match Rates

A behavioral audience without automated refresh is a snapshot, not a living audience. Users who convert after you upload the list will continue to see ads unless the exclusion (the subscription_created = false condition) is re-evaluated on refresh. Users who hit the pricing page threshold for the first time after the upload won't be added. The audience goes stale within days.

Daily refresh is the standard cadence for high-intent behavioral audiences and is the right default for this use case. Hourly refresh is available on some platforms and makes sense for audiences that change rapidly — e.g., a cart abandonment audience for an e-commerce product where the relevant window is hours, not days. For SaaS upgrade intent with a 14-day lookback, daily is sufficient.

Monitor match rates after the first few syncs. A sudden drop in match rate (from 70% to 30%, for example) usually means either the audience size dropped significantly (check your event data for tracking gaps) or the email addresses being sent changed format (check for normalization issues). These are operational signals worth watching, and they're visible in your ad platform's audience details panel for customer match lists.

What You're Not Getting With This Approach

This workflow handles first-party behavioral audience sync well. It doesn't handle cross-device resolution for logged-out visitors — if someone browses your pricing page without being authenticated, they won't generate an event tied to a user_id, and they won't appear in this audience. That's a legitimate gap for products with significant anonymous-to-authenticated drop-off. Pixel-based audiences (standard website retargeting) are the complement for that use case, not a replacement for behavioral sync.

It also doesn't replace lookalike modeling. Customer match audiences tell the ad platform exactly who to reach. Lookalike audiences tell the platform to find people similar to your seed list. Both have their place in a full campaign structure; this walkthrough covers only the direct match layer.

The behavioral events are already being tracked. The audience definition is straightforward. The gap between having the data and using it for ad targeting is almost entirely a tooling and workflow gap — and that gap is closeable in an afternoon.

Build audiences from your own events →

Request access to Segmentloom