All integrations

Integration · Meta Conversions API

Purchase signals Meta can match, dedupe, and learn from

RoasProof delivers enriched server events to the Conversions API. Each event is deduplicated against your existing pixel, carries every identifier Meta accepts for matching, and stays queued until Meta confirms receipt.

The Meta Conversions API (CAPI) is Meta's server-to-server channel for conversion events: instead of the browser pixel firing, your server sends the event directly to Meta. RoasProof builds each event with hashed customer identifiers, recovered fbc/fbp click identifiers and a deterministic event_id, so Meta can match it to a real account and deduplicate it against your pixel.

Purchase · Lead · CompleteRegistrationevent_id dedupEMQ-optimized user_datastore-and-forward delivery

What a RoasProof server event looks like

A single Purchase event, exactly as it leaves our servers for the Graph API. Every field below exists to make the conversion easier for Meta to match and impossible to double count.

conversions api · purchase
POST https://graph.facebook.com/v24.0/{pixel_id}/events

{
  "data": [{
    "event_name":       "Purchase",
    "event_time":       1781430082,
    "event_id":         "ord_84213",
    "action_source":    "website",
    "event_source_url": "https://store.example/checkout/thank-you",
    "user_data": {
      "em":          ["9f3d0c52ab…"],
      "ph":          ["1b6e21c84f…"],
      "external_id": ["7ac8044190…"],
      "fbp":         "fb.1.1780828882512.83179243",
      "fbc":         "fb.1.1780828882512.IwZXh0bgNhZW0…",
      "client_ip_address": "203.0.113.24",
      "client_user_agent": "Mozilla/5.0 (iPhone; …)"
    },
    "custom_data": {
      "currency":     "EUR",
      "value":        184.50,
      "order_id":     "84213",
      "content_type": "product",
      "content_ids":  ["SKU-2481", "SKU-1177"]
    }
  }],
  "test_event_code": "TEST61045"
}
  • event_id matches your pixel

    The browser event and this server event both carry ord_84213 (derived from the order ID), so Meta counts the purchase exactly once no matter which copy arrives first.

  • fbc recovered, not hoped for

    If the _fbc cookie is missing or was purged, we synthesize the parameter as fb.1.{timestamp}.{fbclid} from the fbclid stored on landing, so the click still gets credit.

  • Hashed identifiers, never raw PII

    em and ph are normalized (trimmed, lowercased, phone in E.164) and SHA-256 hashed on our servers before the request is sent. Meta only ever sees the hashes.

  • Verified before you go live

    During setup, events flow through Meta's Test Events tool with a test_event_code, so you can watch them arrive, match, and dedupe before switching to production.

One purchase, one count: pixel and server together

You keep your pixel. We coordinate with it. Meta pairs the two copies of each event by event_name + event_id and keeps a single one.

  • Deterministic IDs from your order IDs

    The event ID is a stable function of the order, not a random string. Replays, retries, and the browser copy all resolve to the same ID. Dedup never depends on timing.

  • The script hands the ID to your pixel

    At fire time, our on-page script passes the same eventID to the browser pixel that the server event will carry. Both copies reach Meta within the dedup window as a matched pair.

  • The redundant copy is discarded, the coverage stays

    Where the pixel still works, Meta gets two copies and keeps one. Where it was blocked (iOS, ad blockers, closed tabs), the server event is the only copy, and the conversion is no longer lost.

Meta pixel · browser
Purchase·event_id: ord_84213
RoasProof · server
Purchase·event_id: ord_84213
counted once
1 × Purchase

Same event_name + event_id within the dedup window: Meta drops the duplicate and keeps the richer event.

Every matching key Meta accepts, on every event

EMQ scores how well Meta can connect your events to real accounts. More matched conversions mean better attribution and a smarter optimization loop, so we populate user_data as completely as your data allows.

event match quality (illustrative)
010Event Match Quality · 0-10Pixel onlytypical zone ≈ 5-6Hashed IDs + click IDsserver-side ≈ 8-9+

Illustrative zones, not measured data. Your actual EMQ depends on which identifiers your events carry and what consent allows. Meta scores each event type in Events Manager.

parameterwhat it iswhere we get it
emSHA-256 of the normalized email addressOrder or signup email, trimmed and lowercased before hashing
phSHA-256 of the phone number in E.164 formatCheckout or lead-form phone, normalized to international format
external_idSHA-256 of a stable first-party visitor IDSet on the first visit and reused across sessions and devices where identity resolves
fbpMeta browser ID cookieRead on-site and stored with the session, so it survives to conversion time
fbcMeta click ID cookieRead from _fbc when present; otherwise synthesized from the fbclid we stored on landing
client_ip / client_uaIP address and user agent of the buyerRecorded with the session that produced the conversion, not our server's

The dashboard shows the share of events carrying each key per event type, so when EMQ dips you see exactly which identifier went missing instead of reverse-engineering it from Events Manager. New to the metric? Start with the Event Match Quality glossary entry, then the step-by-step EMQ guide on the blog.

Store-and-forward, with receipts

Conversions API requests fail for boring reasons: expired tokens, rate limits, brief outages. None of them should cost you a conversion.

action_source, set honestly

Meta requires every event to declare where it happened. Website conversions go out as website, offline and CRM-sourced events are marked accordingly. We don't apply blanket defaults that would misrepresent your data.

Queued, retried, never dropped

Events are persisted before the first delivery attempt and retried with exponential backoff on errors and rate limits. Events that exhaust retries are parked for review and one-click replay.

Per-event delivery status

Every event shows the exact payload sent and Meta's response, including trace IDs and error codes, so a failed Purchase is a diagnosable fact rather than a mystery in next week's numbers.

Ready to raise your Event Match Quality?

Connect a pixel ID and an access token, send a test event, and watch the dedup work in Meta's Test Events tool before anything goes to production.