Conversion Tracking

What Does a Healthy Meta CAPI Delivery Rate Look Like?

A healthy Meta CAPI delivery rate is 99–100%. Here's how to calculate it, why it's a weak signal on its own, and the two numbers to watch instead.

Quick answer

A healthy Meta Conversions API delivery rate is 99–100%. It is a pass/fail number, not a number you tune: anything below 99% means events are being rejected and something is broken. The catch is that delivery rate only measures the events you actually attempted to send — it says nothing about the conversions you never sent at all, and nothing about whether Meta could match the events to real people. Track it alongside coverage (events attempted ÷ conversions that happened) and Event Match Quality.

Recover the leads you're already earning

Tell us what you're trying to track or fix. We'll show you which visitors your forms miss — and how PartialLeads recovers and qualifies them.

A healthy Meta Conversions API delivery rate is 99–100%. It is a pass/fail number, not one you optimise — below 99% means events are being rejected and something is broken. But a perfect delivery rate proves less than it sounds. It only counts the events you actually attempted, and says nothing about whether Meta matched them to real people.

That gap is where most server-side setups quietly lose money. The dashboard is green, the conversions are missing, and nobody can explain the difference.

What Does a Meta CAPI Delivery Rate Actually Measure?

Delivery rate is the share of the events you sent that Meta accepted: events accepted ÷ events sent. It is a measurement of the HTTP conversation between your server and Meta’s endpoint, nothing more. It starts the moment your code decides to fire an event and ends the moment Meta’s response comes back.

Three separate things happen in a server-side conversion, and the Conversions API only scores the middle one:

  1. A conversion happens. Someone buys, books, or submits a form.
  2. You attempt an event, and Meta accepts it. This is delivery.
  3. Meta resolves that event to a real user. This is match quality.

Delivery rate owns step two. Step one is coverage, and it lives entirely in your code — Meta has no idea a conversion happened if you never told it. Step three is Meta’s graph, which you influence but do not control.

Diagram mockup: five pipeline steps from conversion happens to person matched, with three coloured brackets labelled coverage, delivery rate and match quality spanning different parts of the chain, plus a response body card showing 200 OK with events_received of 5 against 6 sent

One detail catches nearly everyone: an HTTP 200 is not an acceptance. Meta’s API returns a body containing events_received, and that count can be lower than the number of events in your payload. Send six events, get a 200 back with events_received: 5, and you just lost one without an error in your logs. A delivery rate built on status codes rather than on that count will read 100% forever.

What Is a Healthy Meta CAPI Delivery Rate?

99–100%. There is no acceptable band below that, which makes delivery rate different from every other tracking metric you read.

Event Match Quality has a range because matching depends on the audience. Match rate has a range because identity is hard. Delivery has no range, because rejection is deterministic: Meta refuses events for structural reasons — a bad token, a malformed payload, wrongly hashed customer data, a timestamp outside the window. Fix the structure and every event goes through. Nothing about your traffic or your audience makes 94% a reasonable number.

So read it like a smoke alarm:

  • 99–100% — normal. At most a handful of transient network errors or rate limits, retried and cleared.
  • 95–99% — one systematic bug hitting a subset: usually one event type, one source, or one payload shape.
  • Under 95% — a broken token, a schema change, or a misconfigured dataset. Treat it as an outage.
  • 0% — the token expired or was revoked. The most common catastrophic failure and the easiest to miss, because nothing in your own application errors.

If you have never confirmed that events leave your server and arrive at all, start with whether your Meta CAPI is working before you start computing rates on it.

Why Does a 99% Delivery Rate Still Leave You Under-Reporting?

Because the denominator is wrong. Delivery rate divides by events you sent, not by conversions that happened. Every conversion your code never attempted is invisible to the metric — and those are the ones that cost you.

Picture a month with 412 orders in your store admin. Your server attempted 318 events. Meta accepted 317. Delivery rate: 99.7%. Coverage: 77%. Ninety-four conversions were never offered to Meta at all, and the number on your dashboard was green the entire time.

Where the 94 go:

  • Browser-dependent firing. If the event only fires from a client-side hook, ad blockers, closed tabs, gateway redirects and crashed scripts each eat a slice.
  • Paths without a dispatch site. Manual orders, phone orders, subscription renewals and admin-created records take a code path nobody wired up.
  • Silent filters. A rule that skips events without an email, a test-mode check that never got removed, a currency the handler doesn’t recognise.
  • Late conversions. A purchase landing outside Meta’s seven-day event_time window is dropped on arrival unless the timestamp is clamped.

Coverage is the number that moves your reporting. Delivery rate just tells you the pipe is clear.

How Do You Calculate Your Real Delivery Rate?

