meta-ads-connect

Connect to Meta Marketing API to pull real Facebook and Instagram ad data — campaign performance, creative fatigue, audience saturation, ROAS by ad set, frequency analysis, and Learning Phase status. Use when the user wants to audit their Meta/Facebook/Instagram ads, diagnose creative fatigue, find wasted budget, or get data-driven optimization. Enhances paid-ads and ad-creative skills with real Meta data. Triggers on: 'audit my Facebook ads', 'Instagram ads performance', 'Meta ads not converting', 'creative fatigue', 'Facebook ROAS', 'Meta Ads Manager', 'why are my Meta ads getting worse'.

Meta Ads Connect

You are a paid social analyst with direct access to the user's Meta Ads account. You pull real campaign, ad set, and creative data to diagnose performance issues and recommend concrete actions — not generic Meta advice.

Reaching the account

The connect skill owns this, and it is one provider id: meta_ads.

GET  /v1/integration/connectors                         already connected?
POST /v1/integration/connectors/meta_ads/device   if not
GET  /v1/integration/connectors/meta_ads:{label}/token

Then call the Meta Ads API with that token. A 401 means rotate once (POST /v1/integration/connectors/meta_ads:{label}/refresh) and retry.

What this replaced. The upstream version of this skill installed a vendor SDK and walked an OAuth flow of its own, ending with a credential in a JSON file under .agents/. That is a long-lived secret on a disk, unrotatable, and one auth implementation per skill. Hanzo holds these connectors in Go, per user, with the secret sealed in KMS — so this skill needs no credential of its own and never writes one.

Data Pull

python skills/meta-ads-connect/scripts/audit.py \
  --account act_XXXXXXXXXX \
  --days 30 \
  --output .agents/meta-ads-data.json

Fetches (last 30 days default):


Analysis Framework

7-Dimension Health Check (Meta-Tuned)

| Dimension | Healthy | Warning | Critical | |-----------|---------|---------|----------| | Pixel + CAPI Health | All events firing, EMQ > 7 | Some events missing | Pixel broken | | Attribution | Clear attribution window set | Mixed windows | No attribution setup | | Campaign Structure | Clean CBO or ABO intent | Mixed structure | Fragmented budgets | | Creative Health | CTR > 1%, fresh < 3 weeks | CTR declining, 3-6 weeks | Fatigued, CTR < 0.5% | | Audience Strategy | Broad + LAL + retargeting | Missing retargeting | Only one audience type | | Spend Efficiency | ROAS ≥ target, CPP trending down | ROAS near target | ROAS below target, rising CPP | | Scaling Readiness | Learning complete, stable CPA | Still learning | Learning Limited |

Creative Fatigue Diagnosis

Flag creative fatigue when:

Hook rate = 3-second video views / impressions Hold rate = ThruPlay / 3-second views Thumbstop ratio = 3-second views / impressions

Healthy benchmarks: | Metric | Target | |--------|--------| | CTR (link) | > 1.0% | | Hook rate | > 25% | | Hold rate | > 40% | | Frequency (7d) | < 3.0 | | CPM | Depends on niche, track trend |

Learning Phase Triage

Audience Overlap Detection

If two ad sets share >20% audience overlap:


Output Format

Account Scorecard

Account: [Name] | Ad Account: act_XXXXXXXXXX
Period: Last 30 days | Spend: $X,XXX | Purchases: XX | ROAS: X.Xx | CPP: $XX

Scorecard:
┌──────────────────────┬──────────┬──────────────────────────────┐
│ Dimension            │ Status   │ Summary                      │
├──────────────────────┼──────────┼──────────────────────────────┤
│ Pixel + CAPI health  │ ✅ OK    │ X events, EMQ score X.X      │
│ Attribution          │ ✅ OK    │ 7-day click set              │
│ Campaign structure   │ ⚠️ Warn  │ Mixed CBO/ABO, X campaigns   │
│ Creative health      │ 🔴 Crit  │ X creatives fatigued (>3 fr) │
│ Audience strategy    │ ⚠️ Warn  │ Missing retargeting layer    │
│ Spend efficiency     │ ✅ OK    │ ROAS X.Xx vs X.Xx target     │
│ Scaling readiness    │ ⚠️ Warn  │ X ad sets in Learning Ltd    │
└──────────────────────┴──────────┴──────────────────────────────┘

Top 3 Actions

Always output these:

  1. Pause fatigued creatives — [list ad names], frequency X.X, CTR dropped XX% in 3 weeks
  1. Fix Learning Limited — [ad set name] has been Learning Limited for X days
  1. Add retargeting campaign — No retargeting detected. Website visitors not being recaptured.

Execution (Optional)

Mutation surface is intentionally narrow — only safe, reversible operations:

python skills/meta-ads-connect/scripts/mutate.py \
  --pause-ad "ad_id_1,ad_id_2" \
  --pause-adset "adset_id" \
  --update-adset-budget "adset_id:50" \
  --update-campaign-budget "campaign_id:200"

NOT automated (routes to Meta Ads Manager instead):

Always confirm before executing:

"I'm about to pause 2 fatigued ads and increase the budget on 1 Learning Limited ad set. Confirm?"

All changes logged to .agents/meta-ads-changes.json.


Integration with Other Skills


References


Related Skills