Pixel & Platform IntegrationsTutorialIntermediate

Meta Conversions API in practice: event_id, hashed matching data and test event codes

How to run Meta Pixel and the Conversions API side by side without double counting — with the exact fields, hashing rules and the test-event workflow from Meta's documentation.

By
Track editorial team
Published
Last reviewed
Reading time
3 min read

Key takeaways

  • Meta merges a pixel event and a server event only when both share event_id and event_name within the dedup window, so generate the id once and pass it to both paths.
  • user_data identifiers are SHA-256 hashed after normalisation; fbc, fbp, IP and user agent stay plain, and fbc/fbp are captured only after marketing consent.
  • Hybrid mode gives Meta the union of matching keys — hashed e-mail and phone from the order system plus fbp/fbc from the browser.
  • A test_event_code keeps test purchases in the Test events tab and out of reporting; every attempt and error code is visible in the event debugger.

The endpoint in one line

POST https://graph.facebook.com/{version}/{pixel_id}/events with a system-user access token and a JSON body containing a data array of events. Track pins the Graph API version centrally (v25.0 at the time of writing) and records when the endpoint was last verified against Meta's documentation.

The fields that matter

Each event object carries:

  • event_namePurchase, Lead, AddToCart, InitiateCheckout, CompleteRegistration, Subscribe, StartTrial, Contact, Schedule, Search, ViewContent, PageView or a custom name
  • event_time — Unix seconds, at most seven days old
  • event_id — your deduplication key
  • event_source_url — the page URL
  • action_sourcewebsite for web events
  • user_data — matching data (see below)
  • custom_datavalue, currency, content_ids, contents, order_id, num_items

Optional but valuable in testing: test_event_code at the top level of the body. Events sent with a test code appear in Events Manager → Test events and are not counted in reporting.

Deduplication: same event_id, same event_name

Meta merges a pixel event and a server event when both share event_id and event_name, arriving within a window of the same order of magnitude as the event itself (Meta documents 48 hours). Two consequences:

  1. Generate the id once, at the moment the action happens, and hand it to both the pixel call (fbq('track', 'Purchase', {...}, { eventID: id })) and the server payload.
  2. Keep event names identical on both paths. A browser Purchase and a server purchase are two events.

Track does this by construction: the SDK generates a source event id, mirrors the pixel call with that id, and the worker sends the same id in event_id.

user_data: what to hash and how

Meta requires SHA-256 hashing for personal identifiers after normalisation:

FieldNormalisation before hashing
emtrim, lowercase
phdigits only, including country code, no leading zeros or plus
fn, lnlowercase, trimmed, letters only
ctlowercase, no spaces or punctuation
zplowercase, first five digits for US
countrytwo-letter ISO code, lowercase
external_idany stable id, hashed

Not hashed: client_ip_address, client_user_agent, fbc, fbp. The fbc value is built from the fbclid URL parameter as fb.1.{timestamp}.{fbclid}; fbp is the _fbp cookie set by the pixel. Both are captured by the Track SDK only after marketing consent and forwarded only to Meta.

What "event match quality" rewards

Meta scores each event by how many matching keys it received. The ones with the largest effect are hashed e-mail, hashed phone, fbp/fbc and external_id. Server events from an order system typically carry e-mail and phone; browser events carry fbp and fbc. Sending both paths with the same event_id therefore gives Meta the union — the practical reason hybrid mode outperforms either path alone.

The test workflow

  1. In Events Manager, open the dataset → Test events and copy the code (for example TEST12345).
  2. Store it in the destination's settings; Track attaches it only while the destination is in test mode.
  3. Send a test purchase from the wizard. The worker delivers it and shows Meta's response (events_received: 1 and an fbtrace_id).
  4. Confirm the event in the Test events tab with the expected parameters and matching keys.
  5. Switch off test mode; from now on events count.

Error classes you will see

  • 190 / OAuthException — token invalid or expired: rotate the system-user token
  • 100 with subcode 2804 — invalid parameter: usually a malformed hash or a missing action_source
  • 4 / 17 / 32 / 613 — rate limits: Track backs off with jitter and retries
  • 5xx — temporary: retried; the circuit breaker pauses the destination if it persists

Every attempt, including the redacted payload preview, is visible in the event debugger — which is where you start when a purchase is missing.

Primary sources

Documentation and standards this article is based on.

  1. Meta — Conversions API: Using the APIdevelopers.facebook.com
  2. Meta — Customer information parameters (hashing)developers.facebook.com

Was this article helpful?

Responsible editor

Track editorial team

Product & engineering

The people building Track: engineers and analysts who work on server-side tracking, consent tooling and connector integrations every day.