Consent · engineers · PMs
Limited Data Use is a parameter, not a vibe
Pixellint flags LDU country without state because Meta's own docs say they will geolocate. That is the opposite of a restriction you thought you set.
Browser pixel
On facebook.com/tr, Limited Data Use is dpo=LDU. dpoco is the country: 1 for the United States, 0 to let Meta geolocate. dpost is the numeric state code, or 0 to let Meta geolocate. Typos in dpo that are not LDU do nothing. A comment in GTM named LDU does not travel. Pixellint checks the documented values: vendor.meta.param.dpo.invalid, vendor.meta.param.dpoco.invalid, vendor.meta.param.dpost.invalid.
dpo is the switch. dpoco and dpost are the geography Meta should use instead of guessing. Send all three when you know the user is in a US state you care about. Send dpo=LDU with dpoco=0 and dpost=0 only if you intend Meta to geolocate. That last pair is a restriction that asks the vendor to invent the region.
https://www.facebook.com/tr?id=1234567890123456&ev=Purchase&cd%5Bvalue%5D=129.99&cd%5Bcurrency%5D=USD&dpo=LDU&dpoco=1&dpost=1000
Country without state
Country without state is the quiet failure. You sent dpoco=1 and omitted dpost, or you sent dpost=0. Meta geolocates instead of taking your word. Pixellint has vendor.meta.ldu.country_without_state for that pair. If you know the user is in California, send the state integer Meta documents. If you do not know, do not pretend LDU is complete.
This is Meta's documented behavior, not a Pixellint extra. The finding exists because the docs say geolocation happens when the state is missing or zero while the country is set. A Purchase with LDU that still trains on a geolocated region is not the restriction the ticket described.
https://www.facebook.com/tr?id=1234567890123456&ev=Purchase&cd%5Bvalue%5D=129.99&cd%5Bcurrency%5D=USD&dpo=LDU&dpoco=1
CAPI requires country when LDU is sent
On the Conversions API the same idea is data_processing_options with LDU, plus data_processing_options_country, plus data_processing_options_state. Pixellint requires the country when LDU is sent: vendor.meta-conversions-api.body.ldu_requires_country. A body that names LDU and leaves country out is an incomplete processing instruction, not a default to US.
Do not send data_processing_options: ["LDU"] and stop. Do not copy the browser dpo trio into user_data. They are event-level processing options, not customer information parameters. Hashing em does not fill country. fbc does not fill country.
{
"data": [{
"event_name": "Purchase",
"event_time": 1770000000,
"action_source": "website",
"event_source_url": "https://example.com/checkout/thank-you",
"user_data": {
"em": ["a85e9ca18f34935ab9b0381b25bfad2455444112b0149270fd88e3da172fe196"]
},
"custom_data": { "value": 129.99, "currency": "USD" },
"data_processing_options": ["LDU"]
}]
}
Pixel and CAPI have to agree
LDU on the browser and a full-fidelity server Purchase with no processing options is two policies for one order. Dedup may keep the richer event. Then you paid for Limited Data Use on the tag and did not get it on the event that trained the model.
Use the same event_id on both hops. Put LDU on both hops, or on neither, on purpose. A test_event_code on CAPI diverts to the test tool (vendor.meta-conversions-api.testing.test_event_code_present). It does not make LDU optional. It also does not apply LDU to the browser pixel.
Not the IAB string
US Privacy and GPP travel on the URL for the rest of the chain. LDU is Meta-specific. Set both if both apply. Do not assume Meta reads 1YNN from a Floodlight tag you did not fire. us_privacy=1YNN does not set dpo. gpp does not set dpo.
Hashing the email does not replace LDU. Hashing is matching. LDU is a processing restriction. A hashed em on an unrestricted pixel is still full processing of a matchable event. Send both when both apply, and keep state codes consistent with what your CMP actually collected.
Check the artifact
Paste the pixel URL or JSON body into the
playground. Same engine as
pixellint validate. Nothing leaves the tab.