API Reference βΊ Google Ads βΊ analyze_search_terms
analyze_search_terms
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/analyze_search_terms/execute
Headers
Authorization: Bearer sk_live_... β your Adspirer API key (required)
Content-Type: application/json (required)
Idempotency-Key: <uuid> β recommended for write operations to make retries safe
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
Discover keyword opportunities and optimize match types by analyzing actual search terms.
β οΈ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. Google Ads only - NOT available for TikTok.
π― **What This Tool Does (Performance Agent - Phase 1 Feature 3):**
- Identifies OPPORTUNITY keywords: Converting search terms NOT in your keyword list
- Identifies NEGATIVE keywords: Expensive terms with zero conversions
- Analyzes MATCH TYPE performance: Exact vs Phrase vs Broad efficiency
- Provides specific recommendations with suggested bids and match types
- Ranks opportunities by profit potential (not just ROAS)
**Returns comprehensive keyword intelligence:**
- Top 20 opportunity keywords with suggested bids and match types
- Top 20 negative keyword candidates with wasted cost breakdown
- Match type performance comparison (Exact/Phrase/Broad)
- BroadβExact conversion recommendations
- Total opportunity value and wasted spend amounts
- Actionable recommendations for immediate implementation
π **What Search Term Mining Reveals:**
**Opportunity Keywords (Money Left on Table):**
- Search terms that ARE converting but you're NOT bidding on them directly
- These are queries triggering your ads via Broad/Phrase match, but should be added as Exact keywords
- Example: User searches "enterprise security software pricing" β converts β but you only have "security software" as keyword
- **Action:** Add high-converting search terms as new keywords with suggested bids
**Negative Keywords (Money Wasted):**
- Search terms costing >$10 with ZERO conversions
- Low-intent queries like "free", "download", "crack", "how to"
- Example: "free security software download" β 120 clicks, $540 spent, 0 conversions
- **Action:** Add as negative keywords to stop wasting budget
**Match Type Optimization:**
- Compares performance of Exact vs Phrase vs Broad match
- Identifies Broad keywords that should be converted to Exact for better control
- Example: Broad "security software" has 45% wasted spend, but top search terms have 20x ROAS
- **Action:** Convert high-performing Broad keywords to Exact match
**Parameters:**
- lookback_days: 7, 30, 60, 90, or 120 days (default: 30)
- start_date: Optional start date (YYYY-MM-DD). Overrides lookback_days when used with end_date.
- end_date: Optional end date (YYYY-MM-DD). Overrides lookback_days when used with start_date.
β οΈ DATE CLARIFICATION: If the user's date request is vague or ambiguous (e.g., "March to June" without a year, "last quarter", "recently", "a few months ago"), ask the user to specify exact dates before calling this tool. Do not assume or guess dates.
- analysis_type: 'opportunities', 'negatives', 'match_types', 'all', or **'raw_report'** (default: 'all')
- Use **'raw_report'** when the user wants to SEE their actual search terms β the words customers type into Google
- force_refresh: true to trigger immediate API collection (default: false, uses cached data)
- customer_id: Optional (uses connected account if omitted)
- **campaign_id**: Optional β filter search terms to a specific campaign (get from list_campaigns)
- **page**: Page number for raw_report pagination (default: 1)
- **page_size**: Results per page for raw_report (1-100, default: 50)
- **sort_by**: Sort for raw_report: 'cost' (default), 'clicks', 'impressions', 'conversions'
- **min_clicks**: Minimum clicks filter for raw_report (default: 0)
**Execution time:** 1-3 seconds (cached database query)
**Data source:** search_term_daily_metrics table (updated nightly, 120-day retention)
**β‘ RAW REPORT PAGINATION CONTRACT:**
- When using analysis_type='raw_report', results are paginated
- Check `pagination.has_more` β if true, call again with next `page`
- Continue until `has_more` is false, then present consolidated results
- Use `campaign_id` to focus on a specific campaign's search terms
**Use this tool when:**
- User asks "what keywords should I add?"
- User wants to find wasted spend at keyword level
- User asks "what should I add as negative keywords?"
- User wants to improve match type efficiency
- User asks "which Broad keywords should be Exact?"
- User wants to discover hidden keyword opportunities
- **User asks "show me my search terms" or "what are people searching for?"** β use analysis_type='raw_report'
- **User asks "show me search terms for campaign X"** β use analysis_type='raw_report' with campaign_id
β οΈ **Platform Limitation:**
This tool ONLY works for Google Ads. TikTok Ads does not provide search term data due to privacy restrictions.
π **AFTER calling this tool, help the user understand:**
**Opportunity Keywords:**
- **What it means:** These are winning search terms you're missing
- **Profit potential:** Shows expected additional profit if added
- **Suggested action:** Add as new keywords with recommended bid and match type
- **Priority:** Start with highest opportunity_value (profit potential)
**Example:**
Search term: "enterprise security software pricing"
- 8 conversions, $240 cost, $4,800 value
- Opportunity Value: $4,560 profit potential
- Suggested Bid: $6.00 (based on current CPC and ROAS)
- Suggested Match Type: EXACT (high intent, proven converter)
- **Action:** Add this as an Exact match keyword with $6 bid
**Negative Keywords:**
- **What it means:** These queries waste money and never convert
- **Cost:** Total wasted spend on non-converting terms
- **Common patterns:** "free", "download", "crack", "review", "how to"
- **Action:** Add as negative keywords (campaign or account level)
**Example:**
Search term: "free security software"
- 120 clicks, $540 wasted, 0 conversions
- Reason: Low purchase intent (free)
- **Action:** Add "free" as negative keyword at campaign level
**Match Type Performance:**
- **Exact:** Tightest control, lowest waste, highest ROAS (recommended)
- **Phrase:** Moderate flexibility, some waste, decent ROAS
- **Broad:** Most volume, highest waste, lowest ROAS (use sparingly)
**Example Analysis:**
- Exact: 450 keywords, ROAS 4.8x, 2% wasted spend β
- Phrase: 280 keywords, ROAS 3.2x, 8% wasted spend β οΈ
- Broad: 120 keywords, ROAS 1.8x, 45% wasted spend π΄
**Quick Actions:**
1. Add top 5 opportunity keywords as Exact match
2. Block top 10 negative keywords at campaign level
3. Convert high-performing Broad keywords to Exact
4. Review Phrase keywords with >10% wasted spend
**Visualization Tip:**
For opportunity keywords, suggest creating a scatter plot (x=ROAS, y=Spend, size=conversions) to visualize profit potential.
**Implementation Steps:**
1. Review top opportunities and negatives
2. Start with 5-10 new keywords (don't overwhelm account)
3. Add negatives in batches (test impact over 7 days)
4. Convert BroadβExact gradually (monitor volume drop)
5. Re-run analysis monthly to discover new opportunities
**Best Practices:**
- Focus on opportunity_value (profit) not just ROAS
- Start with Exact match for all new keywords (tightest control)
- Add negatives at campaign level first (easier to undo than account level)
- Monitor match type distribution: Aim for 60%+ Exact, 30% Phrase, 10% Broad
- Review search terms every 2 weeks during active optimization
π¬ **Community**: For keyword optimization discussions, visit our Discord: https://discord.gg/dH3Qt4YS
Request body
All tool arguments are wrapped in an arguments object.
| Field | Type | Description |
start_date | string optional | Start date (YYYY-MM-DD). If provided with end_date, overrides lookback_days for custom date range queries. |
end_date | string optional | End date (YYYY-MM-DD). If provided with start_date, overrides lookback_days for custom date range queries. |
date_range | string optional | Date 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_data | boolean optional | If 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 |
lookback_days | integer optional | Number of days to analyze search term data (7, 30, 60, 90, or 120 days). Default is 30 days. default: 30 |
analysis_type | string optional | Type of analysis: 'opportunities', 'negatives', 'match_types', 'all', or 'raw_report'. Use 'raw_report' to see all actual search terms with metrics (what Vijay wants). Default is 'all'. default: "all" |
force_refresh | boolean optional | If true, triggers immediate API collection from Google Ads (not yet implemented - currently uses cached data). Default is false. default: false |
customer_id | string optional | Google Ads customer ID. Required for multi-account users. Get from list_connected_accounts. |
campaign_id | string optional | Optional campaign ID to filter search terms to a specific campaign. Get from list_campaigns. |
page | integer optional | Page number for raw_report (1-based). Default: 1 default: 1 |
page_size | integer optional | Results per page for raw_report (1-100). Default: 50 default: 50 |
sort_by | string optional | Sort field for raw_report: 'cost' (default), 'clicks', 'impressions', 'conversions' default: "cost" |
min_clicks | integer optional | Minimum clicks filter for raw_report. Default: 0 (show all) default: 0 |
Example request
{
"arguments": {
"start_date": "string",
"end_date": "string",
"date_range": "string",
"raw_data": false,
"lookback_days": 30,
"analysis_type": "all"
}
}
Example responses
200 β Success
{
"success": true,
"data": {
"text": "(tool-specific textual output for analyze_search_terms)",
"quota": {
"used": 42,
"limit": 150,
"tier": "plus",
"period_end": "2026-05-01"
}
},
"tool": "analyze_search_terms"
}
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": "analyze_search_terms"
}
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": "analyze_search_terms",
"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