Snapchat Conversions API
Server-side event delivery to Snapchat's Conversions API v3 for enhanced conversion tracking, bypassing browser limitations and improving match quality for ad optimization.
Snapchat Conversions API is a server destination in the walkerOS flow:
Sends events server-side to Snapchat's Conversions API using raw HTTP (no SDK). Identity fields (`em`, `ph`, `fn`, `ln`, `db`, `ge`, `ct`, `st`, `zp`, `country`, `external_id`) are SHA-256 hashed before sending. Events include a stable `event_id` for deduplication with the Snap Pixel.
Installation
npm install @walkeros/server-destination-snapchat- Integrated
- Bundled
import { startFlow } from '@walkeros/collector';
import { destinationSnapchat } from '@walkeros/server-destination-snapchat';
await startFlow({
destinations: {
snapchat: {
code: destinationSnapchat,
config: {
settings: {
accessToken: 'YOUR_ACCESS_TOKEN',
pixelId: 'YOUR_PIXEL_ID',
},
},
},
},
});Add to your flow.json destinations:
"destinations": {
"snapchat": {
"package": "@walkeros/server-destination-snapchat",
"import": "destinationSnapchat",
"config": {
"settings": {
"accessToken": "YOUR_ACCESS_TOKEN",
"pixelId": "YOUR_PIXEL_ID"
}
}
}
}Configuration
This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see destination configuration. Package-specific fields live under config.settings and are listed below.
Settings
| Property | Type | Description | More |
|---|---|---|---|
accessToken | string | Long-lived Conversions API access token from Snapchat Ads Manager | |
pixelId | string | Snap Pixel ID | |
url | string | Custom Conversions API base URL (default https://tr.snapchat.com/v3/) | |
action_source | Event action source (default WEB) | ||
doNotHash | Array<string> | User data fields to skip hashing | |
user_data | Record<string, string> | Mapping for user data fields | |
testMode | boolean | When true, sends events to /events/validate instead of /events for testing | |
ip | any | boolean | Client IP, sent as user_data.client_ip_address. Resolves against { ingest, event }. Default: ["ingest.ip", "event.user.ip"]. false switches it off. A mapped user_data.client_ip_address wins. | |
userAgent | any | boolean | Client user agent, sent as user_data.client_user_agent. Resolves against { ingest, event }. Default: ["ingest.userAgent", "event.user.userAgent"]. false switches it off. A mapped user_data.client_user_agent wins. |
Mapping
This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.
Examples
Add to cart
A product add is sent to Snapchat as an ADD_CART conversion with value and product details.
{
"name": "product add",
"data": {
"id": "SKU-B2",
"name": "Running Shoes",
"price": 89.99,
"color": "blue"
},
"context": {
"shopping": [
"intent",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "SKU-B2",
"name": "Running Shoes",
"price": 89.99,
"quantity": 1
}
}
],
"consent": {
"functional": true
},
"id": "e1f2a3b4c5d60002",
"trigger": "click",
"entity": "product",
"action": "add",
"timestamp": 1700000901000,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "browser",
"platform": "web",
"url": "https://shop.example.com/products/running-shoes"
}
}{
"name": "ADD_CART",
"data": {
"map": {
"custom_data": {
"map": {
"value": "data.price",
"currency": {
"value": "EUR"
},
"contents": {
"loop": [
"nested",
{
"condition": {
"$code": "e=>g(e)&&\"product\"===e.entity"
},
"map": {
"id": "data.id",
"item_price": "data.price",
"quantity": {
"key": "data.quantity",
"value": 1
}
}
}
]
}
}
}
}
}
}sendServer("https://tr.snapchat.com/v3/p1x3l1d/events?access_token=s3cr3t", "{\"data\":[{\"event_name\":\"ADD_CART\",\"event_time\":1700000901,\"action_source\":\"WEB\",\"event_id\":\"e1f2a3b4c5d60002\",\"user_data\":{},\"custom_data\":{\"value\":89.99,\"currency\":\"EUR\",\"contents\":[{\"id\":\"SKU-B2\",\"item_price\":89.99,\"quantity\":1}]},\"event_source_url\":\"https://shop.example.com/products/running-shoes\"}]}")Sign up
A newsletter form submission is sent to Snapchat as a SIGN_UP conversion with a hashed email.
{
"name": "form submit",
"data": {
"type": "newsletter"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"email": "user@example.com"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "e1f2a3b4c5d60004",
"trigger": "test",
"entity": "form",
"action": "submit",
"timestamp": 1700000903000,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "browser",
"platform": "web",
"url": "https://example.com/contact"
}
}{
"name": "SIGN_UP",
"data": {
"map": {
"user_data": {
"map": {
"em": "user.email"
}
},
"custom_data": {
"map": {
"sign_up_method": {
"value": "newsletter"
}
}
}
}
}
}sendServer("https://tr.snapchat.com/v3/p1x3l1d/events?access_token=s3cr3t", "{\"data\":[{\"event_name\":\"SIGN_UP\",\"event_time\":1700000903,\"action_source\":\"WEB\",\"event_id\":\"e1f2a3b4c5d60004\",\"user_data\":{\"em\":\"b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514\"},\"custom_data\":{\"sign_up_method\":\"newsletter\"},\"event_source_url\":\"https://example.com/contact\"}]}")Page view
A page view is forwarded to Snapchat with the event source URL and no extra custom data.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "e1f2a3b4c5d60003",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000902000,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "browser",
"platform": "web",
"url": "https://example.com/docs/"
}
}sendServer("https://tr.snapchat.com/v3/p1x3l1d/events?access_token=s3cr3t", "{\"data\":[{\"event_name\":\"page view\",\"event_time\":1700000902,\"action_source\":\"WEB\",\"event_id\":\"e1f2a3b4c5d60003\",\"user_data\":{},\"custom_data\":{},\"event_source_url\":\"https://example.com/docs/\"}]}")Purchase
A completed order is sent to the Snapchat Conversions API as a PURCHASE with value, currency, and contents.
{
"name": "order complete",
"data": {
"id": "ORD-300",
"total": 249.99,
"currency": "EUR"
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "user-123",
"device": "device-456"
},
"nested": [
{
"entity": "product",
"data": {
"id": "SKU-A1",
"name": "Widget Pro",
"price": 124.99,
"quantity": 2
}
}
],
"consent": {
"functional": true
},
"id": "e1f2a3b4c5d60001",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000900000,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "browser",
"platform": "web",
"url": "https://shop.example.com/checkout/complete"
}
}{
"name": "PURCHASE",
"data": {
"map": {
"custom_data": {
"map": {
"value": "data.total",
"currency": {
"key": "data.currency",
"value": "EUR"
},
"transaction_id": "data.id",
"contents": {
"loop": [
"nested",
{
"condition": {
"$code": "e=>g(e)&&\"product\"===e.entity"
},
"map": {
"id": "data.id",
"item_price": "data.price",
"quantity": {
"key": "data.quantity",
"value": 1
}
}
}
]
}
}
},
"user_data": {
"map": {
"external_id": "user.id"
}
}
}
}
}sendServer("https://tr.snapchat.com/v3/p1x3l1d/events?access_token=s3cr3t", "{\"data\":[{\"event_name\":\"PURCHASE\",\"event_time\":1700000900,\"action_source\":\"WEB\",\"event_id\":\"e1f2a3b4c5d60001\",\"user_data\":{\"external_id\":\"fcdec6df4d44dbc637c7c5b58efface52a7f8a88535423430255be0bb89bedd8\"},\"custom_data\":{\"value\":249.99,\"currency\":\"EUR\",\"transaction_id\":\"ORD-300\",\"contents\":[{\"id\":\"SKU-A1\",\"item_price\":124.99,\"quantity\":2}]},\"event_source_url\":\"https://shop.example.com/checkout/complete\"}]}")Client IP and user agent
The destination sends the client IP as user_data.client_ip_address and the user agent as user_data.client_user_agent by default. The ip and userAgent settings resolve against { ingest, event } and default to ["ingest.ip", "event.user.ip"] and ["ingest.userAgent", "event.user.userAgent"], so they fill in whenever the source provides them (see the config.ingest recipe on the Express source). A value your mapping sets for user_data.client_ip_address or user_data.client_user_agent wins. A value that resolves to nothing is not sent. Set either setting to false to turn it off, or to another mapping value to read it elsewhere.
Event mapping
Map walkerOS events to Snapchat standard event names via each rule's name field. Snapchat uses UPPERCASE standard event names (e.g. PURCHASE, not Purchase).
"mapping": {
"order": {
"complete": {
"name": "PURCHASE",
"data": {
"map": {
"custom_data": {
"map": {
"value": "data.total",
"currency": "data.currency",
"transaction_id": "data.id"
}
}
}
}
}
}
}custom_data structure
Unlike Meta's CAPI (which places properties flat on the event root), Snapchat requires event properties to be nested under custom_data. Always map into custom_data.map.
Hashing
The destination automatically SHA-256 hashes the 11 standard identity fields before sending: em, ph, fn, ln, db, ge, ct, st, zp, country, external_id. Pass raw values and hashing is handled for you.
Non-hashable fields pass through as-is: sc_cookie1, client_ip_address, client_user_agent, sc_click_id, idfv, madid.
If a value is already hashed or you want to skip hashing for a specific field, use doNotHash:
"settings": {
"accessToken": "YOUR_ACCESS_TOKEN",
"pixelId": "YOUR_PIXEL_ID",
"doNotHash": ["em"]
}Deduplication
Each event is sent with event_id set to the walkerOS event id. If you also run the Snap Pixel in the browser, Snapchat deduplicates server and browser events that share the same event_id and event_name within a 48h window, so conversions are not double-counted.
Test mode
Set testMode: true to send events to Snapchat's /events/validate endpoint for validation instead of the live /events endpoint. Useful during development. Events validated via this endpoint do not count toward ads delivery or optimization.
"settings": {
"accessToken": "YOUR_ACCESS_TOKEN",
"pixelId": "YOUR_PIXEL_ID",
"testMode": true
}