All articles
Conversion TrackingMeta PixelMeta CAPIAttributionLead Generation

_fbp and _fbc Cookies: What They Are and How to Capture Them

July 10, 202611 min read
_fbp and _fbc Cookies: What They Are and How to Capture Them

You can send Meta a perfectly formed conversion event and still watch your Event Match Quality sit at "Poor." Usually the culprit isn't the event. It's what's missing from it. Two of the most valuable match signals Meta accepts don't come from a form field at all. They come from cookies: _fbp and _fbc.

They matter most for exactly the visitors that are hardest to track: the anonymous top-of-funnel traffic that clicks an ad, lands on your page, and hasn't given you an email yet. Capture these two cookies and you can tie that person's eventual conversion back to the ad click you paid for. Miss them, and Meta is guessing.

Here's what each cookie is, how long it lasts, how to capture it without dropping it on the floor, and the mistakes that quietly cost you match quality. I checked every rule below against Meta's own documentation in November 2026.

What _fbp and _fbc actually are

Both are first-party cookies: set on your domain, and readable by JavaScript running on your domain. Neither contains personal data. They're opaque identifiers Meta uses for matching, and Meta's docs call them the Browser ID (fbp) and the Click ID (fbc).

_fbp, the Facebook browser ID. When the Meta Pixel loads and no _fbp cookie exists yet, it creates one, then reuses it on later visits. It identifies the browser, and it exists for essentially everyone once the Pixel has run, ad traffic or not. Its value looks like this:

fb.1.1720598400000.1834267592

That's four dot-separated parts: the fb prefix, a subdomain index, the creation time in milliseconds, and a random number the Pixel generates so every _fbp is unique. The subdomain index records which level of your domain the cookie was set on: 0 for com, 1 for example.com, 2 for www.example.com.

_fbc, the Facebook click ID. This one is the prize. When someone clicks your Meta ad, Meta appends an fbclid parameter to your landing URL:

https://yoursite.com/offer?fbclid=IwAR2xY...

The Pixel reads that fbclid and stores it as the _fbc cookie, in the same format:

fb.1.1720598400000.IwAR2xY...

The difference is in the last segment. _fbp ends in a random number, _fbc ends in the actual click ID. That click ID is what lets Meta connect a conversion to a specific ad, ad set and campaign, which is why _fbc is the higher-value of the two.

_fbp vs _fbc at a glance

_fbp_fbc
Meta calls itBrowser IDClick ID
IdentifiesThe browserThe ad click
Exists whenThe Pixel has run onceThe visitor arrived with fbclid in the URL
Formatfb.1.<creation time>.<random number>fb.1.<creation time>.<fbclid>
Lifetime90 days, per cookie scanners90 days, as Meta recommends
Hash before sending?NoNo
Conversions API fielduser_data.fbpuser_data.fbc

On lifetime: Meta's docs recommend a 90-day expiry for _fbc but don't give one for _fbp. Cookie scanners such as CookieYes list _fbp at 90 days as well. Safari cuts both much shorter, which is the catch covered below.

How to see them in your browser

On any page where your Pixel runs:

  1. Open DevTools (F12, or Cmd + Option + I on a Mac). In Chrome, go to Application, then Cookies, then your domain. In Safari and Firefox it's the Storage tab.
  2. Type _fb into the filter box.
  3. Compare each Value with the formats above, and check the Expires column to see when the browser will delete it.

No _fbc in the list? That's normal unless you arrived from a Meta ad. It only forms when there's an fbclid to read.

Why they move the needle

Meta scores every event you send on Event Match Quality: how confidently it can tie the event to a real person. More strong parameters, higher score, better attribution and optimization.

Email and phone are great when you have them. But a huge share of ad traffic converts (or half-converts) before handing over any personal detail, and for those people _fbp and _fbc are often the only signals you've got. _fbc in particular carries the click ID, so it's the difference between "a conversion happened somewhere" and "this conversion came from that campaign." Sending both is one of the cheapest ways to lift match quality across your whole funnel.

The catch: the browser is where these cookies go to die

If capturing two first-party cookies sounds trivial, it usually is, right up until the browser deletes them. The same forces that break browser-side pixels are working against _fbp and _fbc:

  • Safari's Intelligent Tracking Prevention caps script-written storage at 7 days, and JavaScript cookies at 24 hours in some cases. A visitor who clicks your ad today and converts ten days later has no _fbc cookie left, even though the conversion is 100% attributable.
  • Safari's Link Tracking Protection removes fbclid from links opened in Private Browsing, Mail and Messages (Mapp's notes on it), so _fbc never forms for those clicks.
  • Ad blockers and tracking prevention stop connect.facebook.net from loading, so the Pixel never runs and neither cookie is ever set.
  • Cookie consent, done right, holds the Pixel back until the visitor opts in, so early in the session the cookies simply don't exist yet.
  • Redirects, link shorteners and cross-domain jumps strip the fbclid from your URL before the Pixel can read it, so _fbc never forms in the first place.

Meta's docs go a step further than the Pixel does: they recommend also setting _fbc as an HTTP cookie from your server, with a 90-day expiry.

The lesson: don't assume the cookies were captured cleanly at page load and will still be there later. Capture them at the moment of conversion, and have a fallback.

How to capture them reliably

Three moves cover the vast majority of cases.

1. Read the cookies when the visitor converts, not just on landing. On your domain, at submit time, read them straight from document.cookie:

function readCookie(name) {
  const match = document.cookie.match(
    new RegExp("(?:^|;\\s*)" + name + "=([^;]*)")
  );
  return match ? decodeURIComponent(match[1]) : undefined;
}

const fbp = readCookie("_fbp");
let fbc = readCookie("_fbc");

