leadstoolpack

Home › How-tos › The Secret Setups › Meta

The Secret Setups · 11 of 20

How to set up the Meta Conversions API with event deduplication

Live guide · Checked 28 October 2026 · Updated 28 October 2026 · Checked every week against Meta's own help pages

Send leads to Meta from your server as well as the browser, using the same event ID, so Meta counts every lead once, even when ad blockers or iPhones hide the pixel.

Time
40 minutes
You will need
  • The Meta Pixel sending Lead with an eventID (previous Secret Setup)
  • A server, CRM or automation tool that can send a web request when a lead arrives
  • Admin access to Meta Events Manager
Stuck?
Troubleshooting or ask us a question

Step by step

  1. Make an access token

    In Meta Events Manager, open your pixel > Settings, scroll to Conversions API and click Generate access token. Copy it and keep it somewhere safe, like a password: never put it in your site's code.

  2. Or use a no-code setup first

    In the same place, Set up with Conversions API Gateway or a partner (Shopify, WordPress, HubSpot and others) does this without code. If your platform is listed, use it and skip to the dedup check. The steps below are for your own server.

  3. Send the lead from your server

    When a lead arrives on your server, send it to Meta. Use the same lead_id you pushed to the dataLayer as event_id:

    JavaScript
    // Node 18+ (or a Cloudflare Worker). Hash personal details with SHA-256 first.
    const sha = async (s) => [...new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(s.trim().toLowerCase())))].map(b => b.toString(16).padStart(2, '0')).join('');
    
    await fetch('https://graph.facebook.com/v21.0/YOUR_PIXEL_ID/events?access_token=' + process.env.META_CAPI_TOKEN, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({
        data: [{
          event_name: 'Lead',                         // must match the browser event name exactly
          event_time: Math.floor(Date.now() / 1000),
          event_id: lead.lead_id,                      // the same id the pixel sent as eventID
          action_source: 'website',
          event_source_url: lead.page_url,
          user_data: {
            em: [await sha(lead.email)],
            ph: lead.phone ? [await sha(lead.phone.replace(/\D/g, ''))] : undefined,
            client_ip_address: lead.ip,
            client_user_agent: lead.user_agent,
            fbp: lead.fbp,                             // the _fbp cookie
            fbc: lead.fbc                              // the _fbc cookie, if there is one
          },
          custom_data: { value: lead.value, currency: 'GBP' }
        }]
      })
    });
  4. Send the lead_id and cookies with the form

    Your server needs the lead_id and Meta's cookies from the browser. Add hidden fields lead_id, fbp and fbc to the form and fill them before it's sent:

    JavaScript
    function cookie(n) { return (document.cookie.match('(^|; )' + n + '=([^;]*)') || [])[2] || ''; }
    var id = 'L-' + Date.now();
    document.querySelectorAll('form').forEach(function (f) {
      f.addEventListener('submit', function () {
        [['lead_id', id], ['fbp', cookie('_fbp')], ['fbc', cookie('_fbc')]].forEach(function (p) {
          var el = f.querySelector('input[name="' + p[0] + '"]'); if (el) el.value = p[1];
        });
      });
    });

    Use the same id in your dataLayer push, so the browser and server copies match.

  5. Test with a test code

    In Events Manager open Test events and copy the test event code (like TEST12345). Add "test_event_code": "TEST12345" next to data in the request, send a test lead and watch it appear marked Server. Remove the test code after.

  6. Check deduplication

    Send a real test lead with the pixel on. In Events Manager > Overview, click Lead: after a few hours it shows Browser and Server with a Deduplicated note. If the counts double instead, the event names or IDs don't match.

  7. Watch Event Match Quality

    On the same page, Event Match Quality shows how well Meta matches your leads to people. Sending email, phone, fbp and fbc usually gets it to Good or Great.

Tips from people who set these up every week

  • event_name and event_id must match exactly between browser and server, or Meta counts the lead twice.
  • Send server events within an hour of the browser event: Meta only dedups inside a 48-hour window and works best when they're close.

Troubleshooting: questions and answers

Server events show but browser ones don't.

That's normal for people with ad blockers or who declined cookies. Make sure the server only sends for people who gave consent, if your banner requires it for marketing.

The API says the token is invalid.

Tokens can be revoked when a user leaves the business. Generate a new one from a system user in Business Settings for a token that doesn't expire.

Official help pages

Let Claude fix the rest of your funnel

Lead Focus is 12 Claude Skills that find the stage of your funnel that's costing you leads, then fix it: ads, landing pages, follow-ups and tracking. One payment, 12 months of updates, and a 14-day refund.

Get Lead Focus · $29.99

Still stuck, or have a question?

Tell us where you got to and what you see. We read every message and reply by email, usually the same working day.