Count three things over the same window, in the same timezone, and divide twice:

coverage       = events attempted  /  conversions that happened
delivery rate  = events accepted   /  events attempted

The first count — conversions that happened — has to come from a system that does not depend on tracking. Your order table, your CRM record count, your payment processor’s ledger. If you count conversions using the same code that fires the events, both numbers move together and the ratio is meaningless.

Four rules keep the arithmetic honest:

  • Count events_received, not 200s. Parse the response body. A partial acceptance is a failure for one event, not a success for the batch.
  • Exclude test traffic from both counts. Events carrying a test_event_code route to the Test Events tab, not your live dataset, so they belong in neither numerator nor denominator — and keeping test events out of live data is what stops them skewing campaign optimisation too.
  • Count attempts, not retries. A conversion that failed twice and succeeded on the third try is one delivered event, not three attempts and one success.
  • Use the same day boundary everywhere. Your ledger is probably in your business timezone and your logs in UTC. An eight-hour offset invents a phantom gap at either end of the month.

Do this by hand once a month and you will find the leak. Automate it and you will find it the week it starts.

What Makes a Delivery Rate Drop, and How Fast Should You React?

Four failure classes, and they need different reaction times.

Authentication failures stop everything at once. A token is revoked, regenerated by a colleague, or tied to a user who lost access to the asset. Delivery goes to zero and stays there, and every event fired during the outage is gone once it ages past the seven-day window. React within hours, not days.

Payload validation failures hit a subset. One event type or one source starts failing because a field changed shape: a phone number arriving unhashed, a currency code in the wrong case, a value sent as a string. Meta’s error body names the cause with a code, a subcode and an fbtrace_idMeta rejects CAPI events for a short and diagnosable list of reasons. React within a day.

Timestamp failures look like random drops and are usually a backfill. event_time must fall inside Meta’s seven-day window; older events are refused. When you are catching up after an outage, clamp the timestamp to the oldest accepted value rather than sending the true one and eating a rejection.

Transient failures — rate limits, timeouts, a bad minute at either end — should never reach your delivery rate at all, because a retry queue absorbs them. If they do, you don’t have a retry queue, and that is the actual bug.

One class never shows as a failure: regional data-handling flags. Events from California require data_processing_options to be set correctly, and without it the traffic can be dropped on Meta’s side behind a healthy-looking response. Only reconciling against your own order count catches that one.

Should You Optimise Delivery Rate or Match Quality?

Match quality, every time — once delivery is at 99%+. Delivery is a binary you fix once; Event Match Quality is the number that decides whether Meta’s optimiser can actually use the events you worked so hard to deliver.

The distinction is worth stating plainly, because the two get conflated constantly:

  • Delivery rate is measured in your logs. It answers: did Meta take this?
  • Event Match Quality is measured by Meta, per event. It answers: could Meta tell who this was?
  • Match rate is measured in your own data. It answers: could you tie this conversion to a tracked session in the first place? A useful benchmark for what a good match rate looks like is a different exercise entirely.

A perfectly delivered event with no email, no phone and no click ID is a delivered event that teaches Meta nothing. It counts as a success in your delivery log and contributes almost nothing to optimisation. That is the failure mode worth worrying about, and it is invisible if delivery rate is the only number you check.

The honest split: you control dispatch, the platform controls matching. Get dispatch to 100%, then spend your effort on the identifiers you attach — because those are the other half you can still influence.

How Does PartialLeads Make the Delivery Number Trustworthy?

By removing the browser from the dispatch decision and writing down what happened to every single event.

Purchases arrive server-side from the store or CRM webhook, not from a script in the visitor’s tab, so every order in your admin produces a conversion event regardless of blockers, closed tabs or gateway redirects. That is the claim worth making about delivery: 100% of your orders get sent. Whether Meta ties each one to a user is the platform’s half, and no vendor controls it.

Underneath, five dispatch sites cover the paths that usually go uninstrumented — the hot path, the catch-up worker, real-time conversions, the ecommerce fan-out and inbound purchases — so a conversion doesn’t fall through a gap because it arrived by an unusual route. Each send carries a deterministic event_id (a SHA-256 of the pixel ID, event name and record ID) against a dedup table with a uniqueness constraint, so a redelivered webhook physically cannot double-fire and inflate your numerator.

CAPI activity log mockup: six rows with event names in monospace, green OK, red FAILED and grey QUEUED status dots, META platform chips, cyan EMQ values and timestamps, with a footer strip reading sent 318, accepted 317, failed 1, queued 2

The CAPI activity log is where you read it: one row per send, with the status, the platform, the event name and the error text when there is one. Because the dispatcher compares the events Meta reports receiving against the events it sent, an HTTP 200 that silently drops an event is recorded as a failure rather than a success. The Leads list carries an API column naming which conversion APIs each lead was dispatched to, so per-lead audits don’t require a log dive.

