campaign-report
Generate a campaign performance report with key metrics and trends. Pulls 30 days of data, compares to previous period, highlights anomalies, and identifies top and bottom performers. Use when: "/campaign-report", "campaign report", "performance report", "how are my ads doing", "monthly report", "ad performance summary", "campaign metrics".
Campaign Report Generator
You are generating a campaign performance report. Pulls the last 30 days, compares to the previous 30-day period, highlights anomalies, and ranks campaigns by performance.
Before you start, read the ads-playbook skill to load target CPA and business context.
Step 1: Pull Current Period Data (Last 30 Days)
SELECT
campaign.name,
campaign.status,
campaign.advertising_channel_type,
metrics.cost_micros,
metrics.conversions,
metrics.cost_per_conversion,
metrics.clicks,
metrics.impressions,
metrics.ctr,
metrics.average_cpc,
metrics.search_impression_share,
metrics.conversions_value
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
AND campaign.status = 'ENABLED'
ORDER BY metrics.cost_micros DESC
Step 2: Pull Previous Period Data (30-60 Days Ago)
Use explicit date ranges for the comparison period:
SELECT
campaign.name,
metrics.cost_micros,
metrics.conversions,
metrics.cost_per_conversion,
metrics.clicks,
metrics.impressions,
metrics.ctr,
metrics.average_cpc,
metrics.search_impression_share
FROM campaign
WHERE segments.date BETWEEN '{30_days_ago}' AND '{60_days_ago}'
AND campaign.status = 'ENABLED'
ORDER BY metrics.cost_micros DESC
Calculate the date range: if today is 2026-03-25, current period is 2026-02-23 to 2026-03-25, previous period is 2026-01-24 to 2026-02-22.
Cost conversion: Divide cost_micros, cost_per_conversion, and average_cpc by 1,000,000.
Step 3: Pull Daily Trend Data
For trend analysis and anomaly detection:
SELECT
segments.date,
metrics.cost_micros,
metrics.conversions,
metrics.clicks,
metrics.impressions
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
AND campaign.status = 'ENABLED'
ORDER BY segments.date ASC
Step 4: Generate the Report
Structure the report as markdown. Save to the user's Desktop as campaign-report-YYYY-MM-DD.md.
Report Structure
Campaign Performance Report Period: [start date] to [end date] Generated: [today's date]
Account Overview
| Metric | Current Period | Previous Period | Change |
|---|---|---|---|
| Total Spend | $X,XXX | $X,XXX | +X% |
| Conversions | XXX | XXX | +X% |
| CPA | $XX.XX | $XX.XX | -X% |
| Clicks | X,XXX | X,XXX | +X% |
| Impressions | XX,XXX | XX,XXX | +X% |
| CTR | X.X% | X.X% | +X.Xpp |
| Avg. CPC | $X.XX | $X.XX | +X% |
Color-code changes in the chat:
- Improvements (lower CPA, higher conversions, higher CTR): positive
- Declines: flag them
Note whether CPA is above or below the target from the ads-playbook.
Campaign Breakdown
| Campaign | Spend | Conv. | CPA | CTR | Imp. Share | vs Prev CPA |
|---|---|---|---|---|---|---|
| [name] | $X,XXX | XX | $XX.XX | X.X% | XX% | -X% |
| ... | ... | ... | ... | ... | ... | ... |
| Total | $X,XXX | XXX | $XX.XX | X.X% |
Top Performers (by CPA relative to target)
List the 3 campaigns with the best CPA (closest to or below target):
- [Campaign] - CPA: $XX vs $XX target. X conversions. Why it works: [brief note on what's driving performance]
Bottom Performers (by CPA relative to target)
List the 3 campaigns with the worst CPA:
- [Campaign] - CPA: $XX vs $XX target (Xx above target). $XXX spent. Potential issue: [brief diagnosis]
Anomalies and Trends
Scan the daily trend data for:
- Spend spikes or drops: Any day with spend >2x or <0.5x the daily average
- Conversion droughts: 3+ consecutive days with zero conversions in any campaign
- CTR shifts: Sudden CTR changes (>30% swing day-over-day)
- Impression share drops: Significant loss of impression share vs previous period
For each anomaly:
[Date]: [What happened] [Campaign name] saw a X% drop in conversions while spend remained flat. Possible causes: landing page issue, competitor activity, or audience fatigue.
Recommendations
Based on the data, provide 3-5 specific, actionable recommendations. Examples:
- "Campaign X has CPA 2.5x above target. Run /mine-search-terms on it to check for wasted search terms."
- "Campaign Y is budget-constrained (losing 35% impression share to budget). Run /budget-optimizer to evaluate an increase."
- "Campaign Z has strong metrics but low volume. Consider expanding keywords or increasing bids."
Reference other skills in the plugin where relevant.
Step 5: Present and Save
- Show the full report in-chat as formatted markdown
- Save the report to the user's Desktop as
campaign-report-YYYY-MM-DD.md - Confirm the file location
Edge Cases
- No previous period data: Skip the comparison columns. Note that this is the first reporting period.
- No MCP connected: Ask the user to paste campaign data or export from Google Ads. Generate the report from that.
- Single campaign: Still generate the full report structure, just with one row in the campaign breakdown.
- Meta Ads: Pull from Meta Ads API. Metrics map differently: use "results" instead of "conversions", "cost per result" instead of "CPA", "reach" and "frequency" instead of impression share.
- Apple Search Ads: Pull from the Campaign Report endpoint. Use "installs" instead of "conversions", "cost per install (CPI)" instead of "CPA", "share of voice" instead of "impression share".
- Multi-platform: If multiple platforms are connected, generate separate sections for each and include a combined summary at the top.