← All articles

Blog

How to Verify Your Meta Conversions API (CAPI) Is Working

verify meta conversions apimeta capi not workingtest facebook conversions apicapi setup verification

You set up the Conversions API (CAPI) thinking, "Now I'll finally recover what iOS and ad blockers were dropping" — but have you actually confirmed that events are reaching Meta from your server? You may believe CAPI is configured, yet a lapsed access token or a server that never fires can mean not a single event is actually arriving at Meta. Worse, because your browser pixel is still working, it can look like "tracking is fine overall" — and that's the hardest case to catch.

Does any of this sound familiar?

  • In Events Manager, server events are still "not received," or the count is suspiciously low
  • The browser pixel shows up, but you can't find the server-side event anywhere
  • You're warned that Event Match Quality is low, but you don't know why
  • Since adding CAPI, your conversion counts seem to have doubled up

This guide organizes how to confirm CAPI is actually working, why events can be sent from the server yet still not get used, and how to think it through without guessing.

Before you check: CAPI doesn't replace the pixel — it complements it

Let's get the premise straight first. CAPI is not a mechanism that replaces the browser pixel (the one fbevents.js sends to facebook.com/tr); it sends events directly to Meta from your server to complement it. The goal is to fill in the share that the browser pixel drops due to ITP, ad blockers, iOS signal loss, and so on, via server-side sends.

That's exactly why what you need to check differs from a pixel-only setup. Separating these three levels makes diagnosis dramatically easier.

Level Meaning Common trap
① Server sends Your server sends the event to Meta's API Token lapsed / server never fires
② Meta receives Meta accepts the server event Missing parameters / wrong destination (pixel ID)
③ Match & dedup Cross-checks with the browser side, ties to a person, removes duplicates event_id mismatch causes double counting, low EMQ

The key point: ① sending and ③ matching are different things. Even if requests leave your server, problems with deduplication against the browser side or with match quality can mean the events aren't in a usable form for optimization. Most checks stop at ①.

When you run CAPI alongside the browser pixel, Meta deduplicates the two events that share the same event name and event_id. A missing or mismatched event_id causes double counting or loss. See Verifying deduplication (event_id) for details.

Step 1: Look at the "connection method" in Events Manager

First, in Events Manager → your dataset (pixel) → each event's details, check where the event is arriving from.

  • Each event shows a connection method such as "Server," "Browser," or "Both server and browser"
  • Does your target event (Purchase, Lead, etc.) show Server?
  • Is the server event's received time recent (i.e., not stopped)?

What it tells you: whether there's a track record of events arriving from the server (the closest check to ① and ②). What it doesn't: whether the code you're configuring right now is sending correctly (Step 2 covers that).

Common pitfall: assuming "I configured CAPI, so it's working." It's not rare for someone to merely save the settings screen while the server-side code or connector has never fired once. Always look at the actual record of received events.

Step 2: Test Events + test_event_code

Meta's official Test Events (Events Manager → your dataset → Test Events) displays events arriving right now in real time. For CAPI, the trick is to attach a test_event_code to your server send.

  1. Grab the test_event_code shown on the Test Events screen (a string like TEST12345)
  2. Include that test_event_code in your server-send payload and send one test event
  3. Within seconds, it should appear in the Test Events stream as a Server event

What it tells you: that your server code, specifically, can send an event in a form Meta receives (the closest proof to ③).

Common pitfall: being satisfied by a browser action alone. A browser event appearing in Test Events is proof the pixel is working — not proof that CAPI (the server) is. Always confirm that a server-originated row appears.

Check API responses on the server side

A detail competitors often highlight that's easy to overlook: your server receives an HTTP response every time it calls Meta's Conversions API. Logging and checking those responses is one of the fastest ways to catch problems.

HTTP status Meaning Action
200 Meta accepted the event Confirm the response body's events_received count matches what you sent
400 Bad request — malformed payload or missing required fields Read the error message; common causes are a missing event_time, action_source, or improperly hashed user_data
401 / 403 Authentication or permission failure Your access token is expired, revoked, or lacks the required scope — regenerate it in Events Manager

If you don't log API responses today, you're flying blind. An error rate above a few percent means events are being silently dropped.

Tip: Before deploying changes, paste your JSON payload into Meta's Payload Helper (inside Events Manager → Conversions API → Payload Helper). It validates required fields, correct hashing, and common mistakes — without actually sending the event to your pixel.

Step 3: Are both browser and server present — and deduplicated?

When you run CAPI alongside the pixel, the healthy state is that both appear and then get deduplicated. On Test Events, confirm the following.

  • For the same conversion, can you see both the browser and server events?
  • Do the two share the same event name and the same event_id?
  • Does Meta recognize them as "deduplicated" and not double-count?

What it tells you: not just that events arrive, but that they're correctly cross-checked and double counting is prevented.

Common pitfall: the browser and server build event_id differently (only one side sets it, or they use different values). Then Meta treats them as separate events and your conversions balloon to double. Align the event_id generation logic on both senders.

Step 4: Event Match Quality (EMQ) and customer-information parameters

CAPI's value isn't just "it arrives" — it's that the event ties to a person. What shows this is Event Match Quality (EMQ).

  • In each event's details in Events Manager, check the match quality score and which customer-information parameters are being sent
  • Are email (em), phone (ph), name (fn/ln), external ID (external_id), and the like sent after being hashed?
  • The more — and more accurate — parameters you send, the higher match quality generally goes

