Criteo Events API
Server-side event delivery to Criteo's Events API (S2S v0) for reliable retargeting, bypassing browser limitations and providing consistent user matching for ad optimization.
Criteo Events API is a server destination in the walkerOS flow:
Sends events server-side to Criteo using raw HTTP (no SDK). Authentication is in-payload (`account` = Partner ID, `id.mapping_key` = Caller ID). Emails are hashed into MD5, SHA-256, and SHA-256(MD5) before sending.
Installation
npm install @walkeros/server-destination-criteo- Integrated
- Bundled
import { startFlow } from '@walkeros/collector';
import { destinationCriteo } from '@walkeros/server-destination-criteo';
await startFlow({
destinations: {
criteo: {
code: destinationCriteo,
config: {
settings: {
partnerId: 'YOUR_PARTNER_ID',
callerId: 'YOUR_CALLER_ID',
},
},
},
},
});Add to your flow.json destinations:
"destinations": {
"criteo": {
"package": "@walkeros/server-destination-criteo",
"import": "destinationCriteo",
"config": {
"settings": {
"partnerId": "YOUR_PARTNER_ID",
"callerId": "YOUR_CALLER_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 |
|---|---|---|---|
partnerId | string | Criteo Partner ID (numeric string, provided by Criteo) | |
callerId | string | Caller ID for user mapping (provided by Criteo) | |
siteType | 'd' | 'm' | 't' | Site type: d (desktop), m (mobile web), t (tablet) | |
country | string | ISO 3166-1 alpha-2 country code | |
language | string | 2-letter language code | |
url | string | Custom Events API endpoint (default https://widget.criteo.com/m/event?version=s2s_v0) | |
user_data | Record<string, string> | Mapping for identity fields | |
ip | any | boolean | Client IP, sent as ip. Resolves against { ingest, event }. Default: ["ingest.ip", "event.user.ip"]. false switches it off. A mapped user_data.ip wins. | |
userAgent | any | boolean | Client user agent, sent as useragent. Resolves against { ingest, event }. Default: ["ingest.userAgent", "event.user.userAgent"]. false switches it off. A mapped user_data.useragent 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 becomes a Criteo addToCart event with the item id, price, and quantity.
{
"name": "product add",
"data": {
"id": "SKU-B2",
"name": "Running Shoes",
"price": 89.99
},
"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": "8c4696e0bb056dea",
"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": "addToCart",
"data": {
"map": {
"item": {
"loop": [
"nested",
{
"condition": {
"$code": "e=>_(e)&&\"product\"===e.entity"
},
"map": {
"id": "data.id",
"price": "data.price",
"quantity": {
"key": "data.quantity",
"value": 1
}
}
}
]
}
}
}
}sendServer("https://widget.criteo.com/m/event?version=s2s_v0", "{\"version\":\"walkeros_criteo_1.0.0\",\"site_type\":\"d\",\"account\":\"PARTNER_ID\",\"id\":{\"mapping_key\":\"CALLER_ID\"},\"events\":[{\"event\":\"addToCart\",\"timestamp\":\"2023-11-14T22:28:21.000Z\",\"item\":[{\"id\":\"SKU-B2\",\"price\":89.99,\"quantity\":1}]}],\"full_url\":\"https://shop.example.com/products/running-shoes\"}")Page view
A page view becomes a Criteo viewHome event used for home page impression tracking.
{
"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": "c29aaabd58161bcf",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000903000,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "browser",
"platform": "web",
"url": "https://example.com/"
}
}{
"name": "viewHome"
}sendServer("https://widget.criteo.com/m/event?version=s2s_v0", "{\"version\":\"walkeros_criteo_1.0.0\",\"site_type\":\"d\",\"account\":\"PARTNER_ID\",\"id\":{\"mapping_key\":\"CALLER_ID\"},\"events\":[{\"event\":\"viewHome\",\"timestamp\":\"2023-11-14T22:28:23.000Z\"}],\"full_url\":\"https://example.com/\"}")Purchase
A completed order is posted to the Criteo Events API as a trackTransaction event with items.
{
"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": "57a96b378b918493",
"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",
"referrer": "https://shop.example.com/cart"
}
}{
"name": "trackTransaction",
"data": {
"map": {
"id": "data.id",
"item": {
"loop": [
"nested",
{
"condition": {
"$code": "e=>_(e)&&\"product\"===e.entity"
},
"map": {
"id": "data.id",
"price": "data.price",
"quantity": {
"key": "data.quantity",
"value": 1
}
}
}
]
}
}
}
}sendServer("https://widget.criteo.com/m/event?version=s2s_v0", "{\"version\":\"walkeros_criteo_1.0.0\",\"site_type\":\"d\",\"account\":\"PARTNER_ID\",\"id\":{\"mapping_key\":\"CALLER_ID\"},\"events\":[{\"event\":\"trackTransaction\",\"timestamp\":\"2023-11-14T22:28:20.000Z\",\"id\":\"ORD-300\",\"item\":[{\"id\":\"SKU-A1\",\"price\":124.99,\"quantity\":2}]}],\"full_url\":\"https://shop.example.com/checkout/complete\",\"previous_url\":\"https://shop.example.com/cart\"}")View item
A product view becomes a Criteo viewItem event with the viewed product id.
{
"name": "product view",
"data": {
"id": "SKU-C3",
"name": "Coffee Maker"
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "SKU-C3"
}
}
],
"consent": {
"functional": true
},
"id": "d130489d643f9c0a",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000902000,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "browser",
"platform": "web",
"url": "https://shop.example.com/products/coffee-maker"
}
}{
"name": "viewItem",
"data": {
"map": {
"item": {
"loop": [
"nested",
{
"condition": {
"$code": "e=>_(e)&&\"product\"===e.entity"
},
"map": {
"id": "data.id"
}
}
]
}
}
}
}sendServer("https://widget.criteo.com/m/event?version=s2s_v0", "{\"version\":\"walkeros_criteo_1.0.0\",\"site_type\":\"d\",\"account\":\"PARTNER_ID\",\"id\":{\"mapping_key\":\"CALLER_ID\"},\"events\":[{\"event\":\"viewItem\",\"timestamp\":\"2023-11-14T22:28:22.000Z\",\"item\":[{\"id\":\"SKU-C3\"}]}],\"full_url\":\"https://shop.example.com/products/coffee-maker\"}")Client IP and user agent
The destination sends the client IP as ip and the user agent as useragent 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.ip or user_data.useragent 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
Criteo uses its own standard event names. Set the Criteo event name via each rule's name field.
| walkerOS Event | Criteo Event Name |
|---|---|
page view | viewHome / viewPage |
product view | viewItem |
product list | viewList |
product add | addToCart |
cart view | viewBasket |
checkout start | beginCheckout |
checkout payment | addPaymentInfo |
order complete | trackTransaction |
user login | login |
"mapping": {
"order": {
"complete": {
"name": "trackTransaction",
"data": {
"map": {
"id": "data.id",
"item": {
"loop": [
"nested",
{
"map": {
"id": "data.id",
"price": "data.price",
"quantity": "data.quantity"
}
}
]
}
}
}
}
}
}User identity
Criteo matches users via three signals. Wire them through user_data in settings:
| Field | Description |
|---|---|
mapped_user_id | Criteo GUM ID |
email | Raw email. Hashed into MD5, SHA-256 and SHA-256(MD5) |
retailer_visitor_id | Stable retailer visitor identifier |
"settings": {
"partnerId": "YOUR_PARTNER_ID",
"callerId": "YOUR_CALLER_ID",
"user_data": {
"mapped_user_id": "user.id",
"email": "user.email",
"retailer_visitor_id": "user.device"
}
}Email hashing
Raw emails are lowercased and trimmed, then hashed into all three formats Criteo expects:
md5: MD5 hex digestsha256: SHA-256 hex digestsha256_md5: SHA-256 hex of the MD5 hex string
Pre-hashed values (detected by hex length: 32 chars for MD5, 64 for SHA-256) are passed through without re-hashing.
Deduplication
Criteo Events API supports deduplication with Criteo OneTag by sharing a deduplication_page_view_id across channels. Wire it via data.map.deduplication_page_view_id in the event mapping.