I was spending 45 minutes every morning reviewing Meta Ads dashboards. Checking spend, spotting underperformers, deciding what to pause, what to scale. Every. Single. Day.
Then I automated it. Here's the full architecture.
The Problem With Manual Ad Management
Meta Ads Manager gives you data. It doesn't give you decisions.
You have to:
- Load the dashboard
- Filter by date range
- Mentally compare campaigns
- Decide what to do
- Make the changes
This takes 30-60 minutes and requires context you built up over days. An LLM has that pattern recognition. All you have to do is feed it the data.
The Architecture
Schedule Trigger (7am daily)
→ Meta Graph API (7-day campaign metrics)
→ Code Node (calculate status flags per campaign)
→ Claude Sonnet (executive analysis + action plan)
→ Code Node (format Telegram message)
→ Telegram (deliver report)
Step 1: Pull Campaign Data From Meta API
The Meta Graph API endpoint for campaign insights:
GET https://graph.facebook.com/v19.0/{account_id}/insights
Parameters I pull for each campaign:
fields: "campaign_name,impressions,clicks,spend,ctr,cpc,cpm,roas,reach"
date_preset: "last_7d"
level: "campaign"
The HTTP Request node handles auth via access token in the query params.
Step 2: Calculate Status Flags
Before passing to Claude, a Code node pre-calculates simple flags:
const status =
roas < 1 ? 'CRITICAL' : // Losing money
roas < 2 ? 'LOW' : // Under target
roas >= 3 ? 'SCALE' : // Ready to scale
'OK'; // Acceptable
This gives Claude structured data, not raw numbers. Claude focuses on reasoning, not arithmetic.
Step 3: The Claude Prompt
The prompt I use — in Spanish because my clients are LATAM:
Analiza estas métricas de Meta Ads (últimos 7 días) y dame reporte ejecutivo:
Gasto total: $[X]
ROAS promedio: [X]x
Campañas:
- [name]: ROAS [X]x | Gasto $[X] | CTR [X]% | Estado: [STATUS]
...
Dame:
1) Campañas urgentes a revisar
2) Candidatas a escalar
3) Exactamente 3 acciones para hoy
4) Semáforo por campaña (rojo/amarillo/verde)
Sin introducciones.
The "Sin introducciones" instruction cuts 40% of tokens. Claude defaults to pleasantries when asked for reports. You don't need them.
Step 4: The Telegram Report
The final message lands in Telegram every morning at 7am:
*REPORTE META ADS DIARIO*
31/05/2026
Gasto 7d: $847 | ROAS: 2.4x | Campañas: 6
Críticas: Retargeting_Cold
Escalar: Lookalike_30d, VideoViews_Top
ANÁLISIS CLAUDE:
🔴 Retargeting_Cold: ROAS 0.6x, quemando $120/semana...
🟡 Remarketing_14d: CTR bajo (0.8%), creative fatigue...
🟢 Lookalike_30d: ROAS 4.1x, aumentar budget 25-30%...
ACCIONES HOY:
1. Pausar Retargeting_Cold inmediatamente
2. Subir presupuesto Lookalike_30d de $50 a $65/día
3. Rotar creatives en Remarketing_14d
No more opening the dashboard until I've read the summary.
The Results After 7 Days
- Total spend: -38% (paused bleeding campaigns faster)
- Average ROAS: 1.8x → 3.1x
- Time spent on ad management: ~45 min/day → ~5 min/day
- Missed optimizations: 0 (Claude catches patterns I'd sleep on)
The key insight: Claude doesn't make decisions. I do. But Claude makes sure I have the right information every morning before I've had my coffee.
What the Workflow Doesn't Do (Yet)
Auto-apply changes: The workflow can be extended to auto-pause campaigns with ROAS < 1 for 3+ consecutive days, with Telegram confirmation required. I didn't include this because I wanted to validate the analysis quality first.
Cross-campaign budget optimization: Moving budget from underperformers to winners automatically. Possible with the Ads Management API — requires write permissions.
Creative performance: This version analyzes campaign-level data. Ad-level creative analysis (which image/video is performing) requires a second API call with level: "ad".
The n8n Template
I packaged this as an importable workflow with:
- Full 6-node workflow JSON
- Supabase-free (no vector DB needed — pure API)
- Telegram + email delivery options
- Setup guide for Meta API permissions
Available on Gumroad: search "Meta Ads Claude Manager n8n"
Questions about Meta API setup or Claude prompt tuning? Drop a comment.
Top comments (0)