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'.
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.
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.
python skills/meta-ads-connect/scripts/audit.py \
--account act_XXXXXXXXXX \
--days 30 \
--output .agents/meta-ads-data.json
Fetches (last 30 days default):
| 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 |
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 |
If two ad sets share >20% audience overlap:
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 │
└──────────────────────┴──────────┴──────────────────────────────┘
Always output these:
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.