Free tool · Meta Conversions API
Meta Conversions API Payload Validator
Paste a Meta Conversions API event below to see what Meta will reject or fail to match: missing required fields, unhashed customer data, hashed fields that must stay raw, and millisecond timestamps. It runs entirely in your browser, so nothing you paste is sent anywhere.
Rules checked against Meta's Conversions API parameter documentation on 28 September 2026. Meta can change them; the source is linked on every rule below.
What it checks
Meta doesn't always tell you when an event is wrong. Some mistakes return an error. Others are accepted but never matched to a customer, so the conversion quietly goes missing from your reports. The validator flags both.
Fails: Meta requires these
| Check | What Meta says | Source |
|---|---|---|
event_name, event_time, action_source and user_data are present | All four are required on every event | Server event |
event_time is in seconds, not milliseconds | Unix time in seconds. Date.now() in JavaScript returns milliseconds, which is the most common cause | Server event |
event_time is no more than 7 days old | If any event in a request is older than 7 days, Meta returns an error for the whole request and processes none of its events | Server event |
Website events include event_source_url | Required when action_source is website | Server event |
Website events include user_data.client_user_agent | Required when action_source is website | Customer information |
em, ph, fn, ln, ct, st, zp and country are SHA-256 hashed | Meta requires hashing for each of these | Customer information |
client_ip_address, client_user_agent, fbc and fbp are not hashed | Meta says not to hash these | Customer information |
Purchase events include value and currency | Both are required for purchase events | Custom data |
Warnings: Meta recommends these, or they point to a bug
| Check | Why | Source |
|---|---|---|
event_id is present | Meta marks it optional but recommends it for deduplicating browser Pixel and server events. Send the same event_id from both | Server event |
At least one customer information parameter, such as em or ph | Meta says you must provide at least one, correctly formatted | Customer information |
external_id is hashed | Meta recommends hashing it; it isn't required | Customer information |
fbc and fbp look like fb.1.<timestamp>.<value> | Anything else usually means the cookie was read or rebuilt wrongly | Customer information |
event_time isn't in the future | Meta's docs set no rule, but a future time usually means a timezone or milliseconds bug | Server event |
Format and hash customer data the way Meta asks
- Normalised value
- SHA-256
A hash of a badly formatted value is still a valid-looking hash, so the validator can't tell it's wrong. Format first, then hash. Meta's rules:
| Field | Format before hashing |
|---|---|
em email | Trim spaces, lowercase |
ph phone | Digits only, no leading zeros, with country code |
fn, ln names | Lowercase, no punctuation |
ct city | Lowercase, no punctuation, special characters or spaces |
st state | Lowercase; US states as the 2-letter code |
zp zip or postcode | Lowercase, no spaces or dashes; first 5 digits for US zips |
country | Lowercase ISO 3166-1 alpha-2 code, such as gb or us |
The UK phone trap. A number written +44 (0)7700 900123 becomes 4407700900123 if you only strip symbols and leading zeros. The zero after the country code is a national prefix, not part of the international number, so the correct value is 447700900123. Remove it before hashing.
The mistakes it catches most often
- Milliseconds instead of seconds.
Math.floor(Date.now() / 1000)in JavaScript, notDate.now(). - Hashing everything. IP address, user agent,
fbcandfbpmust be sent as they are. A hashed IP can't be matched. - Hashing nothing. An email sent in plain text isn't matched, and Meta doesn't always say so.
- Website events without the page URL or user agent. Server-side setups often drop them because the server doesn't see the browser. Capture both in the browser and pass them to the server with the order.
- Retrying old events. One event older than 7 days in a batch makes Meta reject the whole batch.
Run it in your terminal or CI
The same checks are in the open-source shopify-capi-validator package. It exits with code 1 when any check fails, so it can stop a bad deploy:
npx shopify-capi-validator --payload ./event.json Sending events from Shopify
- CAPI Shield sends Shopify orders to Meta server-side, with these fields set.
- The Meta EMQ score estimator shows which customer parameters you send and what that means for match quality.
- The server-side tracking setup guide covers the whole flow.
Some links below are affiliate links (marked sponsored). They fund the free
guides and never change a recommendation: our default pick on this page is a free tier.
How we test & disclose →
The CAPI Shield blueprint is also in the Complete Kit.
Frequently asked questions
Does Meta tell you when a Conversions API event is wrong?
Not always. Missing required fields and events older than 7 days return an error. An unhashed email or a hashed IP address can be accepted and simply not matched, so the conversion goes missing without a warning.
Is event_id required in the Meta Conversions API?
Meta marks event_id as optional but recommends it for deduplication. If you send the same event from the browser Pixel and the server, give both the same event_id so Meta can recognise them as one event.
What format should event_time be in for Meta CAPI?
A Unix timestamp in seconds. JavaScript's Date.now() returns milliseconds, so divide it by 1,000. Events more than 7 days old cause Meta to reject the whole request.
Which Meta CAPI fields must not be hashed?
client_ip_address, client_user_agent, fbc and fbp. Meta says not to hash them. Customer details such as email, phone, name, city, state, zip and country must be hashed with SHA-256.
Is it safe to paste a real event here?
The validator runs in your browser and makes no network requests, so what you paste isn't sent anywhere or stored. You can still replace real customer details with test values if you prefer.