> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Criteo Events API

[Server](#)[ Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/criteo)[ Package](https://www.npmjs.com/package/@walkeros/server-destination-criteo) Beta

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.

Where this fits

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[​](#installation "Direct link to Installation")

```bash
npm install @walkeros/server-destination-criteo
```

* Integrated
* Bundled

```typescript
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:

```json
"destinations": {
  "criteo": {
    "package": "@walkeros/server-destination-criteo",
    "import": "destinationCriteo",
    "config": {
      "settings": {
        "partnerId": "YOUR_PARTNER_ID",
        "callerId": "YOUR_CALLER_ID"
      }
    }
  }
}
```

[See bundled mode setup](/preview/pr-749/docs/getting-started/modes/bundled.md) | [CLI reference](/preview/pr-749/docs/apps/cli.md)

## Configuration[​](#configuration "Direct link to Configuration")

This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see [destination configuration](/docs/destinations#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to 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. |      |

\* Required fields

## Mapping[​](#mapping "Direct link to Mapping")

This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](/docs/mapping).

## Examples

### Add to cart

A product add becomes a Criteo addToCart event with the item id, price, and quantity.

Event

```json
{
  "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"
  }
}
```

Mapping

```json
{
  "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
              }
            }
          }
        ]
      }
    }
  }
}
```

Out

```javascript
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.

Event

```json
{
  "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/"
  }
}
```

Mapping

```json
{
  "name": "viewHome"
}
```

Out

```javascript
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.

Event

```json
{
  "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"
  }
}
```

Mapping

```json
{
  "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
              }
            }
          }
        ]
      }
    }
  }
}
```

Out

```javascript
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.

Event

```json
{
  "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"
  }
}
```

Mapping

```json
{
  "name": "viewItem",
  "data": {
    "map": {
      "item": {
        "loop": [
          "nested",
          {
            "condition": {
              "$code": "e=>_(e)&&\"product\"===e.entity"
            },
            "map": {
              "id": "data.id"
            }
          }
        ]
      }
    }
  }
}
```

Out

```javascript
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[​](#client-ip-and-user-agent "Direct link to 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](/preview/pr-749/docs/sources/server/express.md#ingest-metadata)). 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[​](#event-mapping "Direct link to 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`                 |

```json
"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[​](#user-identity "Direct link to 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                   |

```json
"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[​](#email-hashing "Direct link to Email hashing")

Raw emails are lowercased and trimmed, then hashed into all three formats Criteo expects:

* `md5`: MD5 hex digest
* `sha256`: SHA-256 hex digest
* `sha256_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[​](#deduplication "Direct link to 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.

## Links[​](#links "Direct link to Links")

* [Criteo Events API Guide](https://guides.criteotilt.com/events-api/)
