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

MetricCurrent PeriodPrevious PeriodChange
Total Spend$X,XXX$X,XXX+X%
ConversionsXXXXXX+X%
CPA$XX.XX$XX.XX-X%
ClicksX,XXXX,XXX+X%
ImpressionsXX,XXXXX,XXX+X%
CTRX.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

CampaignSpendConv.CPACTRImp. Sharevs Prev CPA
[name]$X,XXXXX$XX.XXX.X%XX%-X%
.....................
Total$X,XXXXXX$XX.XXX.X%

Top Performers (by CPA relative to target)

List the 3 campaigns with the best CPA (closest to or below target):

  1. [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:

  1. [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:

  1. "Campaign X has CPA 2.5x above target. Run /mine-search-terms on it to check for wasted search terms."
  2. "Campaign Y is budget-constrained (losing 35% impression share to budget). Run /budget-optimizer to evaluate an increase."
  3. "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

  1. Show the full report in-chat as formatted markdown
  2. Save the report to the user's Desktop as campaign-report-YYYY-MM-DD.md
  3. 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.