{
  "id": 16142691,
  "title": "Meta Conversions API in Node.js: Deduplication, Hashing and Event Match Quality Done Right",
  "url": "https://urgent.news/2026/10/23/meta-conversions-api-in-node-js-deduplication-hashing-and-event-match",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-23T02:47:40.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/adnoxx/meta-conversions-api-in-nodejs-deduplication-hashing-and-event-match-quality-done-right-2had"
  },
  "original_language": "en",
  "account": "Meta's Conversions API (CAPI) in Node.js addresses deduplication, hashing, and event match quality for ecommerce stores. When customers make purchases through Facebook or Instagram, the browser Pixel alone does not capture every transaction due to privacy settings, ad blockers, consent banners, and short-lived cookies. CAPI solves this issue by sending the same events from the server-side.\n\nCAPI tutorials often stop at simply POSTing JSON data. However, three crucial elements determine whether CAPI benefits or hinders performance: deduplication, hashing/normalization, and match quality. This article covers all three aspects using a small Node.js implementation. The team at Meta Ads works with peptide ads, a regulated category where accurate purchase signals are crucial. These guidelines are applicable to any ecommerce store, not limited to specific niches.\n\nIn the architecture, the browser sends a fbq(track, Purchase, ...) event on the thank-you page. The backend, triggered by the order-paid webhook, sends a Purchase event to POST https://graph.facebook.com/{API_VERSION}/{PIXEL_ID}/events. Both the browser and server carry the same event_id. Meta receives two copies of the event, identifies the match by event_name and event_id, and retains only one instance to avoid double counting.\n\nTo generate a unique event_id per order, use a stable identifier that both the browser and server can recognize, such as the order ID. For example, set purchaseEventId(orderId) = `purchase_${orderId}`. On the thank-you page, use fbq(track, Purchase, ...) with the appropriate parameters, including the event_id generated in Step 1.\n\nStep 2 involves normalizing and hashing personal data. CAPI requires SHA-256 hashing with normalized data. Un-normalized values that are not hashed often result in low match quality. Common issues include variations like \"John@Mail.com\" vs. \"john@mail.com\". The provided code snippet demonstrates normalization functions for email, phone, name, zip, and country fields. Remember not to hash client_ip_address, client_user_agent, fbc, or fbp, as they are sent as plain values.\n\nStep 3 requires capturing the fbp (browser ID) and fbc (click ID) at checkout. These identifiers are set by the Pixel and stored on the order when the checkout process begins, as the webhook runs later without browser data. Store the fbp, fbc, IP address, user agent, and source URL on the order object.\n\nFinally, in Step 4, use the environment variables META_PIXEL_ID, META_CAPI_TOKEN, and META_API_VERSION to send the server-side event. The provided async function sends the purchase event to CAPI, ensuring proper deduplication, hashing, and match quality.",
  "summary": "If you run an ecommerce store and send traffic from Facebook or Instagram, the browser Pixel alone no longer sees every purchase. Safari's tracking protection, ad blockers, consent banners and short-lived cookies all chip away at it. The answer Meta gives is the Conversions API (CAPI) : send the same events from your server. Most CAPI tutorials stop at \"POST some JSON\". In production, three…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}