Failures are handled by class rather than blindly retried: authentication errors flip the integration to a reconnect-needed state instead of burning retries, transient errors retry on the next worker cycle, and permanent payload errors stop. Late events have their event_time clamped to Meta’s seven-day maximum, so a catch-up send lands with a clamped timestamp instead of being rejected — which also means backfill is bounded by Meta’s window, not unlimited.

One honest constraint: none of this raises match quality by itself. Server events still need the platform cookies your client-side base tag sets, and the identifiers you collect set the ceiling. With email and phone as required form fields, PartialLeads consistently delivers EMQ 9+ — observed across customer accounts — but that number travels with its condition, and an audience of work emails can resolve lower even with a perfect payload.

What breaks The mechanism Where you see it in the dashboard
A conversion never produces an event Purchases arrive server-side from the store or CRM webhook and fan out automatically, independent of the browser Purchases ledger, matched/unmatched wedge
A redelivered webhook double-counts Deterministic event_id with a uniqueness constraint per config — a resend cannot fire twice CAPI activity log
An HTTP 200 hides a dropped event Events received are compared against events sent; a semantic failure is recorded as failed CAPI activity log, status column
An expired token stops sends silently Auth failures flip the config to reconnect-needed; transient failures retry next cycle; permanent ones stop Integration status
A late conversion misses the window event_time clamped to Meta’s seven-day maximum so the send still lands CAPI activity log
You can’t tell which leads were dispatched Per-lead API column naming every conversion API that lead went to Leads list

Recover the leads you're already earning

Tell us what you're trying to track or fix. We'll show you which visitors your forms miss — and how PartialLeads recovers and qualifies them.

Sources


Frequently asked questions

QWhat is a good Meta CAPI delivery rate?
99–100%. Delivery rate is pass/fail rather than a range, because Meta rejects events for structural reasons — a bad token, a malformed payload, wrongly hashed data, a timestamp outside the seven-day window. None of those depend on your audience. Anything under 99% means a specific bug is rejecting a specific slice of your events, and under 95% should be treated as an outage.
QIs delivery rate the same as Event Match Quality?
No. Delivery rate is measured in your own logs and answers whether Meta accepted the event. Event Match Quality is scored by Meta per event and answers whether Meta could resolve the event to a real user. You can have 100% delivery and poor match quality — that happens whenever events are accepted but carry thin customer data, and it is the more expensive problem of the two.
QDoes an HTTP 200 mean Meta accepted my event?
Not necessarily. The response body carries an `events_received` count, and it can be lower than the number of events you put in the payload. A partial acceptance returns a 200 with a smaller count, so a delivery rate built on status codes will read 100% while events quietly disappear. Parse the body and compare received against sent.
QWhy did my delivery rate drop to zero overnight?
Almost always an access token. Tokens get revoked, regenerated, or tied to a user who lost access to the ad account or dataset. Nothing in your own application errors, so the only signal is the delivery number itself. Events fired during the outage are unrecoverable once they age past Meta's seven-day event window, which is why token failures need a same-day response.
QShould test events count toward my delivery rate?
No. Events carrying a `test_event_code` route to the Test Events tab rather than your live dataset, so they belong in neither the numerator nor the denominator. Leaving them in inflates your volume and can mask a real drop — if you fire fifty test events in a debugging session, a genuine failure in live traffic gets averaged away.
QCan a 100% delivery rate still mean broken tracking?
Yes, and it usually does. Delivery rate divides by the events you attempted, so conversions your code never attempted are invisible to it. Reconcile against a system that doesn't depend on tracking — your order table or payment ledger — and compare the counts. The gap between conversions that happened and events attempted is where the real loss lives.
QDoes Meta show a delivery rate number in Events Manager?
Not as a single headline metric. Events Manager shows event volume, diagnostics and match-quality scoring, but the accepted-over-sent ratio is something you compute from your own dispatch logs, because only your side knows how many events you attempted. That asymmetry is exactly why the number is worth instrumenting yourself rather than waiting for a dashboard to raise a flag.
QHow often should you check delivery rate?
Continuously if it can alert you, monthly at minimum if it can't. The failure modes are fast and silent: a token dies and the number goes to zero with no error anywhere in your stack. A weekly glance catches a bad deploy inside the seven-day window where events can still be re-sent; a monthly reconciliation catches slow coverage leaks that a rate alone never shows.

Find the qualified leads your forms are currently throwing away.

Install PartialLeads on one landing page, send traffic, and compare what your CRM captured against what PartialLeads recovered and qualified.