FB/IG Audience Reach (manual)
What It Is
Section titled “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
Section titled “API Details”Endpoint
Section titled “Endpoint”GET /act_{AD_ACCOUNT_ID}/reachestimateKey Parameters
Section titled “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)
Section titled “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}/reachestimateResponse
Section titled “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
Section titled “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/searchReturns city keys like {"key": "1005423", "name": "Cork", "region": "County Cork", ...}.
What You Need
Section titled “What You Need”- Meta Business Account with an ad account (any existing FCR ad account works)
- System User Token with
ads_readpermission (doesn’t needads_management— we’re only reading estimates, not creating ads) - Approved Facebook App — create via developers.facebook.com, request
ads_readin 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
Section titled “Data Collection Strategy”Phase 1: County-Level Baseline
Section titled “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
Section titled “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
Section titled “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
Section titled “Integration Architecture”BQ Table
Section titled “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
Section titled “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-executeINSERT)
S3 / Map Data
Section titled “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
Section titled “Prospect-Intel Integration”Add to prospect-intel.js Phase 1 parallel calls (alongside existing area intelligence):
// Facebook reach estimate for the localityinternal("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
Section titled “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 onlineThe ratio of Facebook MAU to census population is itself a powerful metric — it tells you how “digitally active” an area is.
Area Map Integration
Section titled “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
Section titled “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
Section titled “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
Section titled “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.