Criteo Server To Server - Website Events¶
Summary¶
A Server-to-Server (S2S) integration is the go-to solution for partners that can not or will not integrate the Criteo OneTag JS pixels on their website for technical, legal, or personal reasons.
As a prerequisite, the partner must be able to store their event data locally. A S2S integration relies on the partner passing us first-party data, so a S2S integration is not possible unless the partner can store this data.
A S2S Integration requires 2 parts: (1) the Cookie Synchronization, and (2) Events Registering.
-
Cookie Synchronization: requesting a unique ID from Criteo (called the "GUM ID" henceforth) for each user, and storing this value in a matching table that matches to a partner-side user ID.
-
Events Registering: sending each event with the matching GUM ID and the correct event data to the Criteo S2S endpoint as an HTTP GET or POST request.
The S2S integration can be separated into 3 Phases (divided into 4 parts below).
prerequisites:
- Stored Events: Partner must be able to store the on-site events and GUM ID locally.
Cookie Synchronization:
-
Criteo Gum Call: Partner must request Criteo GUM ID for all on-site visitors.
-
Matching Table: Partner must maintain a matching table between the partner-side user ID and the Criteo GUM ID
Event Registering:
- Sending S2S Event: Partner must pass Criteo the event and user data using our S2S endpoint.
The image below demonstrates where each part comes into play
Stored Events¶
There are 2 common setups when integrating via S2S
- Sending all on-site events via S2S
- Sending only select events (e.g. only sending Sales Events via S2S)
In either case, the partner is responsible for collecting the necessary on-site browsing data so that it can later be passed to Criteo via S2S.
This is not usually a problem for most clients as their first-party data is typically readily available to the partner in a multitude of formats.
For this reason, we will not explain the process of recording this event data or first party identifier any further.
Criteo GUM Call¶
The first implementation step for S2S is to request a unique, salted, Criteo User ID (aka GUM ID) for each user.
- The same user can receive multiple different GUM IDs, but all GUM IDs will be matched to the same Criteo user.
- This action only needs to be done once per user (in other words, the partner only needs to request a GUM ID for each NEW user on site and can store that ID).
- This call must be sent client side so we can set a 3rd party cookie on the users browser.
- For cookie unfriendly browsers (Ex. Safari), you may not be able to receive a GUM ID.
The URL to request a GUM ID has the following syntax:
https://gum.criteo.com/sync?c={{S2S ID}}&a=1&r=[0-3](&u=[URL])(&j=[callback])
- We will go over in detail what each query parameter means later in this documentation.
As an example, if we visit https://gum.criteo.com/sync?c={{S2S ID}}&a=1&r=0
, then the plaintext GUM ID will be returned.
Query parameters for the GUM call:
- c: partner specific S2S Id (used for salting the Criteo UID).
- This will be hardcoded for all GUM calls.
- a: 0 or 1.
- 1 means Criteo should generate a UID if no UID exists for a given user
- for almost all cases, 1 should be passed.
- r: response type. This will determine how the GUM ID is returned by Criteo.
- 0: plaintext (testing purposes only. CORS will block this in production)
- 1: URL redirection (Criteo will need to whitelist your domain for this method)
- 2: JSONP
Once the GUM ID is returned by Criteo, it should be stored in the matching table for use when sending events to Criteo.
URL Redirection (r=1):
https://gum.criteo.com/sync?c={{S2S ID}}&a=1&r=1&u=[URL]
u: The encoded URL to redirect the GUM ID response to.
- this redirect URL should process the GUM ID and store it in a matching table for use later.
- the GUM ID will auto populate in the URL where
@USERID@
is defined. - the entire parameter will be URL encoded so
@USERID@
becomes%40USERID%40
.
Example redirect URL:
https://gum.criteo.com/sync?c={{S2S ID}}&a=1&r=1&u=https%3A%2F%2Fcriteo.com%2Fendpoint%2F%40USERID%40
JSONP (r=2):
https://gum.criteo.com/sync?c={{S2S ID}}&a=1&r=2&j=[callback]
j: the javascript function name to pass the response to.
- the GUM ID will be passed into the callback function defined as the j parameter which should then process the GUM ID and store it in the matching table.
Example JSONP call:
https://gum.criteo.com/sync?c={{S2S ID}}&a=1&r=2&j=_handleGumResponse
Matching Table¶
After the partner requests the GUM ID from Criteo, the next step is to store this ID in a matching table that links the GUM ID to a partner-side identifier.
- the purpose of the matching table is to be able to tie the event that the partner is recording back to a specific Criteo user, without having to use any Criteo cookies.
Example Workflow:
- partner requests the GUM ID from Criteo
- Criteo UID of user: crit_abc_123
- returned GUM ID: xyz789
- GUM ID is processed upon arrival
- partner stores the GUM ID in the matching table that matches to the partner's identifier. (Ex. client_def_456)
Sending Events¶
Sending events via S2S is not very different than sending them in real time (excluding the time delay).
- OneTag: the on-site Criteo OneTag will collect the necessary info from the site then generate an HTTP quest to the Criteo widget server which will be processed as a tag event
- S2S: The on-site data will be collected by the partner, then the partner will generate an HTTP request to the Criteo Widget server for each event collected which will be processed as a tag hit.
The event syntax for S2S events is the same as the OneTag syntax, however, we require the partner to pass extra information with the event to allow the S2S event to be registered correctly.
The URL the S2S events will be sent to is:
https://widget.criteo.com/m/event?version=s2s_v0
Note that this call will return an HTTP 307
redirect response to the domain specified below according to the region:
Region | Criteo Endpoint URL |
---|---|
EMEA | http://widget.eu.criteo.com/m/event?version=s2s_v0 |
AMER | http://widget.us.criteo.com/m/event?version=s2s_v0 |
APAC | http://widget.as.criteo.com/m/event?version=s2s_v0 |
Once the S2S data is formatted, there are two ways to send the data to Criteo.
- via HTTP POST request to the above URL (data in body payload)
- via HTTP GET request to the above URL (data in a "data" query parameters)
HTTP POST Requests:
When sending an event via a POST request, the payload of the request must be set to the JSON object containing the event data.
Below is a sample CURL call containing the bare minimum information for a homepage event. Please reference the "Event Payloads" section below for more parameters and events.
curl --location --request POST 'https://widget.criteo.com/m/event?version=s2s_v0' \ --header 'Content-Type: application/json' \ --data-raw '{ "account":"XXXX", "site_type":"m,d,or t", "id":{ "mapped_user_id":"XXXXXX", "mapping_key":"XXX" }, "events":[ { "event":"viewHome" } ], "version":"s2s_v1.0.0" }'
HTTP GET Requests:
When sending requests via a GET request, you will be making use of the data
query parameter. The data
query param should contain a URL encoded JSON object containing the S2S event data.
Below is a sample CURL call containing the bare minimum information for a homepage event. Please reference the "Event Payloads" section below for more parameters and events.
curl --location --request GET 'https://widget.criteo.com/m/event?version=s2s_v0&data=%7B%0A%20%20%20%20%22account%22%3A%22XXXX%22%2C%0A%20%20%20%20%22site_type%22%3A%22m%2Cd%2Cor%20t%22%2C%0A%20%20%20%20%22id%22%3A%7B%0A%20%20%20%20%20%20%20%20%22mapped_user_id%22%3A%22XXX%22%2C%0A%20%20%20%20%20%20%20%20%22mapping_key%22%3A%22XXX%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22events%22%3A%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22event%22%3A%22viewHome%22%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22version%22%3A%22s2s_v1.0.0%22%0A%7D'
Event Payloads¶
Every S2S call sent to Criteo will start with the same format. Below is the standard format of the payload without the event declared.
{ "account": "", "ip": "", "full_url": "", "site_type": "", "useragent": "", "retailer_visitor_id": "", "id": { "mapping_key": "", "mapped_user_id": "", "idfa": "", "gaid": "", "email": { "raw": "", "md5": "", "sha256_md5": "", "sha256": "" } }, "events":[ ## Event Object From Below ## ], "version":"s2s_v1.0.0" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
account | The partner ID of the account you are sending the data to. Please reach out to your Criteo representative if you do not have this value. | 12345 | Required |
ip | The IP address of the user. | 127.0.0.1 | Optional |
full_url | The full url where the event is triggered | https://www.example.com/product/12345 | Optional |
site_type | The device type of the user. This accepts 'd' (desktop), 't' (tablet) or 'm' (mobile) | d | Optional |
retailer_visitor_id | A unique Id that is consistent across multiple sessions for an unauthenticated user. Example: First party cookie id | 53e20ea700424f7bbdd793b02abcb5d7 | Optional |
useragent | The user agent string from the users browser. | Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 | Optional |
id.mapping_key | The unique Criteo S2S key for the partner. If you do not have this, please contact your Criteo representative. | 123 | Required |
id.mapped_user_id | The Criteo salted user ID (GUM ID) returned by the GUM call. | crit_abc_123 | Required if available |
id.idfa | Apple's identifier for Advertisers unique identifier. | EA7583CD-A667-48BC-B806-42ECB2B48606 | Optional |
id.gaid | Google's advertising identifier. | cdda802e-fb9c-47ad-9866-0794d394c912 | Optional |
id.email.raw | The users raw email address, whitespace trimmed and lowercase. | user@example.com | Optional |
id.email.md5 | The users email, whitespace trimmed, lowercase and MD5 hashed. | b58996c504c5638798eb6b511e6f49af | Optional |
id.email.sha256_md5 | The users email, whitespace trimmed, lowercase, MD5 hashed then SHA256 hashed. | b58996.... | Optional |
id.email.sha256 | The users email, whitespace trimmed, lowercase and SHA256 hashed. | b58996... | Optional |
Please reference the other sections below to populate the events
array with tags.
Standard Web Events:¶
Visit Event
{ "event": "viewPage", "timestamp":"" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
Login Event
{ "event": "login", "timestamp":"" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
Homepage Event
{ "event": "viewHome", "timestamp":"" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
Listing Event
{ "event": "viewList", "item": [ "##Product Id 1##", "##Product Id 2##", "##Product Id 3##" ], "timestamp":"", "category": "", "keywords": "" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
item | An array of the top 3 products on the listing page a user visited. | ["##Product Id 1##", "##Product Id 2##", "##Product Id 3##"] | Required |
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
category | The category of the listing page. This should match the category information passed in the product feed. | shoes > men's shoes > nike | Optional |
keyword | The searched keyword of the search listing page. | blue shirt | Optional |
Product Event
{ "event": "viewItem", "item": "#Product Id#", "timestamp":"" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
item | The product ID of the product the user looked at. | 1234 | Required |
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
Add To Cart Event
{ "event": "addToCart", "timestamp":"", "currency": "", "item": [ { "id": "##Product Id##", "price": "##Price##", "quantity": "##Quantity##" } ] }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
currency | The ISO code of the currency being passed to the tags. | USD | Optional |
item.id | The product ID of the product the user added to the cart. | 1234 | Required |
item.price | The unit price of the product the user added to the cart. | 12.50 | Required |
item.quantity | The quantity of the product the user added to the cart. | 2 | Required |
Basket Event
{ "event": "viewBasket", "timestamp":"", "currency": "", "item": [ { "id": "##Product Id 1##", "price": "##Price##", "quantity": "##Quantity##" }, { "id": "##Product Id 2##", "price": "##Price##", "quantity": "##Quantity##" } ] }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
currency | The ISO code of the currency being passed to the tags. | USD | Optional |
item.id | The product ID of the products in the cart. | 1234 | Required |
item.price | The unit price of the products in the cart. | 12.50 | Required |
item.quantity | The quantity of the products in the cart. | 2 | Required |
Begin Checkout Event
{ "event":"beginCheckout", "timestamp":"", "currency": "", "item":[ { "id":"#Product ID#", "price":"#unit price#", "quantity": "#quantity#" } ] }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
currency | The ISO code of the currency being passed to the tags. | USD | Optional |
item.id | The product ID of the products in the cart. | 1234 | Required |
item.price | The unit price of the products in the cart. | 12.50 | Required |
item.quantity | The quantity of the products in the cart. | 2 | Required |
Add Payment Info Event
{ "event": "addPaymentInfo", "timestamp":"" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
Sales Event
{ "event":"trackTransaction", "timestamp":"", "id":"", "dd": "", "currency": "", "item":[ { "id":"#Product ID#", "price":"#unit price#", "quantity": "#quantity#" } ] }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
id | The order ID used to identify a given order. | ord-1234 | Required |
dd | Populate this with a 1 if you want the sale to be attributed to Criteo or a 0 if you do not. We will still only attribute the sale to Criteo if the order should have been attributed to us via our normal attribution. | 1 | Optional |
currency | The ISO code of the currency being passed to the tags. | USD | Optional |
item.id | The product ID of the products in the cart. | 1234 | Required |
item.price | The unit price of the products in the cart. | 12.50 | Required |
item.quantity | The quantity of the products in the cart. | 2 | Required |
Travel Specific Events:¶
Search Event
{ "event":"viewSearch", "timestamp":"", "checkin_date": "", "checkout_date": "", "nbra": "", "nbrc": "", "nbri": "", "nbrr": "", }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
checkin_date | The check in date the user submitted. | 2017-06-02 | Optional |
checkout_date | The check out date the user submitted. | 2017-06-02 | Optional |
nbra | The number of adults searched for. | 2 | Optional |
nbrc | The number of children searched for. | 2 | Optional |
nbri | The number of infants searched for. | 2 | Optional |
nbrr | The number of rooms searched for. | 1 | Optional |
Store Specific Events:¶
View Store Event
{ "event":"viewStore", "timestamp":"", "store_id": "" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
store_id | The store id as passed to us in the feed. | A734Gd87 | Optional |
Availability In Store Event
{ "event":"checkAvailability", "timestamp":"", "store_id": [], "item": "" }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
store_id | The store id as passed to us in the feed. This is an array for stores with the product available. | ["A734Gd87","A734Gd897"] | Optional |
item | The unique ID of the product. | 1234abc | Required |
Reserve In Store Event
{ "event": "reserveInStore", "timestamp":"", "store_id": "", "currency": "", "item": [ { "id": "", "quantity": "", "price": "" } ] }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
store_id | The store id as passed to us in the feed. This is an array for stores with the product available. | ["A734Gd87","A734Gd897"] | Optional |
currency | The ISO code of the currency being passed to the tags. | USD | Optional |
item.id | The product ID of the products in the cart. | 1234 | Required |
item.price | The unit price of the products in the cart. | 12.50 | Required |
item.quantity | The quantity of the products in the cart. | 2 | Required |
Click and Collect
{ "event": "trackTransaction", "timestamp":"", "id": "", "delivery": "store", "store_id": "", "currency": "", "item": [ { "id": "", "quantity": "", "price": "" } ] }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Optional |
id | The order ID used to identify a given order. | ord-1234 | Required |
store_id | The store id as passed to us in the feed. | A734Gd87 | Optional |
currency | The ISO code of the currency being passed to the call. | USD | Optional |
item.id | The product ID of the products in the order. | 1234 | Required |
item.price | The unit price of the products in the order. | 12.50 | Required |
item.quantity | The quantity of the products in the order. | 2 | Required |
Offline Sales
{ "event": "trackTransaction", "timestamp":"", "id": "", "user_segment": 19, "store_id": "", "currency": "", "item": [ { "id": "", "quantity": "", "price": "" } ] }
Parameter | Explanation | Sample Input | Required? |
---|---|---|---|
timestamp | The timestamp the event happened for the user. | 2017-06-02T12:24:10Z | Mandatory |
id | The order ID used to identify a given order. | ord-1234 | Required |
store_id | The store id as passed to us in the feed. | A734Gd87 | Optional |
currency | The ISO code of the currency being passed to the call. | USD | Optional |
item.id | The product ID of the products in the order. | 1234 | Required |
item.price | The unit price of the products in the order. | 12.50 | Required |
item.quantity | The quantity of the products in the order. | 2 | Required |
Event Sending - Responses¶
The widget call will always return a 200 response. You will need to reference the payload or lack there of to determine if the call was successful or not.
With successful responses, you will receive the response below:
{ "errors": [], "warnings": [] }
If you receive anything but no errors, even lack of this response, it's likely there is an issue with the call.
GDPR Consent¶
With our S2S solution, we give partners the ability to pass us GDPR consent through the GUM call or Event call. If you pass the GDPR consent through the GUM call, you do not need to pass it in the event call.
Passing the consent in the GUM call¶
If you send the below two additional query params in the GUM call and the user has consented to Criteo tracking, we will return a GUM ID so the event can be recorded on the Criteo side. If the user has not consented to Criteo tracking, you will not receive a UID in the response. If you use this method, it is not required to send the GDPR query parameters in the event calls. If no UID is returned in this GUM call, we will still want the event but you can send the event without a UID.
The two query parameters are below:
Parameter | Explanation | Sample Input |
---|---|---|
gdpr | This parameter lets Criteo know that GDPR applies to this user. This should be set to 1 if GDPR applies and 0 if not. | 1 |
gdpr_consent | This parameter contains the TCF consent string and will be considered if gdpr=1 is sent in the gdpr query param. | CO_7cUEO_7cUEAGABCENBICgAAAAAAAAAAYgAAAAAAAA.YAAAAAAAAAAA |
A sample GUM call with the above query params looks like the below:
https://gum.criteo.com/sync?c={{S2S ID}}&a=1&r=2&j=_handleGumResponse&gdpr=1&gdpr_consent=CO_7cUEO_7cUEAGABCENBICgAAAAAAAAAAYgAAAAAAAA.YAAAAAAAAAAA
Passing the consent in the Event call (widget call)¶
If you choose to pass GDPR consent in the event call, you will need to add 3 query parameters to the widget endpoint. If the user has not consented to Criteo tracking, the event will be sent anonymously without the user's UID. If no UID was returned in the GUM call, you can still send the event without a UID. These query parameters are described below:
Parameter | Explanation | Sample Input |
---|---|---|
gra | A flag to let Criteo know GDPR applies to this call. This should be a 1 if the two parameters below are populated, 0 if they are absent. | 1 |
grs | This parameter contains the TCF consent string. | CO_7cUEO_7cUEAGABCENBICgAAAAAAAAAAYgAAAAAAAA.YAAAAAAAAAAA |
grv | This parameter is present only for TCF v2 and contains the TCF version, i.e. grv=2. For TCF v1.1 this parameter will not be present | 2 |
A sample widget.criteo.com
(event) url for a POST or GET call with the above query params looks like the below (excluding the POST payload and GET data
query parameter):
https://widget.criteo.com/m/event?version=s2s_v0&gra=1&grs=CO_7cUEO_7cUEAGABCENBICgAAAAAAAAAAYgAAAAAAAA.YAAAAAAAAAAA&grv=2