Skip to main content

Overview

Creative fatigue is the silent killer of ad accounts. CTR drops 0.1% per day, frequency ticks up, CPC quietly inflates — and by the time you notice in Ads Manager, you’ve burned through budget. This skill watches for those signals daily and flags creatives that need rotation.

How It Works

Fatigue Signals (ranked by severity)

SignalThresholdSeverity
CTR dropping 3+ days in a row>20% decline from peak🔴 Critical
Frequency above 3.5Audience seeing ad too often🟡 Warning
CPC rising 3+ days in a row>15% increase from baseline🟡 Warning
Impressions decliningAd losing delivery🟠 Monitor

Reports

Fatigue Check

Daily scan of all active ads for fatigue signals. Invocation:
"Check for creative fatigue"
"Are any ads getting stale?"
Script:
./scripts/creative-monitor.sh fatigue-check
Example Output:
😴 Creative Fatigue Scan
========================

Pulling 7-day daily breakdown for all active ads...

Day-over-day CTR trends:

🔴 FATIGUED Notes App Hero (ID: 23847111111111)
  CTR trend: 2.1% → 1.9% → 1.7% → 1.5% → 1.3% → 1.2% → 1.0%
  Freq: 4.2

🟡 HIGH FREQ Receipt Screenshot v2 (ID: 23847222222222)
  CTR trend: 1.8% → 1.9% → 1.8% → 1.7% → 1.7% → 1.6% → 1.6%
  Freq: 3.8

✅ OK Kitchen Still Life - Fear (ID: 23847333333333)
  CTR trend: 1.2% → 1.3% → 1.4% → 1.3% → 1.3% → 1.2% → 1.3%
  Freq: 2.1

Creative Leaderboard

Rank all active creatives by efficiency (CTR × spend volume). Invocation:
"Rank my creatives"
"Which creatives are strongest?"
Script:
./scripts/creative-monitor.sh weekly-report
Example Output:
📊 Weekly Creative Health Report
=================================

Ad Name                          Spend      Impressions  Clicks  CTR    CPC     Frequency
Receipt Screenshot - Fear        $287.12    125,438      2,885   2.3%   $0.41   2.8
Notes App - Money Hook           $312.45    173,611      3,125   1.8%   $0.62   3.1
Kitchen Still Life v3            $198.45    282,786      1,980   0.7%   $1.12   4.2

Rotation Recommendations

Based on fatigue signals, recommend which creatives to pause and when new ones are needed. Invocation:
"What needs to be rotated?"
"Which ads need fresh creative?"

The Check Script

./scripts/creative-monitor.sh fatigue-check

Fatigue Check Implementation

The script pulls daily time-series data and analyzes CTR trends:
social --no-banner marketing insights $ACCOUNT_ARG \
  --preset last_7d --level ad --time-increment 1 \
  --json --fields "ad_name,ad_id,date_start,impressions,clicks,ctr,cpc,frequency,spend"
Then processes day-over-day changes:
# Detects fatigue if:
# - CTR dropped >20% from 3 days ago
# - Frequency > 3.5
if ($ctrs[-1] < $ctrs[-3] * 0.8) then "🔴 FATIGUED"
elif ($freqs[-1] > 3.5) then "🟡 HIGH FREQ"
else "✅ OK"

Track Individual Ad

Monitor a specific ad’s performance over time:
./scripts/creative-monitor.sh track-ad 23847111111111
Output:
📈 Tracking Ad: 23847111111111
========================

Ad Name                Date       Impressions  Clicks  CTR    CPC     Freq   Spend
Notes App Hero         2026-02-20 24,782      522     2.1%   $0.58   1.2    $302.76
Notes App Hero         2026-02-21 25,118      477     1.9%   $0.61   1.8    $291.03
Notes App Hero         2026-02-22 24,893      423     1.7%   $0.65   2.3    $274.95
Notes App Hero         2026-02-23 24,501      368     1.5%   $0.72   2.9    $264.96
Notes App Hero         2026-02-24 23,987      312     1.3%   $0.81   3.4    $252.72
Notes App Hero         2026-02-25 23,442      281     1.2%   $0.89   3.9    $250.09
Notes App Hero         2026-02-26 22,891      229     1.0%   $0.98   4.2    $224.42

↑ Clear fatigue pattern: CTR declining, frequency climbing, CPC rising

Invocation Pattern

  1. Pull ad-level insights with daily time increment (--time-increment 1)
  2. Calculate day-over-day CTR, CPC, and frequency trends
  3. Flag any ad showing fatigue signals
  4. Compare against benchmarks in ad-config.json
  5. Present findings with clear severity ratings
  6. Recommend rotation schedule if fatigue detected
  7. Log findings to workspace/brand/learnings.md

Integration with Other Skills

The Ad Creative Monitor integrates with the broader Meta Ads Copilot ecosystem.

Workflow

1. ad-creative-monitor → Detects "Notes App Hero" fatigued (CTR dropped 40%)
2. ad-copy-generator   → Write 3 new body variants matched to the same image
3. ad-upload           → Push fresh creative, attach to existing ad
4. meta-ads            → Monitor new creative performance next 7 days

Data Flow

social marketing insights \
  --preset last_7d \
  --level ad \
  --time-increment 1 \
  --fields "ad_name,ad_id,date_start,ctr,frequency,cpc"

Benchmarks

Read ad-config.json for target benchmarks. If not configured, use sensible defaults:
  • Target CTR: > 1.0%
  • Max frequency: 3.5
  • Fatigue signal: CTR dropping > 20% over 3 days
  • Critical fatigue: CTR dropping > 40% over 7 days

Writes to Brand Memory

workspace/brand/learnings.md
Logs fatigue patterns and creative lifespan data:
  • Which creative formats fatigue fastest
  • Average CTR decline rate by campaign type
  • Optimal rotation schedule based on historical data
  • Frequency thresholds by audience size
Example Entry:
## 2026-02-26 — Creative Fatigue Analysis

**Notes App Hero (23847111111111)** — Fatigued after 7 days
- CTR declined 52% (2.1% → 1.0%)
- Frequency hit 4.2 by day 7
- Pattern: Notes app format has 5-6 day lifespan in prospecting
- Action: Rotated to fresh copy variants (see ad-upload log)

**Learning:** Notes app creatives fatigue 30% faster than receipt screenshots in this account. Consider more aggressive rotation (5 days vs 7 days).

Command Reference

fatigue-check

Scan all active ads for fatigue signals.
./scripts/creative-monitor.sh fatigue-check [--account act_123]

weekly-report

Rank all creatives by performance over the last 7 days.
./scripts/creative-monitor.sh weekly-report [--account act_123]

track-ad

Monitor a specific ad’s daily performance.
./scripts/creative-monitor.sh track-ad AD_ID [--account act_123]

Direct social-cli Integration

All scripts wrap social-cli commands. You can run these directly for custom analysis.
# Get daily ad-level data
social marketing insights \
  --preset last_7d \
  --level ad \
  --time-increment 1 \
  --fields "ad_name,ad_id,date_start,impressions,clicks,ctr,cpc,frequency,spend" \
  --json

# Filter specific ad by ID
social marketing insights \
  --preset last_14d \
  --level ad \
  --time-increment 1 \
  --filtering '[{"field":"ad.id","operator":"EQUAL","value":"23847111111111"}]' \
  --table

Next Steps

  • Meta Ads — Run daily checks to identify ads that need monitoring
  • Ad Copy Generator — Generate fresh copy when fatigue is detected
  • Ad Upload — Push refreshed creative to fatigued ads

Build docs developers (and LLMs) love