Facebook (Meta) Reach Estimate — Integration Plan

What It Is

The Meta Marketing API Reach Estimate endpoint returns the estimated monthly active audience size for any geographic area — how many Facebook/Instagram users are active in that location, optionally filtered by age, gender, and interests.

This gives us real online population per area, not census headcounts. For a digital marketing pitch, "there are 45,000 active social media users in your area aged 25-54" is far stronger than "the census population is 62,000".

API Details

Endpoint

GET /act_{AD_ACCOUNT_ID}/reachestimate

Key Parameters

Parameter Description
targeting_spec.geo_locations Country, region, city (by key), or coordinates + radius
targeting_spec.age_min / age_max Age range filter (default 18-65+)
targeting_spec.genders 1=male, 2=female
targeting_spec.interests Interest targeting (e.g. home improvement, legal services)
optimize_for IMPRESSIONS (recommended for audience sizing)

Example: Audience size for Cork city (15km radius)

curl -G \
  --data-urlencode 'targeting_spec={
    "geo_locations": {
      "cities": [{"key": "{CORK_KEY}", "radius": 15, "distance_unit": "kilometer"}]
    },
    "age_min": 25,
    "age_max": 54
  }' \
  -d 'optimize_for=IMPRESSIONS' \
  -d 'access_token={TOKEN}' \
  https://graph.facebook.com/v25.0/act_{AD_ACCOUNT_ID}/reachestimate

Response

{
  "data": {
    "users_lower_bound": 142000,
    "users_upper_bound": 167000,
    "estimate_dau": 95000,
    "estimate_mau": 155000,
    "estimate_mau_lower_bound": 142000,
    "estimate_mau_upper_bound": 167000
  }
}

Getting Irish City Keys

Use the Targeting Search API to look up city keys:

curl -G \
  -d 'type=adgeolocation' \
  -d 'location_types=["city"]' \
  -d 'q=Cork' \
  -d 'country_code=IE' \
  -d 'access_token={TOKEN}' \
  https://graph.facebook.com/v25.0/search

Returns city keys like {"key": "1005423", "name": "Cork", "region": "County Cork", ...}.

What You Need

  1. Meta Business Account with an ad account (any existing FCR ad account works)
  2. System User Token with ads_read permission (doesn't need ads_management — we're only reading estimates, not creating ads)
  3. Approved Facebook App — create via developers.facebook.com, request ads_read in App Review

Cost: Free. The Reach Estimate API has no per-call cost. Rate limits are generous (200 calls per hour per ad account).

Data Collection Strategy

Phase 1: County-Level Baseline

Query once for each of the 26 Irish counties:

  • Total audience (18-65+)
  • By age bracket: 18-24, 25-34, 35-44, 45-54, 55-64, 65+
  • By gender: male, female

That's 26 counties × 8 age/gender combos = 208 API calls (well within rate limits).

Phase 2: Town-Level for Key Markets

For the ~150 towns/cities already in our area intelligence data:

  • Total audience with 10km radius
  • Age 25-54 (primary commercial audience)

~150 API calls.

Phase 3 (Optional): Interest-Based Audiences

For top FCR categories (Electrician, Plumber, Solicitor, etc.), query interest-based audiences per county:

  • "Home improvement" interests in Cork
  • "Legal services" interests in Dublin
  • "Auto repair" interests in Galway

This shows the prospect how many people in their area are actively interested in their category.

Integration Architecture

BQ Table

CREATE TABLE `listingmanager-1529856313699.fcr_operations.facebook_reach_estimates` (
  location_type STRING,        -- 'county' or 'city'
  location_name STRING,        -- 'Cork', 'Dublin', 'Naas'
  location_key STRING,         -- Meta city/region key
  radius_km INT64,             -- NULL for county, 10-15 for city
  segment STRING,              -- 'all', 'male_25_34', 'female_35_44', 'interest_home_improvement'
  estimate_mau INT64,          -- Monthly active users (midpoint)
  estimate_mau_lower INT64,
  estimate_mau_upper INT64,
  estimate_dau INT64,          -- Daily active users
  collected_date DATE,
  latitude FLOAT64,            -- For city-level (join to map)
  longitude FLOAT64
);

