skills/pixel-capi/SKILL.md
Meta Pixel + Conversions API (CAPI) setup, audit, testing, and EMQ optimization. Covers browser pixel installation, server-side CAPI implementation, deduplication, advanced matching, and Event Match Quality scoring across all major platforms.
npx skillsauth add themattberman/meta-ads-kit pixel-capiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The browser pixel alone is broken. iOS 14.5 killed 30-50% of signal. Ad blockers take another 20-30%. Cookie deprecation is finishing the job.
The fix is Conversions API (CAPI) -- server-side event sending that runs parallel to the browser pixel, shares event IDs for deduplication, and passes hashed user data that browsers can't block.
This skill audits, sets up, tests, and optimizes your Meta Pixel + CAPI stack. Target: 9.3+ EMQ on Purchase, 8.0+ on Lead.
Always read references/pixel-capi-reference.md first. That doc is the full knowledge base. Scripts automate the work; the reference doc explains the why.
Reads: workspace/brand/stack.md for stored pixel IDs and account IDs
| File | What it provides |
|------|-----------------|
| workspace/brand/stack.md | Stored pixel ID, ad account ID, platform type |
Writes:
| File | What it contains |
|------|-----------------|
| workspace/brand/stack.md | Appends pixel ID, EMQ scores, platform config |
| workspace/brand/learnings.md | Appends EMQ findings, platform gotchas, fixes applied |
Before running any script, load references/pixel-capi-reference.md for:
Key principle: Never send PII unhashed. Scripts handle SHA-256 hashing automatically. If implementing manually, hash everything: lowercase, trim whitespace, then sha256sum.
Check what's configured, what's missing, infer EMQ.
Run: scripts/pixel-audit.sh <account_id_or_pixel_id>
If given an ad account ID (e.g., act_123456): lists all pixels, audits each.
If given a pixel ID directly: audits that pixel only.
Output: Scorecard with pass/fail/warning per check, estimated EMQ per event type, prioritized fix list.
Important: EMQ shown is an estimate based on configured matching fields. Actual EMQ may differ. Always verify in Events Manager > Data Sources > [Pixel] > Overview.
Get platform-specific installation instructions with code snippets.
Run: scripts/pixel-setup.sh <platform> <pixel_id>
Supported platforms:
nextjs -- App Router + Pages Routershopify -- Native + custom implementationwordpress -- WooCommerce + standardwebflow -- Custom code embed approachghl -- GoHighLevel native pixel + CAPI webhookclickfunnels -- ClickFunnels 2.0custom -- Vanilla JS / any platformOutput includes: pixel base code, standard events, advanced matching config, CAPI setup, deduplication implementation, platform-specific gotchas.
Send test events and verify receipt in Events Manager.
Run: scripts/capi-test.sh <pixel_id> [test_event_code]
Sends a test PageView and test Purchase. Use test_event_code to see events in Test Events tool without affecting real data.
After running: Check Events Manager > Data Sources > [Pixel] > Test Events to confirm receipt.
Get a detailed EMQ analysis with prioritized recommendations.
Run: scripts/emq-check.sh <pixel_id>
Pulls pixel config, scores each matching parameter, estimates EMQ, outputs recommendations sorted by impact (highest impact first).
EMQ targets:
Send individual CAPI events with full control over parameters.
Run: scripts/capi-send.sh <pixel_id> <event_name> [options]
Options:
--email "[email protected]"
--phone "15551234567"
--value 109.97
--currency USD
--url "https://site.com/thank-you"
--event-id "unique_dedup_id" (auto-generated if omitted)
--ip "203.0.113.1"
--ua "Mozilla/5.0..."
--fbp "fb.1.1234567890.987654321"
--fbc "fb.1.1234567890.IwAR..."
PII (email, phone, names) is hashed automatically. Event ID is generated if not provided.
You need a Meta access token with ads_management and ads_read permissions. Two ways:
Option A -- System User token (recommended for CAPI):
ads_management scopeOption B -- User token:
social auth login
# Then check: cat ~/.social-cli/config.json
Store token:
export META_TOKEN="your_token_here"
# Or add to ~/.social-cli/config.json as "meta_access_token"
# List all pixels for an ad account
curl -s "https://graph.facebook.com/v19.0/act_ACCOUNT_ID/adspixels?fields=name,id,last_fired_time&access_token=$META_TOKEN" | jq '.data'
Or run: scripts/pixel-audit.sh act_ACCOUNT_ID
| Matching Parameter | Field Key | Weight | Notes |
|-------------------|-----------|--------|-------|
| Email | em | Very High | Hash: lowercase, trim, sha256 |
| Phone | ph | Very High | Hash: digits only, country code, sha256 |
| First Name | fn | Medium | Hash: lowercase, trim, sha256 |
| Last Name | ln | Medium | Hash: lowercase, trim, sha256 |
| City | ct | Medium-Low | Hash: lowercase, no spaces, sha256 |
| State | st | Medium-Low | Hash: 2-letter code, lowercase, sha256 |
| ZIP | zp | Medium-Low | Hash: digits only, sha256 |
| Country | country | Medium-Low | Hash: 2-letter ISO, lowercase, sha256 |
| Date of Birth | db | Low | Hash: YYYYMMDD format, sha256 |
| Gender | ge | Low | Hash: m/f, sha256 |
| External ID | external_id | Medium | Your CRM user ID, sha256 |
| IP Address | client_ip_address | Low-Medium | NOT hashed, pass raw |
| User Agent | client_user_agent | Low-Medium | NOT hashed, pass raw |
| FBP Cookie | fbp | Medium | NOT hashed, read from _fbp cookie |
| FBC Cookie | fbc | Medium | NOT hashed, read from _fbc cookie or fbclid param |
The 9.3+ formula: em + ph + fn + ln + fbp + fbc + ip + ua + at least one geo field
Critical: Both pixel and CAPI must fire with the same event_id or Meta double-counts the conversion.
// Browser pixel
const eventId = 'evt_' + Date.now() + '_' + Math.random().toString(36).substr(2,9);
fbq('track', 'Purchase', {
value: 109.97,
currency: 'USD'
}, {
eventID: eventId // <-- pass to pixel
});
// Server-side (pass this eventId to your CAPI call)
// Scripts handle this -- just make sure your backend receives it from frontend
Without matching event IDs: every conversion counts twice. Ad account thinks you're getting 2x conversions you're not. Ruins optimization.
| Platform | Pixel | CAPI | Hardest Part |
|----------|-------|------|-------------|
| Next.js | next/script + react-facebook-pixel | API route /api/capi | Hydration -- fire only client-side |
| Shopify | Native pixels (new UI) | Shopify CAPI native OR webhook | Checkout extensibility limits |
| WordPress | Header code or plugin | Custom webhook or plugin | WooCommerce order hooks |
| Webflow | Custom code embed | External webhook (Zapier/n8n) | No server-side access -- use Webhook |
| GHL | Native pixel field | GHL CAPI integration (native) | Attribution window settings |
| ClickFunnels 2.0 | Native pixel field | CF2 CAPI native (beta) | Limited event customization |
| Custom | Direct script tag | Server endpoint (any language) | Full control -- see reference doc |
For platform-specific code: scripts/pixel-setup.sh <platform> <pixel_id>
"My EMQ is 4.0"
emq-check.sh for specific gaps"Events are double-counting"
"CAPI events not showing up"
ads_management permissioncapi-test.sh with a test_event_code to debug in isolation"Purchase EMQ good, Lead EMQ bad"
When the user asks about:
references/pixel-capi-reference.md for the full knowledge baseworkspace/brand/stack.md for stored pixel/account IDsworkspace/brand/learnings.md/meta-ads -- Campaign performance. Pair with good signal = better optimization./ga4-report -- See what tracked traffic actually does on-site./analytics-tracking -- Full analytics stack including GA4 event tracking.tools
Meta Ads management and reporting — daily checks, campaign performance, creative fatigue, bleeders, winners. Wraps social-cli for Facebook/Instagram ads. The '5 Daily Questions' that replace Ads Manager.
testing
Analyze spend efficiency across campaigns and adsets. Recommends budget shifts from underperformers to winners.
development
Push ad copy and images to Meta via Graph API — no Ads Manager required. Uploads images, builds asset_feed_spec creatives, and creates or refreshes ads in existing ad sets. Downstream of ad-copy-generator.
tools
Track creative performance over time and detect fatigue before it kills ROAS. Monitors CTR decay, frequency creep, and CPC inflation at the ad level.