pixellint

vendor/snapchat · vendor documented

Snap CAPI writes WEB where Meta writes website

Snap CAPI and Meta CAPI post the same envelope, down to the field names. A bare payload carries no host, so the packs tell each other apart by action_source. A payload whose action_source is missing or misspelled matches both, and both report it.

Hashed identifiers, unhashed IP and user agent, and event_source_url required when action_source is WEB: same shape of contract as Meta CAPI, different enum. Snap Conversion API is not a Meta CAPI body on a Snap host.

What this pack matches

Hosts
tr.snapchat.com
Paths
…/events…
Vendor docs
developers.snap.com/api/marketing-api/Conversions-API/UsingTheAPI

Rules

Codes are stable. A finding in CI, MCP, or the playground lands on the same id.

Field Required What it checks Rule ids Source
access_token required The events endpoint authenticates with an access token on the request. Fix: Send the Conversions API access token, and keep it out of anything client-side. vendor.snapchat.param.access_token.missing
vendor.snapchat.param.access_token.empty
docs
event_name required Snap documents a fixed set of event types, spelled in upper case with underscores. Fix: Use one of the documented event types, such as `PAGE_VIEW` or `PURCHASE`. vendor.snapchat.body.event_name.missing
vendor.snapchat.body.event_name.empty
vendor.snapchat.body.event_name.invalid
docs
event_time required It is the epoch timestamp of the conversion, and Snap only accepts events from the last 7 days. Fix: Send the epoch timestamp of the conversion, not of the moment you forwarded it. vendor.snapchat.body.event_time.missing
vendor.snapchat.body.event_time.empty
vendor.snapchat.body.event_time.invalid
docs
action_source required It says where the event took place, and Snap accepts three values. Fix: Use `WEB`, `OFFLINE`, or `MOBILE_APP`. Snap spells these in upper case, unlike Meta. vendor.snapchat.body.action_source.missing
vendor.snapchat.body.action_source.empty
vendor.snapchat.body.action_source.invalid
docs
event_source_url optional It is the URL of the page the event happened on, and Snap requires it for web events. Fix: Send the full page URL, including the scheme. vendor.snapchat.body.event_source_url.empty
vendor.snapchat.body.event_source_url.invalid
docs
event_id optional It is an advertiser-chosen identifier for deduplication against the Pixel. Snap documents it as recommended for unique events. An empty pair cannot collapse a web and CAPI pair. Fix: Send the same `event_id` the Pixel used as `client_dedup_id`, or drop the empty pair. vendor.snapchat.body.event_id.empty docs
user_data required Snap matches the conversion on customer information, and the event needs at least one identifier. Fix: Add a `user_data` object carrying a hashed email, hashed phone, mobile ad id, or IP and user agent pair. vendor.snapchat.body.user_data.missing docs
user_data.em optional Email must be normalized and SHA-256 hashed before it is sent. Fix: Trim and lowercase the address, hash it with SHA-256, and send the hex digest. vendor.snapchat.body.user_data.em.empty
vendor.snapchat.body.user_data.em.invalid
docs
user_data.em[] optional Every email in the list must be normalized and SHA-256 hashed. vendor.snapchat.body.user_data.em[].empty
vendor.snapchat.body.user_data.em[].invalid
docs
user_data.ph optional Phone must be normalized and SHA-256 hashed before it is sent. vendor.snapchat.body.user_data.ph.empty
vendor.snapchat.body.user_data.ph.invalid
docs
user_data.ph[] optional Every phone number in the list must be normalized and SHA-256 hashed. vendor.snapchat.body.user_data.ph[].empty
vendor.snapchat.body.user_data.ph[].invalid
docs
user_data.fn optional First name must be SHA-256 hashed. vendor.snapchat.body.user_data.fn.empty
vendor.snapchat.body.user_data.fn.invalid
docs
user_data.ln optional Last name must be SHA-256 hashed. vendor.snapchat.body.user_data.ln.empty
vendor.snapchat.body.user_data.ln.invalid
docs
user_data.ge optional Gender must be SHA-256 hashed. vendor.snapchat.body.user_data.ge.empty
vendor.snapchat.body.user_data.ge.invalid
docs
user_data.ct optional City must be SHA-256 hashed. vendor.snapchat.body.user_data.ct.empty
vendor.snapchat.body.user_data.ct.invalid
docs
user_data.st optional State must be SHA-256 hashed. vendor.snapchat.body.user_data.st.empty
vendor.snapchat.body.user_data.st.invalid
docs
user_data.zp optional Postal code must be SHA-256 hashed. vendor.snapchat.body.user_data.zp.empty
vendor.snapchat.body.user_data.zp.invalid
docs
user_data.country optional Country must be SHA-256 hashed. vendor.snapchat.body.user_data.country.empty
vendor.snapchat.body.user_data.country.invalid
docs
user_data.client_ip_address optional It is sent unhashed, and it must be the address of the browser rather than of your server. vendor.snapchat.body.user_data.client_ip_address.empty docs
user_data.client_user_agent optional It is sent unhashed, and it must be the browser's user agent rather than your HTTP client's. vendor.snapchat.body.user_data.client_user_agent.empty docs
user_data.sc_click_id optional It is the Snap click ID from the landing-page `ScCid` query. Snap documents it as unhashed. Fix: Copy `ScCid` from the landing URL into `user_data.sc_click_id`, or drop the empty pair. vendor.snapchat.body.user_data.sc_click_id.empty docs
user_data.sc_cookie1 optional It is the first-party `_scid` cookie. Snap documents it as unhashed and recommended for match rate. Fix: Read `_scid` under your domain into `user_data.sc_cookie1`, or drop the empty pair. vendor.snapchat.body.user_data.sc_cookie1.empty docs
user_data.madid optional It is the mobile advertiser ID. Snap documents it as lowercase and unhashed. Fix: Send the IDFA or GAID in lowercase, unhashed, or drop the empty pair. vendor.snapchat.body.user_data.madid.empty docs
user_data.idfv optional It is the plain-text IDFV. Snap documents it as unhashed and recommended for app events. Fix: Send the IDFV unhashed, or drop the empty pair. vendor.snapchat.body.user_data.idfv.empty docs
custom_data.value optional It is the monetary value of the event. Snap documents a float, required for PURCHASE, with no currency symbol. Fix: Send the purchase total in `custom_data.value` as a number, such as `10`. vendor.snapchat.body.custom_data.value.empty
vendor.snapchat.body.custom_data.value.invalid
docs
custom_data.currency optional It is the currency of `custom_data.value`. Snap documents a subset of ISO 4217, not every three-letter code. Fix: Send a documented code such as `USD`. vendor.snapchat.body.custom_data.currency.empty
vendor.snapchat.body.custom_data.currency.invalid
docs
custom_data.order_id optional It is the order identifier. Snap documents it on the Dynamic Ads custom_data table. Fix: Send the order id in `custom_data.order_id`, or drop the empty pair. vendor.snapchat.body.custom_data.order_id.empty docs
custom_data.content_type optional It says what `content_ids` or `contents` represent. Snap documents `product` for a single item or `product_group` for a variant group. Fix: Set `custom_data.content_type` to `product` or `product_group`. vendor.snapchat.body.custom_data.content_type.empty
vendor.snapchat.body.custom_data.content_type.invalid
docs
custom_data.content_ids optional It is a product or category identifier. Snap documents a single id, an array, or a comma-separated list. Fix: Send a catalog id in `custom_data.content_ids`, or drop the empty pair. vendor.snapchat.body.custom_data.content_ids.empty docs
custom_data.content_ids[] optional Every id in the list is a product or category identifier. Fix: Send catalog ids in `custom_data.content_ids`, or drop empty entries. vendor.snapchat.body.custom_data.content_ids[].empty docs
custom_data.num_items optional It is the total number of items. Snap documents it as a string. Fix: Send a whole number in `custom_data.num_items`, such as `2`. vendor.snapchat.body.custom_data.num_items.empty
vendor.snapchat.body.custom_data.num_items.invalid
docs
custom_data.contents[].id optional It is the item id on a contents row. Snap documents `id` on each contents object. Fix: Set `custom_data.contents[].id` to the catalog item ID, or drop the empty pair. vendor.snapchat.body.custom_data.contents[].id.empty docs
custom_data.contents[].quantity optional It is the item count on a contents row. Snap's published example sends it as a number string. Fix: Send `custom_data.contents[].quantity` as a number, such as `1`. vendor.snapchat.body.custom_data.contents[].quantity.empty
vendor.snapchat.body.custom_data.contents[].quantity.invalid
docs
custom_data.contents[].item_price optional It is the unit price of one item. Snap's published example sends `item_price` as a number string. Fix: Send `custom_data.contents[].item_price` as a number, such as `5`. Put the order total in `custom_data.value`. vendor.snapchat.body.custom_data.contents[].item_price.empty
vendor.snapchat.body.custom_data.contents[].item_price.invalid
docs
custom_data.content_name optional It is the name of the page or product associated with the event. Snap documents it on the Dynamic Ads custom_data table. Fix: Send the page or product name in `custom_data.content_name`, or drop the empty pair. vendor.snapchat.body.custom_data.content_name.empty docs
custom_data.content_category optional It is an item or category. Snap documents a single category or an array. Fix: Send a category in `custom_data.content_category`, or drop the empty pair. vendor.snapchat.body.custom_data.content_category.empty docs
custom_data.content_category[] optional Every entry in the list is an item or category. Fix: Send categories in `custom_data.content_category`, or drop empty entries. vendor.snapchat.body.custom_data.content_category[].empty docs
custom_data.search_string optional It is the text that was searched for. Snap documents it on the Dynamic Ads custom_data table. Fix: Send the query in `custom_data.search_string`, or drop the empty pair. vendor.snapchat.body.custom_data.search_string.empty docs
custom_data.predicted_ltv optional It is the predicted lifetime value of the conversion. Snap documents a float. Fix: Send `custom_data.predicted_ltv` as a number, such as `120.5`. vendor.snapchat.body.custom_data.predicted_ltv.empty
vendor.snapchat.body.custom_data.predicted_ltv.invalid
docs
custom_data.checkin_date optional It is the hotel check-in date in the hotel's time zone. Snap documents YYYYMMDD, YYYY-MM-DD, YYYY-MM-DDThh:mmTZD, and YYYY-MM-DDThh:mm:ssTZD. Fix: Send a documented check-in date such as `20261015` or `2026-10-15`. vendor.snapchat.body.custom_data.checkin_date.empty
vendor.snapchat.body.custom_data.checkin_date.invalid
docs
custom_data.origin_airport optional It is the origin airport. Snap documents the official IATA code. Fix: Send a three-letter IATA code such as `JFK`. vendor.snapchat.body.custom_data.origin_airport.empty
vendor.snapchat.body.custom_data.origin_airport.invalid
docs
custom_data.destination_airport optional It is the destination airport. Snap documents the IATA code. Fix: Send a three-letter IATA code such as `CDG`. vendor.snapchat.body.custom_data.destination_airport.empty
vendor.snapchat.body.custom_data.destination_airport.invalid
docs
custom_data.num_adults optional It is the number of adults staying. Snap documents an integer on the Dynamic Travel Ads table. Fix: Send a whole number in `custom_data.num_adults`, such as `2`. vendor.snapchat.body.custom_data.num_adults.empty
vendor.snapchat.body.custom_data.num_adults.invalid
docs
custom_data.num_children optional It is the number of children staying. Snap documents an integer on the Dynamic Travel Ads table. Fix: Send a whole number in `custom_data.num_children`, such as `1`. vendor.snapchat.body.custom_data.num_children.empty
vendor.snapchat.body.custom_data.num_children.invalid
docs
custom_data.num_infants optional It is the number of infants staying. Snap documents an integer on the Dynamic Travel Ads table. Fix: Send a whole number in `custom_data.num_infants`, such as `0`. vendor.snapchat.body.custom_data.num_infants.empty
vendor.snapchat.body.custom_data.num_infants.invalid
docs
body.web_requires_source_url required The event is marked `action_source: WEB` but carries no `event_source_url`, which Snap requires for website events. Fix: Send the URL of the page the event took place on. vendor.snapchat.body.web_requires_source_url docs
body.purchase_requires_value_and_currency required A `PURCHASE` event is missing its value or currency. Snap documents `value` as required for PURCHASE, and currency rides with that value. Fix: Send `custom_data.value` and `custom_data.currency` on PURCHASE events. vendor.snapchat.body.purchase_requires_value_and_currency docs
body.value_requires_currency required The event carries `custom_data.value` with no `custom_data.currency`. Snap documents currency as the ISO code that goes with the value. Fix: Add `custom_data.currency` as a three-letter code alongside the value. vendor.snapchat.body.value_requires_currency docs
body.unhashed_email required A field carries what looks like a raw email address. Snap requires customer information to be normalized and SHA-256 hashed. Fix: Trim the address, lowercase it, hash it with SHA-256, and send the hex digest. vendor.snapchat.body.unhashed_email docs
body.hashed_plaintext_field required This field looks like a SHA-256 digest, but Snap documents it as one of the parameters that is sent unhashed. Fix: Send the raw value. Hashing it makes the event unmatchable. vendor.snapchat.body.hashed_plaintext_field docs

Validate a payload

pixellint validate json @payload.json --rulepack vendor/snapchat

Try this failing payload in the playground. Snap WEB event without event_source_url.

{"data":[{"event_name":"PURCHASE","event_time":1770000000,"action_source":"WEB","user_data":{"em":["buyer@example.com"]}}]}

cargo install pixellint · npm install pixellint