2. Rebuild _fbc from fbclid when the cookie is missing. This is the step most people skip, and it's one Meta documents. If there's no _fbc cookie but you have the fbclid, build the value yourself as fb.1.<creation time>.<fbclid>, following three rules from Meta's docs:

  • Use 1 as the subdomain index when you generate the value yourself.
  • Use the time you first saw the fbclid as the creation time, not the time of the conversion.
  • Keep the fbclid exactly as you received it. Meta's docs say the click ID is case sensitive, so never lowercase it or change it in any other way.

So save it the moment the visitor lands, along with the time:

// On landing: remember the click ID and when you first saw it.
const fbclid = new URLSearchParams(location.search).get("fbclid");
if (fbclid && !sessionStorage.getItem("fbclid_seen")) {
  sessionStorage.setItem(
    "fbclid_seen",
    JSON.stringify({ fbclid, at: Date.now() })
  );
}

// At conversion: prefer the Pixel's cookie, fall back to the saved click ID.
if (!fbc) {
  const saved = JSON.parse(sessionStorage.getItem("fbclid_seen") || "null");
  if (saved) fbc = `fb.1.${saved.at}.${saved.fbclid}`;
}

sessionStorage keeps the value across pages in the same tab, which covers a landing page that links to a separate form page. For journeys that last days, store it in a cookie your server sets, as Meta recommends. And keep the fbclid alive in the first place: don't bounce visitors through a shortener that drops the query string.

3. Send them server-side, in plain text. Pass fbp and fbc in the user_data of your Conversions API event. Two rules people get wrong:

  • Do not hash them. Email, phone and name get SHA-256 hashed, but Meta's customer information parameters mark fbc and fbp as "Do not hash." Hashing them breaks the match.
  • Share an event ID between the CAPI event and the browser Pixel event, so Meta deduplicates them and counts the conversion once.

Sending them from your server instead of the browser takes cookie lifetimes out of the equation for that event: you read each cookie while it still exists and forward the value server to server, where no browser can expire it.

Or let Meta's library handle it. Meta's open-source Parameter Builder library reads and saves these values for you, in JavaScript on the client and in PHP, Java, Python, Node.js and Ruby on the server. The values it builds end with an extra "appendix" segment. Send those exactly as they are too.

The mistakes that quietly cost you match quality

  • Hashing _fbp / _fbc. The single most common error. They must be sent raw.
  • Changing the click ID. Lowercasing, trimming or "cleaning up" the fbclid breaks it. Meta treats it as case sensitive.
  • Using the conversion time as the creation time. When you build _fbc yourself, the timestamp is when you first saw the fbclid.
  • Capturing only on the first page. SPA funnels and multi-step forms never reload, so a cookie value grabbed at landing can be stale or gone by the time the conversion fires. Read the cookies at submit.
  • No fbclid fallback. If you only read the _fbc cookie and never rebuild it, every visitor whose cookie was blocked or expired loses their click match.
  • Losing fbclid to redirects. A "click → shortener → redirect → landing page" chain often arrives with the parameter stripped, so _fbc can never form.
  • Firing before consent. Reading cookies that shouldn't exist yet, or setting them before the visitor opts in, is both useless and a compliance risk.

How Collectform captures them for you

Wiring all of this by hand (reading the cookies at the right moment, forwarding them unhashed, hashing everything else, deduplicating against the Pixel) is exactly the kind of plumbing that's easy to get subtly wrong. In Collectform it's built into the form:

  • Read when each event fires. Every time the form sends an event (a view, a start, a submission or a button click), it reads _fbp and _fbc from the visitor's browser at that moment, while the values still exist.
  • Saved on the response. The values are stored with each submission, so you can see them on the response in your dashboard instead of guessing from Events Manager.
  • Sent the way Meta asks. fbp and fbc go to the Conversions API server-side in plain text, next to your SHA-256-hashed advanced matching fields, the visitor's IP address and user agent, and an event ID shared with the browser Pixel so Meta deduplicates.
  • Consent-aware. With the form's cookie consent banner turned on, Collectform doesn't read either cookie, or send anything to Meta, until the visitor accepts marketing cookies.

Here's the shape of the user_data block it sends, with the values shortened:

{
  "user_data": {
    "em": ["<sha256 of the email>"],
    "ph": ["<sha256 of the phone digits>"],
    "fbp": "fb.1.1720598400000.1834267592",
    "fbc": "fb.1.1720598400000.IwAR2xY...",
    "client_ip_address": "203.0.113.7",
    "client_user_agent": "Mozilla/5.0 ..."
  }
}

When you connect your Meta Pixel, Collectform loads it on the page, and the Pixel creates _fbc from the fbclid the normal way. What Collectform doesn't do yet is rebuild _fbc itself when the Pixel can't run, for example behind an ad blocker. If that matters for your traffic, the fallback in step 2 above, or Meta's Parameter Builder, covers it.

If your site runs on Next.js, the Next.js server-side tracking guide walks through the full setup.

The takeaway

_fbp and _fbc are two of the highest-leverage match signals Meta accepts, and they're the ones you're most likely to be dropping. The browser expires them, blockers kill them, and redirects strip the fbclid before _fbc can even form.

Capture them at conversion time. Never hash them. Keep the click ID exactly as Meta sent it.

Server-side CAPI with automatic _fbp / _fbc capture, deduplication and consent handling is included on every Collectform plan, from $20/month billed yearly, with a 7-day trial. Explore templates or start building with Collectform.

Frequently asked questions

The lead tracking form platform built for paid traffic.

Replace your weak form with a high-converting, multi-step lead form, with server-side tracking built in. Add it to the page you already have with 2 lines of code.

7-day trial · No credit card · From $20/mo, billed yearly