Data Collection Script

New script: data/map/pull_facebook_reach.py (or .js)

  • Reads Meta API token from env
  • Loops through counties + towns
  • Queries Reach Estimate API for each segment
  • Outputs NDJSON for BQ load (or calls dashboard-bq-execute INSERT)

S3 / Map Data

New file: facebook_reach.json — uploaded to S3 alongside existing area data.

{
  "counties": {
    "Cork": {
      "total_mau": 385000,
      "age_25_54_mau": 210000,
      "male_mau": 185000,
      "female_mau": 200000,
      "dau": 260000
    }
  },
  "cities": {
    "Cork": { "radius_km": 15, "total_mau": 155000, "age_25_54_mau": 88000 },
    "Naas": { "radius_km": 10, "total_mau": 32000, "age_25_54_mau": 18000 }
  }
}

Prospect-Intel Integration

Add to prospect-intel.js Phase 1 parallel calls (alongside existing area intelligence):

// Facebook reach estimate for the locality
internal("dashboard-bq-execute", {
  sql: `SELECT segment, estimate_mau, estimate_dau
    FROM \`${DS}.fcr_operations.facebook_reach_estimates\`
    WHERE LOWER(location_name) LIKE LOWER("%${countyEsc}%")
    AND location_type = 'county'`
}, env)

Add to response under areaIntelligence:

areaIntel.facebook_reach = {
  total_mau: 385000,
  age_25_54_mau: 210000,
  _note: "Monthly active Facebook/Instagram users in this area. Use for pitch: 'There are 210,000 active social media users aged 25-54 in Cork — that's your addressable digital audience.'"
};

Skill / Proposal Integration

In prospect proposals, add a section:

Digital Audience: {county}
- {total_mau} monthly active social media users
- {age_25_54_mau} aged 25-54 (primary commercial audience)
- That's {pct}% of the census population actively online

The ratio of Facebook MAU to census population is itself a powerful metric — it tells you how "digitally active" an area is.

Area Map Integration

Add Layer 7 to the Leaflet.js map: Digital Audience Density

  • Overlay Facebook MAU at county level as a choropleth
  • Or at town level as proportional circles
  • Color by MAU-to-census ratio (digital penetration)

Refresh Schedule

Quarterly. Facebook audience sizes shift slowly — seasonal variation exists (summer dips, Q4 peaks) but month-to-month changes are small. Quarterly collection keeps it current without burning API calls.

This aligns with the existing area data refresh cadence:

  • Census 2022: static
  • Valuation/CRO: annual
  • New builds: quarterly (NDQ07)
  • Facebook reach: quarterly (new)

Comparison with Existing Data

Data Source What It Measures Granularity Freshness
CSO Census 2022 Total population, demographics Small Area (~100 HH) Static (2022)
Pobal Index Deprivation/affluence score Electoral Division Static (2022)
CRO Companies Active businesses County + NACE sector Annual
Valuation Office Commercial properties Individual property Annual
CSO New Builds Housing completions Eircode routing key Quarterly
Facebook Reach Active online users County / City+radius Quarterly

The Facebook data fills a gap none of the other sources cover: how many people in an area are reachable through digital channels. Census tells you who lives there. Facebook tells you who's online there.

Implementation Steps

Step Owner Effort
1. Create Meta System User + get ads_read token Cathal (Meta Business Manager) 30 min
2. Look up Irish city keys via Targeting Search API Script 1 API call per town
3. Build pull_facebook_reach.py collection script Claude Medium
4. Create BQ table + initial load Claude + BQ console Small
5. Add facebook_reach.json to S3 pipeline Claude Small
6. Add to prospect-intel.js response Claude Small
7. Update prospect skill + Ro.am system prompt Claude Small
8. Add map layer (optional) Claude Medium

Blocker: Step 1 — need the Meta API token. Everything else is straightforward once the token exists.

FCR Dashboard documentation · generated from docs/ · keep counts verified, not guessed.