---
name: creative-fatigue-monitor
description: "Watch frequency and CTR/CPA decay per ad; flag creatives that have fatigued and should be refreshed, with the evidence. Read-only, alert-only."
license: MIT
compatibility: "Works with any Agent-Skills-compatible AI (Claude, ChatGPT, Cursor, Codex, and more). Ad-account actions run through Adspirer."
metadata:
  author: "Adspirer"
  version: "1.0.0"
  adspirer_category: "ad-ops-optimization"
  adspirer_source: "https://www.adspirer.com/skills/creative-fatigue-monitor"
  adspirer_connection_url: "https://adspirer.ai/sign-up"
  adspirer_primary_keyword: "facebook ad fatigue"
  adspirer_secondary_keywords: "creative fatigue, ad fatigue analysis"
  adspirer_launch_wave: "1"
  adspirer_kind: "agent"
  adspirer_level: "operator"
  adspirer_platforms: "meta,tiktok"
  adspirer_supported_clients: "claude,claude-code,chatgpt,codex,cursor,gemini,windsurf"
  adspirer_summary: "Watch frequency and CTR/CPA decay per ad; flag creatives that have fatigued and should be refreshed, with the evidence. Read-only, alert-only."
  adspirer_connections_required: "adspirer"
  adspirer_connections_optional: ""
---

# Creative Fatigue Monitor

## Use this when

You're running 3+ active ad sets/campaigns per platform with creatives that have been live 5+ days and want an early warning before performance decay shows up in blended account numbers. Best run 2-3x/week on always-on accounts (prospecting or retargeting) — not useful in the first 3-4 days of an ad's life (Meta learning phase) or on accounts with <1,000 impressions/day per ad, where frequency and CTR are too noisy to trust. Most valuable for DTC/lead-gen accounts running the same 3-8 creatives for weeks, where nobody is watching frequency daily and the first sign of fatigue is usually a CPA spike someone notices too late.

## What you need

Meta and/or TikTok ad account(s) connected via Adspirer with at least one active campaign that's been running 5+ days with stable daily spend (so frequency/CTR trends are readable, not noise). Know your platform's optimization event (purchase, lead, install) so CPA decay is measured against the right conversion, not a proxy. Optional but useful: your own fatigue thresholds if they differ from platform norms — e.g., a retargeting account expects higher frequency ceilings than cold prospecting, so a blanket "frequency > 3" rule will false-flag it.

## Procedure

1. Pull the account's active ad set structure and confirm which ads are still in delivery (not paused, not learning-limited) — fatigue analysis on a paused or newly-launched ad is meaningless.
2. **Connect Adspirer (the ads connection):** when you reach a step that touches a live ad account, connect Adspirer first. In Claude Code, run `/plugin marketplace add anthropics/claude-plugins-community` then `/plugin install adspirer-ads-agent@claude-community`. In claude.ai or ChatGPT, add the Adspirer connector from https://www.adspirer.com/docs/ai-clients. Any other agent: follow https://www.adspirer.com/docs/ai-clients for your client. Sign-in link for the user: https://adspirer.ai/sign-up. Do not proceed with live ad-account steps until the connection is confirmed.
3. For each active ad with 5+ days of delivery, pull daily-granularity frequency, CTR (link click-through for Meta, or the platform-equivalent outbound click rate for TikTok), CPA/CPL against the account's actual optimization event, and spend — going back 14 days where available, 7 minimum.
4. Segment ads by delivery volume before judging fatigue: an ad with under ~1,000 impressions/day is too thin for CTR/frequency trend to be reliable — flag it as "insufficient data" rather than forcing a verdict either way.
5. For each ad with sufficient volume, compute the trend, not a single-day snapshot: CTR and CPA compared as a trailing-3-day average against the trailing-3-day average from the prior week (or against the first 3 days of the flight if under 10 days old) — single-day dips are noise, especially around weekends or platform algorithm re-optimization events.
6. Apply the fatigue signature, not any one metric alone — the classic pattern is frequency climbing past ~3.5-4x on Meta prospecting (or ~2.5-3x on TikTok, which decays faster) WHILE CTR is down 20%+ off its trailing average WHILE CPA is up 20%+ in the same window. One metric moving alone (e.g., frequency up but CTR flat) is often just audience saturation setting in slowly, not full fatigue — note it as "watch" not "fatigued."
7. Cross-check for confounds before flagging: did the advertiser change budget or bid strategy in this window (budget jumps push frequency and CPA around independent of creative wear-out), is the ad set still in or re-entering Meta's learning phase (post-edit resets reduce reliability of the CTR/CPA read for ~3-7 days or 50 conversions), and did the audience size shrink (a narrowed custom audience will show rising frequency that's a targeting artifact, not creative fatigue)? Exclude or caveat any ad where a confound is present in the same window as the metric decay.
8. Rank flagged creatives by spend-at-risk (daily spend × days since decay onset) so the highest-dollar-impact fatigue surfaces first, not just the most statistically "fatigued."
9. Produce the fatigue report: per flagged ad, show the actual numbers (frequency trend, CTR trend, CPA trend, days live, spend/day) side by side with the platform average for that ad set, plus a one-line verdict (fatigued / watch / insufficient data) and the evidence it's based on — never a bare "this is fatigued" without the underlying trend.

## Fixed checks

Every frequency, CTR, and CPA number in the report is pulled live from the platform in the same run — never carried over from a prior report or estimated. Confirm each flagged ad is still active (not already paused by the advertiser) at report time, so the alert isn't stale. Confirm the optimization event used for CPA matches the ad set's actual configured conversion event (pulled from the ad set, not assumed) — mixing up "purchase" vs "add to cart" CPA silently invalidates the whole verdict. Confirm the comparison window has no budget or bid-strategy change logged in the same period (via change history where the platform exposes it) before calling it fatigue rather than a budget-driven metric shift. Confirm delivery volume (impressions/day) meets the minimum threshold used for that ad before including it in a firm verdict, not just an "insufficient data" note.

## Stop conditions

Success: report delivered listing every active ad status (fatigued / watch / healthy / insufficient data) with evidence, and at least one fatigued or watch flag, or an explicit "no fatigue detected this cycle" if all clear. No-op: fewer than 2 active ads with 5+ days delivery and sufficient volume exist in the account — report that monitoring isn't yet viable and state when it will be (e.g., after day 5 or once daily impressions clear the threshold). Blocked: Adspirer connection fails, ad platform API returns errors, or account has no active campaigns — report the specific failure, do not guess at a verdict. Needs-approval: this skill is read-only and ends at the report — any resulting action (pausing a creative, launching a replacement, shifting budget) is a separate decision for the user, not taken by this skill.

## Approval boundaries

Read-only. This skill takes no spend actions, pauses no ads, and changes no budgets or bids — it only reads account data and produces a flagged report. Any follow-up action (pause a fatigued creative, launch a refresh, reallocate budget) requires a separate, explicit user approval and is outside this skill's scope.

## What you get

A ranked creative fatigue report: per active ad, a verdict (fatigued / watch / healthy / insufficient data) with the underlying evidence — frequency trend, CTR trend vs trailing average, CPA trend vs trailing average against the correct optimization event, days live, daily spend — plus any confound caveats (recent budget/bid change, learning-phase reset, audience narrowing) that affect confidence in the verdict, sorted by spend-at-risk so the costliest fatigue is at the top.
