← all resources

Meta CAPI server-side setup inside GHL — full guide

The Pixel alone hasn’t been enough since iOS 14.5 dropped in 2021 and ATT (App Tracking Transparency) cut tracked-event volume by 40-60% on most accounts. Server-side Conversions API (CAPI) recovers most of that. Here’s the full setup inside GHL.

Why CAPI matters

The browser-side Pixel relies on the user’s browser to fire events. If the user blocks third-party cookies, opts out of ATT on iOS, or uses a privacy-focused browser, the events don’t fire. Meta’s optimization algorithms get fewer signals → worse ad performance.

Server-side CAPI sends events directly from your server to Meta’s API. The user can’t block them. Meta deduplicates against the Pixel events using event_id (we’ll cover that).

The combo of Pixel + CAPI typically recovers 25-40% of the events that ATT was eating, depending on your audience’s iOS share.

What you need

Step 1 — Pixel events firing client-side

Standard Pixel install on every page that matters. In GHL:

  1. Location-level settings → Tracking & SEO → Add the base Pixel snippet (Meta provides this).
  2. For specific events (Lead, CompleteRegistration, Purchase), use GHL’s built-in tracking config OR fire them via a small inline script tied to form submissions / button clicks.

For each event, generate an event_id (UUID). Pass the same event_id to both Pixel (client-side) and CAPI (server-side) — that’s how Meta deduplicates.

Example client-side event:

const eventId = crypto.randomUUID();
fbq('track', 'Lead', {
  value: 0,
  currency: 'USD',
}, { eventID: eventId });

// also send the eventId to your backend so it can fire CAPI with the same ID

Step 2 — CAPI events firing server-side

GHL doesn’t have a native “send to Meta CAPI” action. You have two paths:

Path A: GHL Webhook → middleware → Meta CAPI. Use a Make.com or Zapier scenario as the middleware. Trigger when a contact is created, custom field is updated, or pipeline stage moves.

Path B: GHL Webhook → custom endpoint you control → Meta CAPI. More flexible, requires hosting (a Cloudflare Worker is ~$0/mo at this volume).

The CAPI payload looks like:

{
  "data": [{
    "event_name": "Lead",
    "event_time": 1715600000,
    "event_id": "the-same-uuid-from-pixel",
    "action_source": "website",
    "event_source_url": "https://yourclient.com/contact",
    "user_data": {
      "em": ["sha256-of-email"],
      "ph": ["sha256-of-phone"],
      "client_ip_address": "1.2.3.4",
      "client_user_agent": "Mozilla/...",
      "fbp": "fb.1.1715600000.1234567890",
      "fbc": "fb.1.1715600000.AbCdEfGh"
    },
    "custom_data": { "value": 0, "currency": "USD" }
  }],
  "access_token": "EAA..."
}

POST to https://graph.facebook.com/v19.0/{PIXEL_ID}/events.

Step 3 — Hashing PII

em (email), ph (phone), fn (first name), ln (last name) — all must be SHA-256 hashed before sending. Lowercase first, then hash:

const hash = await crypto.subtle.digest('SHA-256',
  new TextEncoder().encode(email.toLowerCase().trim())
);

If you’re on Make.com, they have a built-in SHA-256 module. If you’re on a Cloudflare Worker, use the WebCrypto API as above.

Step 4 — Event prioritization (Aggregated Event Measurement)

iOS users running ATT see only your top 8 events. You configure the priority order in Events Manager → Data Sources → your Pixel → Aggregated Event Measurement → Configure Web Events.

Order matters. Your highest-value event (Purchase) should be #1. Lead should be #2 or #3. Page-level “ViewContent” events should be lowest priority — they get dropped first.

Step 5 — Verify the dedup is working

In Events Manager → Data Sources → your Pixel → Test Events:

  1. Trigger a test event (submit a form on your site)
  2. You should see the event arrive twice — once from Pixel (browser), once from Server (CAPI)
  3. After ~20 minutes, the deduplication report should show them as deduplicated (1 unique event with 2 sources)

If they’re NOT deduplicating, the event_id isn’t matching between Pixel and CAPI. That’s the most common bug.

Step 6 — Attribution validation

Wait 24-48 hours, then in Ads Manager:

You should see CAPI contributing 25-40% of total conversions on accounts with meaningful iOS traffic. If you see 5% or less, dedup is broken or events aren’t firing.

TL;DR

CAPI is the difference between Meta seeing your Lead events as “200 leads” vs “320 leads” on iOS-heavy audiences. The lift on Smart Bidding optimization is meaningful — usually 15-25% better cost-per-lead on a 30-day window after proper CAPI setup.

The setup is doable in 4-6 hours if you’ve done it before. If you haven’t, allow a full day plus debugging the dedup loop.

If you’d rather skip the dedup-debugging marathon, book the intro call. Meta Pixel + CAPI server-side is included in the Snapboard $1,295/mo retainer. We’ve shipped this dozens of times — first-pass dedup typically works because we have the patterns memorized.

Want this built for you?

Snapboard handles every part of GHL for marketing agencies. Flat $1,295/mo, 24-hour turnaround, pause anytime.

Book a 15-min intro call →