pixellint

Blog · Snap CAPI

Snap CAPI v2 is gone. The v3 path is tr.snapchat.com/v3/{id}/events.

Snap CAPI v2 is gone. Posting the old conversion body to /v2/conversion is how Snap never sees the purchase. The v3 path is tr.snapchat.com/v3/{id}/events, and the envelope is not the v2 field list with a new host.

The live introduction page is Version 3. It still points at the v2 endpoint //tr.snapchat.com/v2/conversion and says Conversions API V2 will be deprecated in early 2025. Use the Migration Guide. Early 2025 is the news. A worker that still POSTs pixel_id, timestamp, event_type, and hashed_email to /v2/conversion is posting into a retired shape.

v3 wants a data array. Each event needs event_name in SCREAMING_SNAKE, event_time as Unix seconds or milliseconds, action_source WEB, OFFLINE, or MOBILE_APP, and event_source_url when the event is a website event. hashed_email is em inside user_data. page_url is not the field. Purchase is not the event_name. That paste is the miss.

The path carries the id now

v2 put pixel_id in the JSON body and posted to /v2/conversion. v3 puts the Pixel ID or Snap App ID in the path. Web: POST https://tr.snapchat.com/v3/{PIXEL_ID}/events?access_token={TOKEN}. App: the same host with {SNAP_APP_ID} instead of the pixel. The access token is a query parameter. Mixing a Graph-style Authorization header with a v2 body is a different miss from mixing field names.

The migration guide is blunt: the request structure and parameters are different for v3. Send all event data in the body as JSON. The root is a data array of one or more events. Server parameters including event_name sit at the root of each event. user_data holds em, ph, sc_click_id, sc_cookie1. custom_data holds currency, value, contents, order_id. app_data holds extinfo for app events.

Validate before you cut production. Web validate is POST https://tr.snapchat.com/v3/{pixel_id}/events/validate. App validate swaps in snap_app_id. A VALID status on validate is schema. It is not Events Manager attribution. The live events path is the one that trains, the same way Meta test_event_code is not production.

event_name is PURCHASE, not Purchase

The Parameters page lists event_name as required. The enum is SCREAMING_SNAKE: PURCHASE, SAVE, START_CHECKOUT, ADD_CART, VIEW_CONTENT, ADD_BILLING, SIGN_UP, SEARCH, PAGE_VIEW, SUBSCRIBE, AD_CLICK, AD_VIEW, and the rest of that table, plus CUSTOM_EVENT_1 through CUSTOM_EVENT_5. Meta PascalCase Purchase is not in the list. A shared enum named Purchase will be a custom miss or an invalid event depending on how strictly the gate reads the string.

action_source is WEB, OFFLINE, or MOBILE_APP. Meta uses website. Pinterest uses web. Snap uses WEB. Copying the Meta spelling is a silent miss on a vendor that enumerates WEB. event_source_url is required when website events are shared via Conversions API. It must include a protocol. That is not v2 page_url and it is not Meta event_source_url copied onto a v2 body.

If event_name is PURCHASE, currency and value are also required. They live in custom_data, not as v2 price on the root. value is a numeric value associated with the event. currency is a subset of ISO 4217 codes Snap lists on the Parameters page. Sending price: "43" on the root is the v2 example in the migration guide. It is not a v3 purchase.

Two clocks, two windows, one field

event_time is an integer Epoch timestamp. Snap says it can handle second-level or millisecond-level granularity and encourages milliseconds. Date.now() is already milliseconds. Math.floor(Date.now() / 1000) is the Meta helper. Both can be legal on Snap. A string timestamp like the v2 example "1642815764" is the old type.

The Parameters page says event_time cannot be more than 7 days in the past for web and app events. The introduction page still says events can have a date of maximum 37 days back to be eligible. The older v2 conversion reference said timestamp cannot be more than 37 days in the past. Do not invent which gate fires in production. Send a recent event_time. Do not backfill a month of v2 leftovers onto v3 and assume the 37-day sentence still applies.

Dedup is event_id plus timestamp within a 48 hour window. Send event_id on CAPI and on the Pixel. For Snap Pixel non-purchase events, event_id maps to client_dedup_id. For purchase events it can map to transaction_id. UsingTheAPI says always ensure timestamps are accurate. A v3 event with a new event_id and an old v2 timestamp is a different event from the pixel fire you think you are pairing.

The body people will send first

A Snap CAPI v2 conversion body from the migration guide. This is not a v3 event.

{
  "pixel_id": "67d34640-b7a4-42a8-b821-6434d70f08a4",
  "timestamp": "1642815764",
  "event_conversion_type": "WEB",
  "event_type": "PURCHASE",
  "page_url": "https://www.example.com",
  "hashed_email": "8c2a47d3bdb8d3096a6479f53eac3b724291db5f1c31611100f675be5537329d",
  "transaction_id": 123123123123,
  "price": "43"
}

That object is the v2 request example Snap still publishes so you can see what changed. Posted to /v2/conversion after deprecation it is how Snap never sees the purchase. Posted to /v3/{id}/events it is the wrong array name, the wrong event key, the wrong clock key, the wrong URL key, and a pixel_id that now belongs in the path.

The v3 shape is data[] of events with event_name PURCHASE, event_time as an integer, action_source WEB, event_source_url, event_id, user_data.em, and custom_data.currency plus custom_data.value. The migration guide's v3 example shows that event object. UsingTheAPI wraps it in data. Send the wrapper.

Names that do not translate

This is for Version 3 of Snap's Conversions API. Note: Conversions API V2 will be deprecated in early 2025. Use our Migration Guide to avoid any disruptions.

Snap Conversions API introduction

What to do

Stop posting to /v2/conversion. Put the Pixel ID in the v3 path. Wrap events in data[]. Map your internal purchase to event_name PURCHASE. Convert the clock at the edge: integer Unix time, milliseconds preferred. Persist event_id as a different column from Meta event_id. Capture ScCid on the landing hit and copy it through checkout.

If you run the Pixel, send sc_cookie1 and reuse client_dedup_id or transaction_id as event_id. Validate on /events/validate, then strip the validate path in production. Lint the body you actually POST. The Snap pack is vendor/snapchat. A Meta CAPI fixture cannot serve it.

The contract page for the field list is Snap's Parameters page. This post is the market fact: v2 is the retired hop, and v3 is a different envelope. Pixellint is not affiliated with Snap. Passing a linter means the artifact matches the published v3 envelope. It does not mean Events Manager attributed the order.

Checklist

Sources

Contract pages

The dated argument is above. These pages are the field lists.

Open the Snapchat pack Docs