[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M718P6CFT6MA927TVHCFM7K4":3,"skill-same:01M718P6CFT6MA927TVHCFM7K4":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":6,"ownerHtmlUrl":48,"ownerBlogUrl":6,"ownerDescription":49,"updatedAt":50,"install":51,"resources":64},"01M718P6CFT6MA927TVHCFM7K4","meta-ads-tracking-setup",null,"Implement and validate Meta Pixel + Conversions API (CAPI) for maximum signal quality — the single biggest lever for Meta Ads performance via the Andromeda ranking system.","narayan-metaflow\u002Fmetaflow-marketing-skills","narayan-metaflow","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F181216517?v=4","01M718MB0Y27AYKTC9ZKT16V86","narayan","01M718MB209XRYRTS3ZZFK0JXS",19,"MIT","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmeta-ads-tracking-setup\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"ads","meta ads","tracking","setup","meta ads tracking setup","Meta","validate","quality","via","implement","api","single","lever","ranking","pixel","signal","system","performance","for","2026-11-10 10:12:30",false,"---\nname: meta-ads-tracking-setup\ndescription: Implement and validate Meta Pixel + Conversions API (CAPI) for maximum signal quality — the single biggest lever for Meta Ads performance via the Andromeda ranking system.\n---\n\n## Why This Matters\n\nMeta's Andromeda deep learning architecture uses signal quality as its primary input for ad delivery optimization. Weak tracking = weak signals = poor delivery = wasted spend. Getting Pixel + CAPI right is foundational — do this before any campaign optimization.\n\n## Process\n\n1. **Audit current state** — Check Events Manager for active Pixel, CAPI status, EMQ scores, event volume, and deduplication status\n2. **Choose implementation path** — Select CAPI method based on technical resources and budget (see Decision Tree below)\n3. **Implement CAPI** — Deploy server-side tracking alongside existing Pixel\n4. **Configure event deduplication** — Match `event_id` between Pixel and CAPI to prevent double-counting\n5. **Optimize EMQ** — Add all matching keys to maximize user match rate\n6. **Validate** — Use Test Events tool to confirm both Pixel and CAPI fire correctly\n7. **Monitor** — Track EMQ scores, event volumes, and deduplication rates weekly for 30 days\n\n## CAPI Implementation Decision Tree\n\nAsk these questions in order:\n\n**Q1: What platform runs the website?**\n- Shopify → Use **native Shopify integration** (free, built-in CAPI, minimal setup)\n- WordPress\u002FWooCommerce → Use **CAPI Gateway** or **server-side GTM**\n- Custom-built site → Use **server-side GTM** or **manual API**\n- No website (CRM\u002Foffline events only) → Use **manual API** with `action_source: system_generated`\n\n**Q2: What's the technical budget?**\n\n| Method | Cost | Dev Effort | Best For |\n|--------|------|-----------|----------|\n| Native platform integration (Shopify, WooCommerce plugins) | Free–$50\u002Fmo | Low | Ecommerce on supported platforms |\n| CAPI Gateway | $10–$400\u002Fmo hosting | Low–Medium | Teams wanting managed solution |\n| Server-side GTM | $10–$50\u002Fmo (GCP) | Medium | Teams already using GTM |\n| Manual API implementation | $500–$5K+ dev time | High | Custom platforms, maximum control |\n\n**Q3: Are there offline\u002FCRM conversions?**\n- Yes → Must implement CAPI with stored `fbc` values (see fbclid Capture Workflow below)\n- **CRITICAL (May 2025):** Meta permanently discontinued the Offline Conversions API. All offline tracking now flows through standard CAPI with `action_source` set to `physical_store` or `system_generated`\n\n## Pixel vs CAPI Comparison\n\n| Dimension | Meta Pixel (Client-Side) | Conversions API (Server-Side) |\n|-----------|------------------------|------------------------------|\n| How it fires | JavaScript in browser | Server-to-server HTTP POST |\n| Blocked by ad blockers | Yes | No |\n| Blocked by iOS ATT | Partially | No (server-side) |\n| Blocked by cookie restrictions | Yes (3P cookies) | No |\n| Data freshness | Real-time | Near real-time (seconds) |\n| Data quality control | Limited | Full (you control the payload) |\n| Events supported | Web events only | Web + offline + CRM + in-store |\n| Required for | Baseline tracking | Signal recovery + offline events |\n| Typical signal recovery | Baseline | Recovers 20–30% of events lost to browser restrictions |\n\n**Both are required.** Pixel alone misses 20-30% of events. CAPI alone misses real-time behavioral signals. Together they give Meta's algorithm the fullest picture.\n\n## Event Deduplication Setup\n\nWhen both Pixel and CAPI fire for the same event, Meta must know they're the same event to avoid double-counting.\n\n**How it works:**\n1. Generate a unique `event_id` on your server or in the browser (UUID or timestamp-based)\n2. Pass the same `event_id` to both the Pixel event AND the CAPI event\n3. Both events must share the same `event_name` (e.g., both say `Purchase`)\n4. Meta deduplicates by matching `event_id` + `event_name`\n\n**Implementation pattern:**\n```\n\u002F\u002F Browser: Pixel fires with event_id\nfbq('track', 'Purchase', {value: 99.99, currency: 'USD'}, {eventID: 'order_abc123'});\n\n\u002F\u002F Server: CAPI fires with same event_id\nPOST to graph.facebook.com with event_id: 'order_abc123'\n```\n\n**Validation:** In Events Manager, check \"Overview\" tab → deduplication should show matched events. If CAPI event count far exceeds Pixel, deduplication may be failing.\n\n## EMQ Optimization Checklist\n\nEvent Match Quality (EMQ) measures how well Meta can match your sent events to Meta user profiles. Higher EMQ = better attribution = better ad delivery.\n\n**Targets:**\n- 6.0+ = Good (minimum acceptable)\n- 8.0+ = Excellent (target this)\n- Below 6.0 = Degraded performance — fix immediately\n\n**Matching keys to send (priority order):**\n\n| Key | Parameter | Impact | Notes |\n|-----|-----------|--------|-------|\n| Email (hashed) | `em` | Highest | SHA-256 hash, lowercase, trimmed |\n| Phone (hashed) | `ph` | High | SHA-256 hash, include country code, digits only |\n| fbc (click ID) | `fbc` | High | Captured from `fbclid` URL parameter — critical for offline conversions |\n| fbp (browser ID) | `fbp` | Medium | Read from `_fbp` first-party cookie |\n| IP address | `client_ip_address` | Medium | User's IP, not server IP |\n| User agent | `client_user_agent` | Medium | Browser user agent string |\n| First name (hashed) | `fn` | Lower | SHA-256 hash, lowercase |\n| Last name (hashed) | `ln` | Lower | SHA-256 hash, lowercase |\n| City (hashed) | `ct` | Lower | SHA-256 hash, lowercase |\n| State (hashed) | `st` | Lower | SHA-256 hash, lowercase, 2-char code |\n| Zip code (hashed) | `zp` | Lower | SHA-256 hash |\n| Country (hashed) | `country` | Lower | SHA-256 hash, 2-char ISO code |\n| Date of birth (hashed) | `db` | Lower | SHA-256 hash, YYYYMMDD format |\n| Gender (hashed) | `ge` | Lower | SHA-256 hash, 'm' or 'f' |\n| External ID (hashed) | `external_id` | Lower | Your system's user ID, hashed |\n\n**Rules:**\n- ALL customer data must be SHA-256 hashed before leaving your server — Meta never receives raw PII\n- Send as many keys as you have — more keys = higher match rate = higher EMQ\n- Email alone typically gets EMQ to ~5-6. Email + phone + fbc gets to 7-8+\n- Read `references\u002Fcapi-event-parameters.md` for full parameter specifications and hashing requirements\n\n## fbclid Capture & Storage Workflow\n\nFor CRM and offline events sent hours\u002Fdays\u002Fweeks after the ad click, the `fbc` value is the critical link connecting the downstream conversion to the original ad.\n\n**Step-by-step:**\n1. User clicks ad → lands on your site with `?fbclid=xyz` in URL\n2. Your landing page JavaScript captures `fbclid` from the URL\n3. Store `fbclid` alongside the lead record in your CRM\u002Fdatabase\n4. Also read and store the `_fbp` cookie value\n5. Construct the `fbc` parameter: `fb.1.{timestamp}.{fbclid_value}`\n6. When the CRM event fires (e.g., sale closes 14 days later), send it via CAPI with the stored `fbc` value\n7. **Event acceptance window:** Maximum 7 days from event time. Send CRM events as soon as possible after they occur\n\n## action_source Parameter Values\n\nEvery CAPI event requires an `action_source` telling Meta where the event originated:\n\n| Value | Use When |\n|-------|----------|\n| `website` | Event happened on your website (most common for web CAPI) |\n| `app` | Event happened in your mobile app |\n| `phone_call` | Event was a phone conversion |\n| `chat` | Event originated from a messaging conversation |\n| `email` | Event resulted from an email campaign |\n| `physical_store` | In-store purchase or offline event at a physical location |\n| `system_generated` | CRM event, backend event, or any system-triggered conversion |\n| `other` | Doesn't fit above categories |\n\n**Post-May 2025 migration:** If you were using the Offline Conversions API, change your integration to standard CAPI and set `action_source` to `physical_store` (for in-store events) or `system_generated` (for CRM\u002Fbackend events).\n\n## Validation Workflow\n\n**Using Meta Test Events Tool:**\n1. Go to Events Manager → your Pixel → Test Events tab\n2. Open your website in a new tab\n3. Perform a conversion action (e.g., submit a form, complete a purchase)\n4. Return to Test Events — confirm you see:\n   - One Pixel event AND one CAPI event for the same action\n   - Both showing the same `event_id`\n   - Status shows \"Deduplicated\" (not \"Duplicate\" or missing match)\n5. Check EMQ score for the event — identify any missing matching keys\n\n**Common validation failures:**\n\n| Symptom | Likely Cause | Fix |\n|---------|-------------|-----|\n| CAPI events not appearing | Server not sending, API auth error | Check server logs, verify access token |\n| Double-counted events | Missing or mismatched `event_id` | Ensure same `event_id` in Pixel and CAPI calls |\n| Low EMQ despite sending keys | Hashing errors, wrong format | Verify SHA-256 hashing, check lowercase\u002Ftrim |\n| CAPI events far exceed Pixel | Pixel blocked but no dedup issue | Normal — CAPI recovers blocked events. Verify dedup still works for events both capture |\n| Events delayed >7 days | Exceeds acceptance window | Speed up CRM-to-CAPI pipeline. Events must fire within 7 days |\n\n## Output Format\n\nWhen asked to help with Meta tracking setup, produce this deliverable:\n\n```\n## Meta Tracking Implementation Plan\n\n### Current State Assessment\n- Pixel status: [Active\u002FInactive\u002FNot installed]\n- CAPI status: [Active\u002FInactive\u002FNot configured]\n- EMQ score: [X.X \u002F 10]\n- Event deduplication: [Working\u002FNot configured\u002FFailing]\n- Events tracked: [List of standard and custom events]\n- Missing matching keys: [List]\n\n### Implementation Steps\n1. [Step with specific technical action]\n2. [Step with specific technical action]\n...\n\n### Matching Keys Action Plan\n| Key | Current Status | Action Required |\n|-----|---------------|-----------------|\n| em (email) | Sending | None |\n| ph (phone) | Not sending | Add to CAPI payload |\n...\n\n### Validation Checklist\n- [ ] Pixel fires on all conversion pages\n- [ ] CAPI fires for all conversion events\n- [ ] event_id matches between Pixel and CAPI\n- [ ] Deduplication confirmed in Test Events\n- [ ] EMQ score ≥ 6.0 (target 8.0+)\n- [ ] All available matching keys sending\n- [ ] SHA-256 hashing verified (no raw PII)\n- [ ] action_source set correctly per event type\n- [ ] CRM events firing within 7-day window\n- [ ] fbclid capture and storage working\n\n### Expected Impact\n- Estimated signal recovery: [X]% of currently lost events\n- EMQ improvement: [current] → [projected]\n- Timeline to stable data: 7-14 days post-implementation\n```\n\n## Example\n\n**Input:** \"We're running Meta ads for a B2B SaaS company. We have the Pixel installed but no CAPI. Our EMQ is 4.2 and we track leads via a CRM. Some leads close 2-3 weeks after the ad click. How do we fix this?\"\n\n**Output:**\n\n## Meta Tracking Implementation Plan\n\n### Current State Assessment\n- Pixel status: Active\n- CAPI status: Not configured — this is your biggest gap\n- EMQ score: 4.2 \u002F 10 — below minimum threshold of 6.0\n- Event deduplication: Not applicable (no CAPI yet)\n- Events tracked: PageView, Lead (Pixel only)\n- Missing matching keys: phone, fbc, fbp, IP, user agent\n\n### Implementation Steps\n1. **Implement CAPI via server-side GTM** — Best option for a custom B2B stack with your CRM. Set up server-side GTM container on Google Cloud ($10-$50\u002Fmo). Configure the Meta CAPI tag in server GTM to mirror Pixel events.\n2. **Add event deduplication** — Generate a unique `event_id` for each Lead event. Pass it to both the Pixel `fbq('track', 'Lead', {}, {eventID: 'lead_xyz'})` and the server-side CAPI tag.\n3. **Capture and store fbclid** — Add JavaScript to capture `fbclid` from landing page URLs. Store it in a hidden form field so your CRM records it on the contact. Also capture the `_fbp` cookie value.\n4. **Build CRM-to-CAPI pipeline** — When a CRM deal closes, fire a CAPI `Purchase` event (or custom `ClosedWon` event) with `action_source: system_generated`, the stored `fbc` value, hashed email, and hashed phone.\n5. **Fix the 2-3 week delay problem** — Events must arrive within 7 days of occurring. Set up a CRM workflow to fire CAPI events at key pipeline stages (MQL, SQL, Opportunity) rather than waiting for close. This keeps events within the 7-day window AND gives Meta more mid-funnel signals.\n6. **Add matching keys** — Send hashed email + hashed phone + fbc + fbp + IP + user agent with every CAPI event.\n\n### Matching Keys Action Plan\n| Key | Current Status | Action Required |\n|-----|---------------|-----------------|\n| em (email) | Not sending via CAPI | Add to CAPI payload, SHA-256 hashed |\n| ph (phone) | Not sending | Add to CAPI payload, SHA-256 hashed |\n| fbc | Not capturing | Add fbclid capture to landing pages + CRM |\n| fbp | Not sending | Read _fbp cookie, pass to server GTM |\n| IP | Not sending | Auto-captured by server-side GTM |\n| User agent | Not sending | Auto-captured by server-side GTM |\n\n### Validation Checklist\n- [ ] Pixel fires Lead event on form submission\n- [ ] CAPI fires Lead event via server GTM\n- [ ] event_id matches between Pixel and CAPI for Lead events\n- [ ] Deduplication confirmed in Test Events\n- [ ] EMQ score ≥ 6.0 (target 8.0+)\n- [ ] fbclid captured and stored on the contact in your CRM records\n- [ ] CRM events (MQL, SQL, ClosedWon) firing via CAPI within 7 days\n- [ ] SHA-256 hashing verified for all PII fields\n- [ ] action_source = \"website\" for web events, \"system_generated\" for CRM events\n\n### Expected Impact\n- Signal recovery: ~20-30% more conversion events captured\n- EMQ improvement: 4.2 → 7.0+ (with email + phone + fbc + fbp)\n- More mid-funnel signals for Meta's algorithm to optimize against\n- Timeline: 7-14 days post-implementation for algorithm to recalibrate\n\n## Guidelines\n\n- **Never skip CAPI.** Pixel alone is insufficient in 2025. Browser restrictions, ad blockers, and iOS ATT mean Pixel misses 20-30% of events.\n- **Never send unhashed PII.** All customer data must be SHA-256 hashed before transmission. Sending raw emails or phone numbers violates Meta's terms and privacy regulations.\n- **Don't ignore EMQ below 6.0.** Sub-6 EMQ directly degrades ad delivery quality. Treat it as a critical issue.\n- **Don't delay CRM events beyond 7 days.** Events older than 7 days are rejected. Build pipeline stages that fire within the window.\n- **Don't set up CAPI without deduplication.** Double-counted conversions inflate metrics and mislead the algorithm.\n- **Offline Conversions API is dead.** If someone references it, redirect them to standard CAPI with `action_source: physical_store` or `system_generated`. Discontinued May 2025.\n- **Instant Experience (June 2025):** Meta no longer counts Instant Experience as a landing page view. Account for this in funnel metrics if using Instant Experience ads.\n- **Attribution API change (October 2025):** `7d_view` and `28d_view` attribution windows are no longer returned in the Ads Insights API. Update any reporting that pulls these windows.\n- **iOS 14+ context:** Aggregated Event Measurement (AEM) still governs measurement for iOS users. You can configure up to 8 prioritized events per domain.\n- **Cross-reference:** For Meta account auditing including tracking health checks, use the **meta-ads-audit** skill. For Google tracking (gtag, GA4, enhanced conversions), tracking setup is covered within the **google-ads-audit** skill.\n- **Confidence:** If the user's platform or tech stack isn't listed in this skill, recommend they consult Meta's official CAPI documentation for platform-specific integration guides rather than guessing at implementation details.\n","## Why This Matters\n\nMeta's Andromeda deep learning architecture uses signal quality as its primary input for ad delivery optimization. Weak tracking = weak signals = poor delivery = wasted spend. Getting Pixel + CAPI right is foundational — do this before any campaign optimization.\n\n## Process\n\n1. **Audit current state** — Check Events Manager for active Pixel, CAPI status, EMQ scores, event volume, and deduplication status\n2. **Choose implementation path** — Select CAPI method based on technical resources and budget (see Decision Tree below)\n3. **Implement CAPI** — Deploy server-side tracking alongside existing Pixel\n4. **Configure event deduplication** — Match `event_id` between Pixel and CAPI to prevent double-counting\n5. **Optimize EMQ** — Add all matching keys to maximize user match rate\n6. **Validate** — Use Test Events tool to confirm both Pixel and CAPI fire correctly\n7. **Monitor** — Track EMQ scores, event volumes, and deduplication rates weekly for 30 days\n\n## CAPI Implementation Decision Tree\n\nAsk these questions in order:\n\n**Q1: What platform runs the website?**\n- Shopify → Use **native Shopify integration** (free, built-in CAPI, minimal setup)\n- WordPress\u002FWooCommerce → Use **CAPI Gateway** or **server-side GTM**\n- Custom-built site → Use **server-side GTM** or **manual API**\n- No website (CRM\u002Foffline events only) → Use **manual API** with `action_source: system_generated`\n\n**Q2: What's the technical budget?**\n\n| Method | Cost | Dev Effort | Best For |\n|--------|------|-----------|----------|\n| Native platform integration (Shopify, WooCommerce plugins) | Free–$50\u002Fmo | Low | Ecommerce on supported platforms |\n| CAPI Gateway | $10–$400\u002Fmo hosting | Low–Medium | Teams wanting managed solution |\n| Server-side GTM | $10–$50\u002Fmo (GCP) | Medium | Teams already using GTM |\n| Manual API implementation | $500–$5K+ dev time | High | Custom platforms, maximum control |\n\n**Q3: Are there offline\u002FCRM conversions?**\n- Yes → Must implement CAPI with stored `fbc` values (see fbclid Capture Workflow below)\n- **CRITICAL (May 2025):** Meta permanently discontinued the Offline Conversions API. All offline tracking now flows through standard CAPI with `action_source` set to `physical_store` or `system_generated`\n\n## Pixel vs CAPI Comparison\n\n| Dimension | Meta Pixel (Client-Side) | Conversions API (Server-Side) |\n|-----------|------------------------|------------------------------|\n| How it fires | JavaScript in browser | Server-to-server HTTP POST |\n| Blocked by ad blockers | Yes | No |\n| Blocked by iOS ATT | Partially | No (server-side) |\n| Blocked by cookie restrictions | Yes (3P cookies) | No |\n| Data freshness | Real-time | Near real-time (seconds) |\n| Data quality control | Limited | Full (you control the payload) |\n| Events supported | Web events only | Web + offline + CRM + in-store |\n| Required for | Baseline tracking | Signal recovery + offline events |\n| Typical signal recovery | Baseline | Recovers 20–30% of events lost to browser restrictions |\n\n**Both are required.** Pixel alone misses 20-30% of events. CAPI alone misses real-time behavioral signals. Together they give Meta's algorithm the fullest picture.\n\n## Event Deduplication Setup\n\nWhen both Pixel and CAPI fire for the same event, Meta must know they're the same event to avoid double-counting.\n\n**How it works:**\n1. Generate a unique `event_id` on your server or in the browser (UUID or timestamp-based)\n2. Pass the same `event_id` to both the Pixel event AND the CAPI event\n3. Both events must share the same `event_name` (e.g., both say `Purchase`)\n4. Meta deduplicates by matching `event_id` + `event_name`\n\n**Implementation pattern:**\n```\n\u002F\u002F Browser: Pixel fires with event_id\nfbq('track', 'Purchase', {value: 99.99, currency: 'USD'}, {eventID: 'order_abc123'});\n\n\u002F\u002F Server: CAPI fires with same event_id\nPOST to graph.facebook.com with event_id: 'order_abc123'\n```\n\n**Validation:** In Events Manager, check \"Overview\" tab → deduplication should show matched events. If CAPI event count far exceeds Pixel, deduplication may be failing.\n\n## EMQ Optimization Checklist\n\nEvent Match Quality (EMQ) measures how well Meta can match your sent events to Meta user profiles. Higher EMQ = better attribution = better ad delivery.\n\n**Targets:**\n- 6.0+ = Good (minimum acceptable)\n- 8.0+ = Excellent (target this)\n- Below 6.0 = Degraded performance — fix immediately\n\n**Matching keys to send (priority order):**\n\n| Key | Parameter | Impact | Notes |\n|-----|-----------|--------|-------|\n| Email (hashed) | `em` | Highest | SHA-256 hash, lowercase, trimmed |\n| Phone (hashed) | `ph` | High | SHA-256 hash, include country code, digits only |\n| fbc (click ID) | `fbc` | High | Captured from `fbclid` URL parameter — critical for offline conversions |\n| fbp (browser ID) | `fbp` | Medium | Read from `_fbp` first-party cookie |\n| IP address | `client_ip_address` | Medium | User's IP, not server IP |\n| User agent | `client_user_agent` | Medium | Browser user agent string |\n| First name (hashed) | `fn` | Lower | SHA-256 hash, lowercase |\n| Last name (hashed) | `ln` | Lower | SHA-256 hash, lowercase |\n| City (hashed) | `ct` | Lower | SHA-256 hash, lowercase |\n| State (hashed) | `st` | Lower | SHA-256 hash, lowercase, 2-char code |\n| Zip code (hashed) | `zp` | Lower | SHA-256 hash |\n| Country (hashed) | `country` | Lower | SHA-256 hash, 2-char ISO code |\n| Date of birth (hashed) | `db` | Lower | SHA-256 hash, YYYYMMDD format |\n| Gender (hashed) | `ge` | Lower | SHA-256 hash, 'm' or 'f' |\n| External ID (hashed) | `external_id` | Lower | Your system's user ID, hashed |\n\n**Rules:**\n- ALL customer data must be SHA-256 hashed before leaving your server — Meta never receives raw PII\n- Send as many keys as you have — more keys = higher match rate = higher EMQ\n- Email alone typically gets EMQ to ~5-6. Email + phone + fbc gets to 7-8+\n- Read `references\u002Fcapi-event-parameters.md` for full parameter specifications and hashing requirements\n\n## fbclid Capture & Storage Workflow\n\nFor CRM and offline events sent hours\u002Fdays\u002Fweeks after the ad click, the `fbc` value is the critical link connecting the downstream conversion to the original ad.\n\n**Step-by-step:**\n1. User clicks ad → lands on your site with `?fbclid=xyz` in URL\n2. Your landing page JavaScript captures `fbclid` from the URL\n3. Store `fbclid` alongside the lead record in your CRM\u002Fdatabase\n4. Also read and store the `_fbp` cookie value\n5. Construct the `fbc` parameter: `fb.1.{timestamp}.{fbclid_value}`\n6. When the CRM event fires (e.g., sale closes 14 days later), send it via CAPI with the stored `fbc` value\n7. **Event acceptance window:** Maximum 7 days from event time. Send CRM events as soon as possible after they occur\n\n## action_source Parameter Values\n\nEvery CAPI event requires an `action_source` telling Meta where the event originated:\n\n| Value | Use When |\n|-------|----------|\n| `website` | Event happened on your website (most common for web CAPI) |\n| `app` | Event happened in your mobile app |\n| `phone_call` | Event was a phone conversion |\n| `chat` | Event originated from a messaging conversation |\n| `email` | Event resulted from an email campaign |\n| `physical_store` | In-store purchase or offline event at a physical location |\n| `system_generated` | CRM event, backend event, or any system-triggered conversion |\n| `other` | Doesn't fit above categories |\n\n**Post-May 2025 migration:** If you were using the Offline Conversions API, change your integration to standard CAPI and set `action_source` to `physical_store` (for in-store events) or `system_generated` (for CRM\u002Fbackend events).\n\n## Validation Workflow\n\n**Using Meta Test Events Tool:**\n1. Go to Events Manager → your Pixel → Test Events tab\n2. Open your website in a new tab\n3. Perform a conversion action (e.g., submit a form, complete a purchase)\n4. Return to Test Events — confirm you see:\n   - One Pixel event AND one CAPI event for the same action\n   - Both showing the same `event_id`\n   - Status shows \"Deduplicated\" (not \"Duplicate\" or missing match)\n5. Check EMQ score for the event — identify any missing matching keys\n\n**Common validation failures:**\n\n| Symptom | Likely Cause | Fix |\n|---------|-------------|-----|\n| CAPI events not appearing | Server not sending, API auth error | Check server logs, verify access token |\n| Double-counted events | Missing or mismatched `event_id` | Ensure same `event_id` in Pixel and CAPI calls |\n| Low EMQ despite sending keys | Hashing errors, wrong format | Verify SHA-256 hashing, check lowercase\u002Ftrim |\n| CAPI events far exceed Pixel | Pixel blocked but no dedup issue | Normal — CAPI recovers blocked events. Verify dedup still works for events both capture |\n| Events delayed >7 days | Exceeds acceptance window | Speed up CRM-to-CAPI pipeline. Events must fire within 7 days |\n\n## Output Format\n\nWhen asked to help with Meta tracking setup, produce this deliverable:\n\n```\n## Meta Tracking Implementation Plan\n\n### Current State Assessment\n- Pixel status: [Active\u002FInactive\u002FNot installed]\n- CAPI status: [Active\u002FInactive\u002FNot configured]\n- EMQ score: [X.X \u002F 10]\n- Event deduplication: [Working\u002FNot configured\u002FFailing]\n- Events tracked: [List of standard and custom events]\n- Missing matching keys: [List]\n\n### Implementation Steps\n1. [Step with specific technical action]\n2. [Step with specific technical action]\n...\n\n### Matching Keys Action Plan\n| Key | Current Status | Action Required |\n|-----|---------------|-----------------|\n| em (email) | Sending | None |\n| ph (phone) | Not sending | Add to CAPI payload |\n...\n\n### Validation Checklist\n- [ ] Pixel fires on all conversion pages\n- [ ] CAPI fires for all conversion events\n- [ ] event_id matches between Pixel and CAPI\n- [ ] Deduplication confirmed in Test Events\n- [ ] EMQ score ≥ 6.0 (target 8.0+)\n- [ ] All available matching keys sending\n- [ ] SHA-256 hashing verified (no raw PII)\n- [ ] action_source set correctly per event type\n- [ ] CRM events firing within 7-day window\n- [ ] fbclid capture and storage working\n\n### Expected Impact\n- Estimated signal recovery: [X]% of currently lost events\n- EMQ improvement: [current] → [projected]\n- Timeline to stable data: 7-14 days post-implementation\n```\n\n## Example\n\n**Input:** \"We're running Meta ads for a B2B SaaS company. We have the Pixel installed but no CAPI. Our EMQ is 4.2 and we track leads via a CRM. Some leads close 2-3 weeks after the ad click. How do we fix this?\"\n\n**Output:**\n\n## Meta Tracking Implementation Plan\n\n### Current State Assessment\n- Pixel status: Active\n- CAPI status: Not configured — this is your biggest gap\n- EMQ score: 4.2 \u002F 10 — below minimum threshold of 6.0\n- Event deduplication: Not applicable (no CAPI yet)\n- Events tracked: PageView, Lead (Pixel only)\n- Missing matching keys: phone, fbc, fbp, IP, user agent\n\n### Implementation Steps\n1. **Implement CAPI via server-side GTM** — Best option for a custom B2B stack with your CRM. Set up server-side GTM container on Google Cloud ($10-$50\u002Fmo). Configure the Meta CAPI tag in server GTM to mirror Pixel events.\n2. **Add event deduplication** — Generate a unique `event_id` for each Lead event. Pass it to both the Pixel `fbq('track', 'Lead', {}, {eventID: 'lead_xyz'})` and the server-side CAPI tag.\n3. **Capture and store fbclid** — Add JavaScript to capture `fbclid` from landing page URLs. Store it in a hidden form field so your CRM records it on the contact. Also capture the `_fbp` cookie value.\n4. **Build CRM-to-CAPI pipeline** — When a CRM deal closes, fire a CAPI `Purchase` event (or custom `ClosedWon` event) with `action_source: system_generated`, the stored `fbc` value, hashed email, and hashed phone.\n5. **Fix the 2-3 week delay problem** — Events must arrive within 7 days of occurring. Set up a CRM workflow to fire CAPI events at key pipeline stages (MQL, SQL, Opportunity) rather than waiting for close. This keeps events within the 7-day window AND gives Meta more mid-funnel signals.\n6. **Add matching keys** — Send hashed email + hashed phone + fbc + fbp + IP + user agent with every CAPI event.\n\n### Matching Keys Action Plan\n| Key | Current Status | Action Required |\n|-----|---------------|-----------------|\n| em (email) | Not sending via CAPI | Add to CAPI payload, SHA-256 hashed |\n| ph (phone) | Not sending | Add to CAPI payload, SHA-256 hashed |\n| fbc | Not capturing | Add fbclid capture to landing pages + CRM |\n| fbp | Not sending | Read _fbp cookie, pass to server GTM |\n| IP | Not sending | Auto-captured by server-side GTM |\n| User agent | Not sending | Auto-captured by server-side GTM |\n\n### Validation Checklist\n- [ ] Pixel fires Lead event on form submission\n- [ ] CAPI fires Lead event via server GTM\n- [ ] event_id matches between Pixel and CAPI for Lead events\n- [ ] Deduplication confirmed in Test Events\n- [ ] EMQ score ≥ 6.0 (target 8.0+)\n- [ ] fbclid captured and stored on the contact in your CRM records\n- [ ] CRM events (MQL, SQL, ClosedWon) firing via CAPI within 7 days\n- [ ] SHA-256 hashing verified for all PII fields\n- [ ] action_source = \"website\" for web events, \"system_generated\" for CRM events\n\n### Expected Impact\n- Signal recovery: ~20-30% more conversion events captured\n- EMQ improvement: 4.2 → 7.0+ (with email + phone + fbc + fbp)\n- More mid-funnel signals for Meta's algorithm to optimize against\n- Timeline: 7-14 days post-implementation for algorithm to recalibrate\n\n## Guidelines\n\n- **Never skip CAPI.** Pixel alone is insufficient in 2025. Browser restrictions, ad blockers, and iOS ATT mean Pixel misses 20-30% of events.\n- **Never send unhashed PII.** All customer data must be SHA-256 hashed before transmission. Sending raw emails or phone numbers violates Meta's terms and privacy regulations.\n- **Don't ignore EMQ below 6.0.** Sub-6 EMQ directly degrades ad delivery quality. Treat it as a critical issue.\n- **Don't delay CRM events beyond 7 days.** Events older than 7 days are rejected. Build pipeline stages that fire within the window.\n- **Don't set up CAPI without deduplication.** Double-counted conversions inflate metrics and mislead the algorithm.\n- **Offline Conversions API is dead.** If someone references it, redirect them to standard CAPI with `action_source: physical_store` or `system_generated`. Discontinued May 2025.\n- **Instant Experience (June 2025):** Meta no longer counts Instant Experience as a landing page view. Account for this in funnel metrics if using Instant Experience ads.\n- **Attribution API change (October 2025):** `7d_view` and `28d_view` attribution windows are no longer returned in the Ads Insights API. Update any reporting that pulls these windows.\n- **iOS 14+ context:** Aggregated Event Measurement (AEM) still governs measurement for iOS users. You can configure up to 8 prioritized events per domain.\n- **Cross-reference:** For Meta account auditing including tracking health checks, use the **meta-ads-audit** skill. For Google tracking (gtag, GA4, enhanced conversions), tracking setup is covered within the **google-ads-audit** skill.\n- **Confidence:** If the user's platform or tech stack isn't listed in this skill, recommend they consult Meta's official CAPI documentation for platform-specific integration guides rather than guessing at implementation details.\n",{"name":5,"description":7},"main","c137446804eb85b2cc0ba009c62068253a7c47be","skills\u002Fmeta-ads-tracking-setup",2,"https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow","engineer by education, marketer by profession, building rn","2026-09-16 13:41:44",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add narayan-metaflow\u002Fmetaflow-marketing-skills --skill meta-ads-tracking-setup",{"tool":57,"command":58},"bunx","bunx skills add narayan-metaflow\u002Fmetaflow-marketing-skills --skill meta-ads-tracking-setup",{"tool":60,"command":61},"pnpm","pnpm dlx skills add narayan-metaflow\u002Fmetaflow-marketing-skills --skill meta-ads-tracking-setup","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmeta-ads-tracking-setup\u002FSKILL.md",true,[65],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"references\u002Fcapi-event-parameters.md","REFERENCE","参考文档",12440,"https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fmeta-ads-tracking-setup\u002Freferences\u002Fcapi-event-parameters.md",[72,107,136,156,185,213],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":88,"publishedAt":38},"01M718Q16XB7D7ZMGNNA1226G5","technical-seo-ai-crawler-audit","Diagnose and prioritize the technical issues blocking a site from being crawled, indexed, ranked, and cited. Modern technical SEO has two audiences: Google's crawler\u002Findexer and AI answer engines (GPTBot, PerplexityBot, ClaudeBot, etc.). Both need HTML-visible content and a clean crawl path.","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Ftechnical-seo-ai-crawler-audit\u002FSKILL.md",[78,83],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000019","营销推广","SCENARIO","使用场景",{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000035","市场营销","PROFESSION","适用职业",[89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106],"seo","technical","technical seo","technical seo ai crawler audit","audit","crawler","crawl","diagnose","answer","issues","clean","indexer","google","prioritize","site","content","html","path",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":118,"publishedAt":38},"01M718PY2PKA7BYS5KNJ2A9DRT","seo-reporting-measurement","Build reports that stakeholders trust, rooted in data sources that are actually reliable. Modern SEO measurement has to reckon with a very specific constraint: **the primary data source (GSC) is ~75% incomplete**, and the AI visibility layer is **probabilistic**, not deterministic. Building reports that ignore these realities produces false confidence.","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fseo-reporting-measurement\u002FSKILL.md",[113,114,117],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},{"categoryNo":115,"categoryName":116,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000033","数据分析师",{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},[119,120,121,122,89,123,124,125,126,127,128,129,130,131,132,133,134,135],"seo reporting","seo reporting measurement","reporting","measurement","sources","gsc","false","reports","data sources","data","layer","source","deterministic","trust","with","build","constraint",{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":144,"publishedAt":38},"01M718PVF0SP35J6S9EHRGQZQ1","seo-max-kt","Long-form SEO and AEO methodology bundle; read SEO_AND_AEO_KT.md for the full corpus.","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fseo-max-kt\u002FSKILL.md",[142,143],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},[145,89,146,147,148,149,150,151,37,152,153,154,155],"kt","seo max kt","max","aeo","long-form","methodology","form","bundle","full","read","long",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":167,"publishedAt":38},"01M718PRQNX2JF71GBFTH3MV19","seo-keyword-research-intent-mapping","Build a keyword universe that reflects how both humans *and* AI answer engines search. Traditional keyword research looks at standalone terms; modern research also maps the **fan-out sub-queries** AI tools generate when breaking down a user prompt.","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fseo-keyword-research-intent-mapping\u002FSKILL.md",[162,163,166],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},{"categoryNo":164,"categoryName":165,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},[89,168,169,170,171,172,173,174,175,176,97,177,178,179,180,181,182,134,183,184],"seo keyword research","seo keyword research intent mapping","research","intent","keyword research","mapping","ai tools","standalone","down","search","prompt","when","maps","queries","generate","how","at",{"skillNo":186,"name":187,"nameZh":6,"description":188,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":189,"categories":190,"keywords":199,"publishedAt":38},"01M718PNDT3A19SV7KVWC9083P","seo-aeo-content-strategy","Design content systems that earn both Google rankings *and* AI citations. The core insight: AI answer engines read content differently than humans — they extract the highest-information-gain sentences and treat H2 headings as prompts. The \"ski ramp\" structure optimizes for both.","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fseo-aeo-content-strategy\u002FSKILL.md",[191,194,195,196],{"categoryNo":192,"categoryName":193,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},{"categoryNo":197,"categoryName":198,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000036","内容创作者",[89,148,200,201,202,104,203,204,205,37,97,206,207,208,209,154,210,211,101,212],"strategy","seo aeo content strategy","content strategy","Citations","as","core","design","information","earn","structure","systems","ramp","prompts",{"skillNo":214,"name":215,"nameZh":6,"description":216,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":217,"categories":218,"keywords":222,"publishedAt":38},"01M718PJM103BE7581G6NRCC7T","prompt-picker","Build a prompt library that reveals how a brand shows up across the full buyer journey in AI search systems. The library is designed for actual LLM visibility tracking, not theoretical SEO keyword research.","https:\u002F\u002Fgithub.com\u002Fnarayan-metaflow\u002Fmetaflow-marketing-skills\u002Fblob\u002Fmain\u002Fskills\u002Fprompt-picker\u002FSKILL.md",[219],{"categoryNo":220,"categoryName":221,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000023","Skill与智能体开发",[223,178,224,225,89,37,168,177,226,227,228,229,170,134,183,210,172,230,21,153],"prompt picker","llm visibility","brand","up","journey","prompt library","across","library"]