All Posts
Measurement

Server-Side CAPI Is Only Half the Fix

The Conversions API solves transport, not identity. Here are the three identity-resolution gaps that quietly break B2B attribution after you go server-side — and the checklist to close them.

· 5 min read
RevenueProven Team
By RevenueProven Team· Editorial
Two desktop monitors displaying analytics charts and code, representing conversion event data pipelines

Most B2B teams treat the Conversions API as a finish line. You stand up server-side event forwarding, the platform stops complaining about browser signal loss, and everyone declares tracking fixed. Then the reported conversions still undercount the CRM, the lift numbers still look thin, and nobody can explain why.

The uncomfortable answer: CAPI solves transport. It does not solve identity. Getting the event to the platform's server is the easy half. The hard half is whether the platform can tie that event to a real person in its graph — and in B2B, that is where the leak lives.

Transport Was Never Your Real Problem

A server-side event that arrives with a thin identity payload is a server-side event that gets discarded. Meta is explicit about this: Event Match Quality is a score from zero to ten that reflects how effectively the customer information parameters you send can be matched to Meta accounts, calculated from the last 48 hours of data (Meta Business Help Center). It is a matching score, not a delivery score. You can have flawless uptime and a mediocre EMQ.

LinkedIn is blunter still. Its Conversions API docs describe checking conversion status in Campaign Manager and warn that a Low Match Rate flag means the information you streamed "has a low likelihood of successful event-to-profile matching" (Microsoft Learn). Events land. Members don't match. The rule shows Active and the data is quietly worthless.

The operational tell is a 201 or 200 response. A successful HTTP status is acknowledgement of receipt — it is not evidence of attribution, identity matching, or business impact. Most tracking monitoring stops at the status code, which is exactly why these gaps run for quarters undetected.

The Three Identity Gaps That Are Specific to B2B

Gap one: the work email you never collected. Platform graphs are built on personal accounts. Meta's own guidance is to send multiple customer information parameters when available, and email carries the heaviest weight (Meta Business Help Center). But your form collected [email protected] and her Meta account is registered to a personal address. One identifier, wrong namespace, no match. LinkedIn is the exception here — it is the one graph where a corporate identity is the native identity — which is exactly why LinkedIn match rates are the benchmark your other channels should be judged against, not the outlier.

Gap two: the click ID that expired before the deal did. Google's enhanced conversions for leads exists precisely because GCLIDs break. It lets you send hashed first-party data at the form fill, then re-attach the same hashed identifier when the lead converts in your CRM, so the match can happen without a surviving click ID (Google Ads Help). If your offline conversion import still requires a GCLID, every deal with a sales cycle longer than the click ID's life is invisible by design.

Gap three: a single identifier per event. Google's own API documentation lists including multiple identifiers as a best practice for enhanced conversions, alongside normalizing and hashing with SHA-256 before import (Google Ads API docs). Meta accepts email, phone, external ID, name, and location fields in user_data. Most implementations send one. You are running a join on a single key and hoping it is populated.

The Resolution Checklist

Work this in order. It is roughly ordered by effort-to-payoff.

  1. Read the match-rate surface before you touch code. Meta Events Manager shows which parameters you send and what percentage of event instances include each one. LinkedIn Campaign Manager flags Low Match Rate on the rule. Both take minutes and tell you where the hole is.
  2. Add a second identifier to every event. Phone number in E.164, plus your own external_id. This is the single highest-leverage change most teams have not made.
  3. Capture personal email where it is honest to do so. Not a dark pattern — a genuine "where should we send the recording" field on webinar and content flows produces a second, graph-native identifier legitimately.
  4. Pass external_id consistently. LinkedIn's schema supports advertiser-provided external IDs once an initial event establishes the association with an accepted standard identifier. That association becomes reusable for later lifecycle events instead of re-sending direct identifiers each time.
  5. Move offline imports to enhanced conversions for leads. Send user-provided data at form fill; upload the same hashed identifier when the deal closes.
  6. Normalize before you hash. Lowercase, trim whitespace, strip dots and plus-addressing where the platform's spec says to. A hash of a non-normalized string is a hash of a different string. This silently destroys match rates and produces no error anywhere.
  7. Alert on match quality, not on delivery. Your CAPI monitoring should page on an EMQ drop or a Low Match Rate flag. Nobody should be paging on HTTP 500s alone — those get noticed. Match-rate decay does not.

What Changes When You Fix It

Two things, and only one of them is the reported number. The obvious win is that more conversions get credited, so channel-level ROAS and cost per acquisition stop flattering the channels that happen to have good identity coverage and penalizing the ones that don't.

The bigger win is bidding. Every automated bidding system on every one of these platforms trains on the conversions it can match, not the conversions you had. A low match rate does not just under-report — it feeds a biased training set, so the algorithm optimizes toward whichever segment of your buyers happens to be easiest to resolve. That is a slow, compounding misallocation that no attribution model will ever surface, because the model only ever sees the matched subset. It is the same structural blind spot that makes last-touch reporting overcredit branded search.

Do this week: open Events Manager and Campaign Manager, write down your current match signals, count how many identifiers you actually send per event, and check whether your hashing pipeline normalizes first. Three of those four are read-only. The fourth is usually a one-line fix that has been costing you budget for a year.