How to Build a Python Script to Detect Meta Ad Fatigue
How to Build a Python Script to Detect Meta Ad Fatigue
Stop relying on gut feeling to kill ads. Here is how growth engineers use our open-source Python heuristic engine to mathematically detect algorithmic ad decay.
Most media buyers kill ads based on gut feeling or a loose rule like “it hasn't gotten a purchase in 3 days.” For growth engineering teams managing 6-figure monthly budgets, that lack of deterministic logic is a massive liability.
Algorithmic ad fatigue is a mathematical state. It happens when Meta's algorithm detects structural saturation in your audience and begins artificially inflating your CPMs. You can detect this state using Python by analyzing the velocity of CPA degradation relative to spend.
The eonik Creative Audit Skill (Open Source)
At eonik, we built an open-source audit skill for detecting fatigue patterns. We have open-sourced a core component of this logic. You can find the full Python implementation in our GitHub repository:
github.com/eonik-ai/eonik-creative-audit-skill
How the Script Works
- Connects to the Meta Graph API: The script pulls daily breakdown data (Spend, Impressions, Clicks, Purchases) at the Ad level.
- Calculates the 7-Day Moving Average: Instead of looking at daily volatility, the script smooths the data to find the true CPA trend line.
- Applies the Fatigue Heuristic: The core logic checks if
Spend > Minimum_ThresholdANDCPA_Trend_Slope > 1.15(indicating a 15% upward velocity in acquisition cost over the window).
Sample Python Implementation
import requests
import pandas as pd
def detect_fatigue(ad_data_df):
"""
Analyzes ad performance DataFrame to detect mathematical fatigue.
Required columns: 'date', 'spend', 'cpa'
"""
# Calculate 7-day rolling average for CPA
ad_data_df['cpa_7d_ma'] = ad_data_df['cpa'].rolling(window=7).mean()
# Calculate the day-over-day slope of the moving average
ad_data_df['cpa_velocity'] = ad_data_df['cpa_7d_ma'].pct_change()
# Flag ads where velocity is strictly positive and exceeds threshold
fatigued_ads = ad_data_df[ad_data_df['cpa_velocity'] > 0.15]
return fatigued_adsWhy This Matters
Building the script to detect fatigue is step one. Step two is solving it. When your Python script flags an ad as fatigued, the traditional workflow requires you to slack a video editor, wait 3 days, and hope the new variant works.
This is why we built eonik. When your script flags fatigue, the traditional workflow is slack a video editor and wait days. eonik assembles finished, on-brand cuts from your footage and AI clips. You direct the hooks; you approve every export before upload.
Feel free to fork the GitHub repository and build your own internal dashboard. Or use eonik to turn what you learn into finished ads you can run.
Related Essays
How to Build a Creative Testing Sandbox in Meta Ads
Stop polluting your main scaling campaigns. Here is the exact Meta Ads architecture to test 50 new AI variations a week without destroying your account history.
Why Your Mac Cannot Render Ads Fast Enough (And What to Use)
If your video editor’s laptop sounds like a jet engine when exporting videos, your workflow is fundamentally broken. Here is how cloud assembly solves the bottleneck.