Criteo
Send website events to Criteo through Criteo Server-to-Server (S2S) event registration.
Why route Criteo through Datafly Signal
- Conversions survive ad blockers and tracking prevention. Signal sends the event from your own infrastructure, so the conversions Criteo optimises against are not filtered by the browser.
- Identifiers are hashed before they leave your infrastructure. Signal normalises and applies SHA-256 inside your own deployment, so Criteo receives match keys, not raw personal data.
- Click and cookie identifiers are captured first-party and replayed on later conversions, so attribution survives when the landing-page cookie has expired.
- One consent decision governs every destination. Criteo is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.
- Presets for Retail and Travel. The mapping starts from a working configuration for your vertical, and every field can be changed afterwards.
Prerequisites
- Your Criteo partner ID (the
account), from your Criteo representative. - Your Criteo S2S mapping key, and the Criteo GUM ID sync enabled in Signal so events carry the visitor’s
mapped_user_id. Without it, events are identified by hashed email only.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
advertiser_id | string | Yes | The Criteo partner ID of the account the events are sent to, sent as account. Ask your Criteo representative if you do not have it. |
mapping_key | string | No | The Criteo S2S mapping key for your account, sent with the Criteo GUM ID (id.mapping_key). Required for events identified by the GUM ID; events without it are identified by hashed email only. |
client_id | string | No | Not read: the S2S event endpoint takes no API credentials. Retained for existing integrations. |
client_secret | secret | No | Not read: the S2S event endpoint takes no API credentials. Retained for existing integrations. |
api_version | string | No | Not read: the S2S endpoint version is fixed (s2s_v0 / s2s_v1.0.0). Retained for existing integrations. |
Configure in Signal
- In the Management UI, go to Integrations > Integration Library and select Criteo.
- Choose a preset, fill in the fields above and choose the pipelines and consent categories (advertising destinations default to marketing).
- Click Install Integration.
Or with the Management API:
curl -X POST http://localhost:8084/v1/admin/integration-catalog/criteo/install \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Criteo", "variant": "default", "config": {"advertiser_id": "12345"}, "delivery_mode": "server_side"}'API endpoint
POST https://widget.criteo.com/m/event?version=s2s_v0Authentication: none (the account is identified in the body). Allow egress to widget.criteo.com from the network your delivery workers run on.
Presets and event mapping
Every preset sends only the fields it maps (the strict output contract is on). Events not listed are not sent.
Retail (ecommerce)
Full Criteo retail funnel over S2S: viewPage, viewList (category and search, with keywords), viewItem, addToCart, viewBasket, beginCheckout, addPaymentInfo, trackTransaction with order ID and items, and login.
| Signal event | Criteo event |
|---|---|
page | viewPage |
view_item_list | viewList |
view_search_results | viewList |
view_item | viewItem |
add_to_cart | addToCart |
view_cart | viewBasket |
begin_checkout | beginCheckout |
add_payment_info | addPaymentInfo |
purchase | trackTransaction |
login | login |
Travel (travel)
Criteo travel events: viewSearch with check-in/check-out dates and party size, listing and hotel views as viewItem, basket and checkout, and trackTransaction for bookings with items.
| Signal event | Criteo event |
|---|---|
page | viewPage |
search | viewSearch |
hotel_searched | viewSearch |
flight_searched | viewSearch |
view_item_list | viewList |
listing_viewed | viewItem |
hotel_viewed | viewItem |
view_item | viewItem |
add_to_cart | addToCart |
begin_checkout | beginCheckout |
purchase | trackTransaction |
Default (default)
Criteo S2S core retargeting events: viewPage, viewList, viewItem, addToCart, viewBasket and trackTransaction, identified by the Criteo GUM ID (with the S2S mapping key) and the hashed email.
| Signal event | Criteo event |
|---|---|
page | viewPage |
view_item_list | viewList |
view_item | viewItem |
add_to_cart | addToCart |
view_cart | viewBasket |
purchase | trackTransaction |
Identity and hashing
| Criteo field | Signal source | Treatment |
|---|---|---|
id.mapped_user_id + id.mapping_key | Criteo GUM ID (gateway sync) + S2S Mapping Key | sent as captured |
id.email.sha256, alternate_ids[] | $traits.email | trim, lowercase, SHA-256 |
retailer_visitor_id | Signal anonymous ID | sent as captured |
ip, user_agent, full_url | visitor request | sent as captured |
Email, phone and names come from datafly.identify() traits (a legacy properties.email / properties.phone is read when no trait is set). Raw personal data is never sent.
Deduplication and consent
Sales carry the order ID as the event’s id. Criteo attributes on events received within about 15 minutes, so keep delivery near real time. Batching is off: the visitor’s identity sits at the request root.
Example: purchase (Default preset)
datafly.identify('crm-user-7', { email: 'jane.doe@example.com', phone: '07700 900123', first_name: 'Jane', last_name: 'Doe' });
datafly.track('purchase', {
transaction_id: 'T_1001', value: 139.99, currency: 'GBP',
items: [
{ item_id: 'SKU_1', item_name: 'Helmet', item_category: 'Motorbike', item_brand: 'Shoei', price: 120.00, quantity: 2 },
{ item_id: 'SKU_2', item_name: 'Gloves', price: 19.99, quantity: 1 }
]
});Request Signal sends (rendered from the preset):
{
"account": "12345",
"alternate_ids": [
{
"hash_method": "sha256",
"type": "email",
"value": "86e0b9e56c17cc4d12387e1949b85053fbe73bc3ce5a1188713a9d300cc6133d"
}
],
"events": [
{
"currency": "GBP",
"event": "trackTransaction",
"id": "T_1001",
"item": [
{
"id": "SKU_1",
"price": 120,
"quantity": 2
},
{
"id": "SKU_2",
"price": 19.99,
"quantity": 1
}
],
"timestamp": 1758500000
}
],
"full_url": "https://shop.example.co.uk/p/123?utm_source=x",
"id": {
"email": {
"sha256": "86e0b9e56c17cc4d12387e1949b85053fbe73bc3ce5a1188713a9d300cc6133d"
},
"mapped_user_id": "gum1",
"mapping_key": "mk1"
},
"ip": "203.0.113.7",
"retailer_visitor_id": "df_anon_bax",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"version": "s2s_v1.0.0"
}Known limitations
- GDPR consent for the event call (
gra,grs,grvURL parameters) is not sent yet (#1386); Signal’s consent gate applies before delivery. viewListsends every listed product ID; Criteo uses the first three.
Troubleshooting
| Symptom | Cause | Resolution |
|---|---|---|
401 / 403 | Invalid, expired or under-privileged credential | Re-issue the credential described under Prerequisites and update the integration. |
400 | A field the vendor rejects | Open the event in the Delivery Log; the vendor’s message names the field. |
| Event dead-lettered with a required-field error | A value the vendor requires is missing (for example currency and value on a purchase) | Send the property in the track() call, or map it in the integration. |
| Low match rate | Few identifiers | Call datafly.identify() with email and phone when you know them, and keep click-ID capture enabled. |
Vendor reference: https://guides.criteotilt.com/onetag/s2s/.