pixellint

Pixels · PMs · marketers · engineers

Thank-you page pixels miss the backend sale

If the purchase happens in a payment iframe, a native app, or a CRM two days later, the thank-you page never runs. That is why postbacks and conversion APIs exist. The browser pixel can read _fbp. The postback cannot unless you stored those values on the landing hit.

Browser conversion pixel

Easy to add in GTM on a thank-you URL. Easy to fire twice on SPA rerenders. Easy to miss when checkout is a redirect to Shopify, Adyen, Stripe Checkout, or an app store. The tag reads cookies the server does not have (_fbp, _ga, _gcl_aw), which is why hybrid setups keep a browser event and a server event with the same event_id.

Meta's browser conversion is facebook.com/tr?ev=Purchase with numeric id, cd[value], and cd[currency] as ISO 4217. Google Ads image conversion puts conversion_id in the path, expects label, and sends guid=ON and script=0 on the image fallback. GA4 uses /g/collect with v=2, tid G-, cid, and en=purchase. Those are three pixels, three hosts, three contracts, all still browser GETs unless you also send CAPI or Measurement Protocol.

MMP S2S postbacks

The MMP (Adjust, AppsFlyer, Branch, Singular) gives you a URL with macros: {idfa}, {gps_adid}, {click_id}, {revenue}, {currency}. Your app server or the MMP's own cloud expands them when the conversion is real and GETs or POSTs that URL to the ads platform. This is the install and in-app purchase path. The thank-you page never runs.

Postbacks do not see _fbp. If you need cookie matching on a web conversion, this is the wrong pipe. If you need an iOS install after ATT, this is the right pipe (plus SKAN, which is a different postback from Apple). Do not fire a web Purchase pixel from the app webview and an MMP postback for the same order without a shared event id; you will double-count in the ads manager and undercount in finance.

CAPI is a third pipe

Meta Conversions API, TikTok Events API, and cousins are JSON POSTs from your backend or from sGTM. They are not MMP postbacks and not thank-you pixels. action_source, event_time (10 digits of seconds for Meta), event_source_url for website, hashed user_data, and event_id for dedup against the browser pixel. pixellint validate json on that body; pixellint validate url on the browser pixel. Two artifacts.

CAPI can fire when the thank-you page never loaded: webhook from Shopify, 3-D Secure that returns to a different host, subscription renewal. That is the point. It cannot invent fbp if you never stored it. Capture click ids and first-party cookies on the landing GET, persist them against the session or order, and send them on the server event.

Macros on fired postbacks

A template postback in the MMP UI still contains {idfa} or [CACHEBUSTER] or ${CLICK_URL}. That is legal in template state. A fired postback in your access log that still contains those tokens never identified a device or a click. Pixellint core flags unexpanded macros on a fired URL (core.macro.unexpanded_in_fired_url). Mixed [NAME] and ${NAME} in one URL is core.macro.mixed_syntax. A macro in the hostname is core.macro.unsafe_position.

Expand on the server that knows the conversion is real. Do not send the template to the ads platform and hope they expand it. They will log a click id of the literal string {click_id}. Validate a production log line as fired. Validate the MMP partner template as template. Same URL shape, opposite expectations.

Which pipe you want

Lead gen with a stable thank-you page: a pixel can be enough. App installs and in-app purchases: MMP S2S, plus SKAN on iOS. Web checkout with ad blockers and ITP: pixel plus CAPI, same event_id. Offline CRM sales: offline conversions or CAPI with action_source that is not website. Hosted checkout on a third-party domain: server event, because your thank-you pixel either never runs or runs with the wrong referrer.

The dashboard that looks low is not a reason to fire all three pipes without dedup. Pick the pipe that sees the real conversion, add a second pipe only for match quality or for environments the first cannot see, and share an event id. A thank-you pixel plus an MMP postback plus CAPI for one Shopify order is three conversions unless you designed otherwise.

Check the artifact

Paste the pixel URL or JSON body into the playground. Same engine as pixellint validate. Nothing leaves the tab.