get_reach_frequency

Google Ads Read

๐Ÿšจ **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work ar

Endpoint

POST https://api.adspirer.ai/api/v1/tools/get_reach_frequency/execute

Headers

Description

๐Ÿšจ **IF THIS TOOL RETURNS A QUOTA ERROR:** - The error message will include a clickable upgrade link - Show the FULL error message to the user (it contains the upgrade link) - DO NOT attempt to work around the error or use alternative data - DO NOT create campaigns or perform actions without valid tool data - STOP and direct the user to upgrade via the provided link Reach & frequency โ€” how many UNIQUE users your campaigns reached, and the average number of times each person saw your ads. This tool retrieves READ-ONLY data via 1 live GAQL query (cached 5 min in Redis). Safe to call multiple times. **Why this tool:** `get_campaign_performance` reports impressions but not unique reach. This is the only tool that returns `unique_users` (de-duplicated people reached) and `average_impression_frequency_per_user` (the "Avg. impr. freq. / user" column in the Google Ads UI) โ€” the direct signal for creative-fatigue and rotation decisions on YouTube / Demand Gen / Video campaigns, instead of proxying frequency from CPM/CTR trends. **Returns one row per campaign** (sorted by impressions): - `campaign_id`, `campaign_name`, `campaign_type`, `status` - `impressions`, `unique_users`, `avg_impression_frequency_per_user` **Google constraints (surfaced honestly, not bugs):** - Reach metrics are **campaign-level only** โ€” Google REJECTS them at the ad-group level, so this tool cannot break reach down by ad group. - Reach is populated for reach-eligible campaign types (Demand Gen, Video/YouTube, Performance Max, Display). Search campaigns typically report 0 unique users. - Google reports unique reach only for a **trailing ~92-day window**; a longer window silently returns zeros, so the lookback is clamped to 92 days (the tool tells you when it clamped). - `unique_users` is de-duplicated over the window and is **NOT summed across campaigns** (the same person can be reached by more than one campaign). **These are the account's own measured numbers โ€” the tool renders NO verdict and invents no "healthy frequency" threshold.** Whether a given frequency is too high depends on the campaign and goal; the tool reports the number and leaves the call to you. **Parameters:** - customer_id: Optional (uses connected account if omitted) - lookback_days: 7, 30, 60, 90 (clamped to โ‰ค92). Ignored when both start_date and end_date set. - start_date / end_date: YYYY-MM-DD (override lookback_days when both provided; clamped to last 92 days) - campaign_id: Optional โ€” scope to one campaign **Execution time:** 1-3 seconds (1 GAQL query, then cached 5 min) **Use this tool when:** - User asks "what's my reach / frequency?", "how many unique users did I reach?", "how often is each person seeing my ad?" - User is deciding whether to rotate/refresh creative on a YouTube or Demand Gen campaign (frequency is the fatigue signal) - User wants unique reach instead of raw impressions

Request body

All tool arguments are wrapped in an arguments object.

FieldTypeDescription
start_datestring optionalStart date (YYYY-MM-DD). If provided with end_date, overrides lookback_days for custom date range queries.
end_datestring optionalEnd date (YYYY-MM-DD). If provided with start_date, overrides lookback_days for custom date range queries.
date_rangestring optionalDate range preset: 'last_7_days', 'last_14_days', 'last_30_days', 'last_60_days', 'last_90_days'. Overrides lookback_days. Ignored if start_date/end_date are provided.
raw_databoolean optionalIf true, return ONLY raw metrics as a JSON code block (spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, ROAS by campaign/ad/date). Strips severity labels, suggested bids/budgets, industry benchmarks, and optimization recommendations. Use when you run your own attribution model or want to minimize token usage. default: false
customer_idstring optionalGoogle Ads customer ID. Required for multi-account users. Get from get_connections_status.
lookback_daysinteger optionalNumber of days to analyze (7, 30, 60, 90). Clamped to Google's ~92-day reach limit. Default 30. Ignored when both start_date and end_date are provided. default: 30
campaign_idstring optionalOptional. Scope to a single campaign (from list_campaigns). Omit for all campaigns with reach data.

Example request

{
  "arguments": {
    "start_date": "string",
    "end_date": "string",
    "date_range": "string",
    "raw_data": false,
    "customer_id": "string",
    "lookback_days": 30
  }
}

Example responses

200 โ€” Success

{
  "success": true,
  "data": {
    "text": "(tool-specific textual output for get_reach_frequency)",
    "quota": {
      "used": 42,
      "limit": 150,
      "tier": "plus",
      "period_end": "2026-05-01"
    }
  },
  "tool": "get_reach_frequency"
}

400 โ€” Tool-level error (bad arguments / multi-account selection)

{
  "success": false,
  "error": "You have 25 meta_ads accounts connected. Please specify which account to use by passing the ad_account_id parameter:\n  - Acme Holdings (ad_account_id=\"act_123456789\")\n  - Acme EU (ad_account_id=\"act_987654321\")",
  "is_error": true,
  "tool": "get_reach_frequency"
}

402 โ€” Quota exhausted

{
  "success": false,
  "error": "\ud83d\udea8 Monthly limit reached (150/150 tool calls on Plus tier).\nUpgrade to Pro at https://adspirer.ai to keep building.",
  "is_error": true,
  "tool": "get_reach_frequency",
  "quota": {
    "used": 150,
    "limit": 150,
    "tier": "plus",
    "period_end": "2026-05-01",
    "upgrade_url": "https://adspirer.ai"
  }
}

Try it live


Adspirer REST API โ€” get an API key at adspirer.ai/keys ยท adspirer.ai