Preserving _fbp, _fbc, and fbclid through server-side Meta attribution
Updated July 14, 2026 · 10 min read
On web, Meta attribution quality is often decided before the Purchase event exists: the click ID must survive the landing page, consent timing, checkout redirects, and the server webhook that eventually emits CAPI.
The hard part is not sending a Purchase. The hard part is preserving a coherent identity envelope from first click to verified conversion without inventing two different users along the way.
The identity envelope Meta receives
For browser and server deduplication to produce a high-quality matched event, the browser path and the server path need to describe the same visitor. The browser path usually contributes _fbp and _fbc cookies. The server path contributes IP address, user agent, event_source_url, hashed customer data, and any first-party identifier you forward.
_fbp identifies a browser instance. _fbc binds the browser instance to a Meta ad click when the landing URL contains fbclid. If _fbc is missing but fbclid was present on the landing URL, the server can still reconstruct the click identity if the value was captured first-party before checkout.
The failure modes that lower attribution
- The landing page captures fbclid in the URL but never persists it before the user leaves for checkout.
- The Pixel writes _fbc after consent, but the server-side Purchase only reads cookies at webhook time, where no browser cookies exist.
- Stripe, Paddle, Shopify, or an app-store flow redirects the user, and the final purchase webhook has no event_source_url from the original landing context.
- CAPI receives Purchase with value and currency but no fbp, fbc, external_id, client_ip_address, or client_user_agent, so the event arrives but matches weakly.
- A new anonymous ID is minted on the pricing page and another one on the checkout success page, splitting a single visitor into multiple identities.
A server-side identity envelope should look like this
The exact storage layer does not matter. The invariant is that every checkout session and every webhook can recover the same click and visitor fields.
type MetaIdentityEnvelope = {
visitorId: string; // first-party anonymous ID, stable pre-login
sessionId: string; // landing/session scope, not a replacement for visitorId
fbp?: string; // fb.1.<creation_ms>.<random>
fbc?: string; // fb.1.<creation_ms>.<fbclid>
fbclid?: string; // raw click ID, stored only to reconstruct fbc if needed
landingUrl: string; // canonical event_source_url for server events
userAgent?: string;
ipAddress?: string;
consentState: "granted" | "denied" | "unknown";
};Fallback _fbc construction
When the URL contained fbclid but the _fbc cookie is missing, reconstructing fbc server-side is better than dropping click identity completely.
function fbcFromFbclid(fbclid: string, createdAtMs = Date.now()) {
return `fb.1.${createdAtMs}.${fbclid}`;
}
const fbc =
request.cookies.get("_fbc")?.value ??
(landingSession.fbclid ? fbcFromFbclid(landingSession.fbclid, landingSession.createdAtMs) : undefined);Implementation sequence
- 1On first page view, parse fbclid, utm parameters, referrer, and the canonical landing URL before any checkout redirect can erase them.
- 2Persist a first-party visitor ID and landing session in a same-site cookie or server session keyed by a signed cookie.
- 3After consent, let Pixel write _fbp and _fbc, but do not depend on Pixel timing as the only source of click identity.
- 4Attach the visitor/session key to checkout metadata, subscription customer metadata, or your own order row.
- 5When the verified Purchase webhook fires, rebuild user_data from the stored envelope, not from the webhook provider's request context.
Frequently asked questions
Is _fbc required for Meta CAPI attribution?
No single field is always required, but _fbc is one of the strongest web click identity fields when the user came from a Meta ad. If it is missing from CAPI while the browser event has it, match quality and attribution can drop.
Can I build _fbc from fbclid server-side?
Yes, if fbclid was captured from the landing URL and your consent policy allows using it. The usual format is fb.1.<creation_time_ms>.<fbclid>. The important part is preserving the original click value before redirects erase it.
Does _fbp replace external_id?
No. _fbp is a browser identifier. external_id is your first-party user or visitor identifier, normally hashed before being sent. Strong setups send both when available because they describe different matching surfaces.
Related guides
Not sure which signal path is breaking?
Zoruko audits your web and mobile code for broken Meta and TikTok signal chains, then ships each fix as a pull request you review.
Run a free audit