explain_performance_anomaly

Google Ads Read

Explain why a performance metric changed using statistical analysis and historical context

Endpoint

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

Headers

Description

Explain why a performance metric changed using statistical analysis and historical context. ⚠️ IMPORTANT: This tool retrieves READ-ONLY data. Safe to call multiple times. Uses statistical analysis only (no ML models). 🎯 **What This Tool Does (Performance Agent - Phase 1 Feature 4):** - Explains why metrics changed (ROAS, CTR, CPC, conversions, conversion rate) - Compares current period to historical averages (30/60/90-day) - Identifies contributing factors with severity levels - Detects campaign changes (paused, new, budget changes) - Finds similar historical periods (seasonality detection) - Provides actionable recommendations to address issues **Returns comprehensive anomaly explanation:** - Current metric value vs historical averages - Deviation percentages (how much it changed) - Contributing factors: - CPC changes (>15% = auction competition shifts) - Conversion rate changes (>10% = landing page/seasonality issues) - Campaign changes (paused high-performers, new campaigns, budget changes) - Day-of-week patterns (weekend vs weekday effects) - Similar historical periods for context - Assessment (normal variation vs requires action) - Specific recommendations to fix the issue 🔍 **How Anomaly Detection Works:** **Historical Comparison:** - Compares current period to 30/60/90-day averages - ±15% deviation considered "normal variation" - >15% deviation flagged as requiring attention **Contributing Factor Detection:** 1. **CPC Changes** (>15% threshold) - Increased CPC = auction competition increased - Decreased CPC = auction competition decreased or bid adjustments 2. **Conversion Rate Changes** (>10% threshold) - Decreased = landing page issues, seasonality, audience quality - Increased = landing page improved, better targeting 3. **Campaign Changes:** - Paused high-performers (ROAS > 3.0x) = lost revenue driver - New campaigns (>$1K spend) = learning phase affecting overall performance - Budget changes (>20%) = delivery and auction participation affected 4. **Day-of-Week Patterns:** - Weekend-heavy periods often show different performance - Normal for B2C (higher weekend conversion) - Normal for B2B (lower weekend conversion) 5. **Seasonality Detection:** - Finds similar historical periods (±10% metric value) - Helps identify if drop is seasonal vs real issue **Parameters:** - metric: 'roas', 'ctr', 'cpc', 'conversions', 'conversion_rate' (REQUIRED) - period_start: Start date in YYYY-MM-DD format (REQUIRED) - period_end: End date in YYYY-MM-DD format (REQUIRED, max 30 days period) - customer_id: Optional (uses connected account if omitted) **Execution time:** 2-4 seconds (statistical analysis + database queries) **Data source:** campaign_daily_metrics table (updated nightly, 120-day retention) **Analysis method:** Statistical comparison (no ML models) **Trigger:** Reactive (user asks "why?"), not proactive alerts **Use this tool when:** - User asks "why did my ROAS drop?" - User asks "why did my CTR increase?" - User notices unexpected metric changes - User wants to understand performance fluctuations - After seeing performance changes in dashboards

Request body

All tool arguments are wrapped in an arguments object.

FieldTypeDescription
metricstring requiredMetric to explain: 'roas' (Return on Ad Spend), 'ctr' (Click-Through Rate), 'cpc' (Cost Per Click), 'conversions', or 'conversion_rate'
period_startstring requiredStart date of the anomaly period (ISO format: YYYY-MM-DD, e.g., '2025-01-15')
period_endstring requiredEnd date of the anomaly period (ISO format: YYYY-MM-DD, e.g., '2025-01-21'). Maximum 30 days between start and end.
customer_idstring optionalGoogle Ads customer ID. Required for multi-account users. Get from get_connections_status.
raw_databoolean optionalIf true, return ONLY raw metrics as a JSON code block (no severity labels, suggested bids/budgets, industry benchmarks, or optimization recommendations). Use when you run your own attribution model or want to minimize token usage. default: false

Example request

{
  "arguments": {
    "metric": "string",
    "period_start": "string",
    "period_end": "string",
    "customer_id": "string",
    "raw_data": false
  }
}

Example responses

200 — Success

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

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": "explain_performance_anomaly"
}

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": "explain_performance_anomaly",
  "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