What it tells you: whether arriving events tie to a person on Meta in a form usable for optimization and attribution.

Common pitfall: trying to send personal information as-is (in plain text). Fields like em and ph must be hashed (SHA-256). Send raw values and Meta can't handle them correctly, and they won't match. Always confirm the hashing happens on the server side.

Don't forget fbp, fbc, and device signals

Beyond PII fields like email and phone, several non-PII parameters significantly boost match quality — and competitors' guides consistently flag them:

  • fbp (Facebook browser ID): the _fbp cookie value set by the Meta pixel. Forwarding it from the browser to your server send lets Meta tie the server event to the same browser session.
  • fbc (Facebook click ID): the _fbc cookie value, populated when a user arrives via an ad click. Passing it is critical for attributing server events to the ad that drove the visit.
  • client_ip_address and client_user_agent: Meta uses these to match the server event to the browser event. Without them, match quality drops noticeably even when hashed PII is present.

These four fields don't require user consent beyond what the pixel already needs, yet omitting them is one of the most common reasons for a low EMQ score. For more on signal loss from browsers, see Safari ITP and Conversion Loss.

Why events can be sent from the server yet not get counted

You confirmed sending (①), but the conversion isn't used as expected. Common reasons:

  • Lapsed access token: the CAPI access token is expired or revoked, so the send is rejected
  • Faulty deduplication: browser and server don't share an event_id, causing double counting or loss
  • Insufficient hashed parameters: too little customer info means low match quality, so it's underused in optimization
  • The server isn't firing: the server-side send simply isn't running at the moment of conversion
  • Wrong destination (pixel ID): you're sending to a different dataset or an invalid destination

In short, confirming the server "can send" is not proof that Meta received, matched, and deduplicated it in production.

What checking on your own machine can't tell you

Checking once, by hand, on your own machine has two structural limits.

  1. Your environment isn't your visitors' environment. Your test send with a test_event_code may go through, yet that doesn't mean the same send fires on the real production server path at the moment an actual visitor purchases or inquires. A successful test send is not the same as a successful production flow.
  2. Conversions involving an ad click are hard to verify. To properly see "does it really track and optimize via an ad," you'd need to click a live ad to recreate the path — which carries the risk of an ad-policy violation as a self-click.

Judging "the test send succeeded, so it's fine" tends to miss the problem of server events going missing on the real path your visitors take.

A checklist to verify with confidence

  • In Events Manager, does the target event show a Server connection method?
  • Is the server event's received time recent, not stopped?
  • Does a server send with a test_event_code appear in Test Events as Server?
  • For the same conversion, are both browser and server visible and deduplicated with the same event_id?
  • Is the CAPI access token valid (not lapsed)?
  • Is customer info (em, ph, etc.) sent hashed, with match quality in an acceptable range?
  • Beyond your own test send, are server events not missing on the real visitor path in production?

Frequently asked questions

Q. If the browser pixel works, isn't CAPI redundant? A. No. CAPI complements, on the server side, the share the browser pixel drops due to ITP, ad blockers, iOS signal loss, and so on. With the pixel alone, that dropped share is simply lost. For the firing check, see also Verifying the Meta pixel fires.

Q. Events show in Test Events, but they don't say "Server." A. That's likely only the browser pixel working. Send one event from your server with a test_event_code attached and confirm a Server-originated row appears in the stream. If it doesn't, suspect that the server code isn't firing or the token is invalid.

Q. Since adding CAPI, my conversions seem to have doubled. A. Most likely the browser and server events don't share an event_id and aren't being deduplicated. Align the event name and event_id on both. See Verifying deduplication (event_id) for details.

Q. How do I raise Event Match Quality (EMQ)? A. Send more — and more accurate — hashed customer-information parameters. Sending email, phone, name, external ID, and the like, correctly hashed (SHA-256) on the server, generally raises the score.

Q. I used Meta's one-click CAPI setup (CAPI Gateway). Do I still need to verify? A. Yes. One-click CAPI (released April 2026) removes the configuration complexity, but you still need to confirm events arrive with a Server connection method, that deduplication works, and that EMQ is acceptable. Because Meta hosts the infrastructure, you won't have direct access to server logs — so the checks in Steps 1 through 4 above become even more important. Note that one-click CAPI covers standard web events only; custom events or offline conversions still require a manual implementation you'll need to verify separately.

Q. How long until the access token expires? A. The expiry depends on the token type and how it was issued. Because a lapse silently stops your server sends, it's safest to check the received-event record regularly and, for long-term operation, decide a token-renewal policy in advance.

Conclusion: don't stop at "it sends" — confirm "Meta received and matched it"

Working through Step 1 (connection method) → 2 (test_event_code) → 3 (deduplication) → 4 (match quality) lets you isolate everything from sending to matching. What matters is the whole picture: whether server events are received, matched and deduplicated against the browser side, and recorded on the real visitor path in production. For the full picture of Meta conversion tracking, see The Complete Guide to Meta Conversion Tracking.

ConversionOK runs your live page in an independent, isolated browser and intercepts the events actually sent, then verifies them — with no need to click your own ad and no interference from your office environment. Start with a free static check to confirm the entry point of your measurement.