# API Authorization Source: https://developers.criteo.com/criteo-apis/docs/api-authorization Once you have completed your application setup and obtained your tokens, you will need access to advertiser accounts to start making API calls with our endpoints. The following pages will guide you through generating consent URLs and requesting advertiser access for the Criteo account you intend to use. # API Client Libraries Source: https://developers.criteo.com/criteo-apis/docs/api-client-libraries Officially supported client libraries for the Criteo Marketing Solutions, Retail Media, and Commerce Grid APIs. API Client Libraries reduce the amount of code you need to write to start accessing Criteo programmatically. They also help expedite troubleshooting when issues arise. *** ## Marketing Solutions API Three officially supported libraries: **Python:** [https://pypi.org/project/criteo-api-marketingsolutions-sdk/](https://pypi.org/project/criteo-api-marketingsolutions-sdk/) **PHP:** [https://packagist.org/packages/criteo/criteo-api-marketingsolutions-sdk](https://packagist.org/packages/criteo/criteo-api-marketingsolutions-sdk) **Java:** [https://search.maven.org/artifact/com.criteo/criteo-api-marketingsolutions-sdk](https://search.maven.org/artifact/com.criteo/criteo-api-marketingsolutions-sdk) **Setup guides:** [Java](https://github.com/criteo/criteo-api-java-sdk) · [PHP](https://packagist.org/packages/criteo/criteo-api-marketingsolutions-sdk) · [Python](https://github.com/criteo/criteo-api-python-sdk) *** ## Retail Media API Three officially supported libraries: **Python:** [https://pypi.org/project/criteo-api-retailmedia-sdk/](https://pypi.org/project/criteo-api-retailmedia-sdk/) **PHP:** [https://packagist.org/packages/criteo/criteo-api-retailmedia-sdk](https://packagist.org/packages/criteo/criteo-api-retailmedia-sdk) **Java:** [https://search.maven.org/search?q=a:criteo-api-retailmedia-sdk](https://search.maven.org/search?q=a:criteo-api-retailmedia-sdk) One community-supported library: **Node.js:** [https://github.com/joepikowski/criteo-api-nodejs-client](https://github.com/joepikowski/criteo-api-nodejs-client) **Setup guides:** [Java](https://github.com/criteo/criteo-api-java-sdk) · [PHP](https://packagist.org/packages/criteo/criteo-api-retailmedia-sdk) · [Python](https://github.com/criteo/criteo-api-python-sdk) *** ## Commerce Grid API Three officially supported libraries: **Python:** [https://pypi.org/project/criteo-api-commercegrid-sdk/](https://pypi.org/project/criteo-api-commercegrid-sdk/) **PHP:** [https://packagist.org/packages/criteo/criteo-api-commercegrid-sdk](https://packagist.org/packages/criteo/criteo-api-commercegrid-sdk) **Java:** [https://search.maven.org/artifact/com.criteo/criteo-api-commercegrid-sdk](https://search.maven.org/artifact/com.criteo/criteo-api-commercegrid-sdk) **Setup guides:** [Java](https://github.com/criteo/criteo-api-java-sdk) · [PHP](https://packagist.org/packages/criteo/criteo-api-commercegrid-sdk) · [Python](https://github.com/criteo/criteo-api-python-sdk) # API Error Codes Source: https://developers.criteo.com/criteo-apis/docs/api-error-codes ## Introduction When working with the API you may encounter errors caused by implementation flaws, wrong input, or environmental differences. Criteo strives to reasonably ensure maximum possible stability of the API system, however in exceptionally rare cases internal server errors may occur. This document will help you to navigate through various types of error messages, the error message structure, and advise you on the common recovery mechanisms for the Criteo API. *** ## Criteo API error types This section gives a high-level description of various error categories that can be generated from your interaction with the API to help you design error handling mechanism of your application. The following sections will explain in more detail how to handle each error type. ### Authorization & Authentication errors These types of errors may appear if you either don't possess a valid token or the token is lacking access permissions for the endpoint you are trying to reach. This error will also appear if the token has expired. For example, if an account administrator has revoked access for your application you will get HTTP error `403 - Forbidden`. A list of common HTTP errors and the recovery strategy can be found in the next section. *** ### Validation errors Validation errors are commonly caused by user-initiated requests and can be further classified into the following categories: * **User input validation**. Typically is evoked when the input supplied by the user is not valid. In this case your application should provide a specific error message to your user based on the error title and error detail. If the error detail is missing, the error title should contain sufficient description. * **Business logic validation**. This type of error is evoked when the current action is not possible due to the account configuration state. For example, launching a Campaign without a positive balance is not possible. In the case of business validation failure, the right strategy would be to request an action from the end user of your application. *** ### Dependency failure Internal error due to temporary unavailability of internal dependency or data persistence failure. This error will have a detailed description of the error in the response body. *** ### Internal server error Generic server-side errors that are not part of business validation. This could be a temporary network failure or host unavailability. If your application has a UI you should immediately indicate an error in your UI so that the end user can attempt to retry the operation. Alternatively, you can retry automatically within set limit of maximum number of attempts using an exponential back-off strategy (see the next section). *** ## HTTP error codes The initial information about the success/failure of a request is based on the conformance to the standard HTTP Status Codes. These status codes indicate at a broader level the kind of problem encountered client-side or server-side. The same HTTP status codes are sometimes not sufficient to convey enough information about an error to be helpful. In order to allow your application be more robust and user-friendly, Criteo provides pertinent information in the response body following [RFC-7807](https://tools.ietf.org/html/rfc7807) standard. This ensures consistency and predictability of integration by providing additional information about a problem encountered.

HTTP code

Description

Notes

400

Bad request, invalid syntax

Generic response will be provided in case of technical failure due to malformed HTTP-request has been received. For example, the request is missing body altogether, has incompatible header and body, or serialization error encountered.

In the case of business validation error, fine-grained error information will be provided in the response body.

401

Authentication error

If Criteo API responded with 401 it means that there is an issue with authentication, e.g invalid authentication credentials, or an expired token was supplied with the request.

403

Forbidden

The request is forbidden due to missing permission on advertiser or domain. Make sure  your application requests all required permissions.

In addition, ensure the consent has been granted on the scope of the requested account. The consent has to be granted by the account owner.

If your connector has a UI  you can  relaunch the OAuth2 flow to reestablish your permission set on advertiser's account.

This error type may have additional information in response body.

Please note, non-existing resource or not enough permissions in case of request to the bulk endpoint requests will result in empty response and 200 response code (see note in the end)

404

Not found

Check correctness of the URL being called.

413

Payload too large

This error may appear if your request payload contains more data then the web-server is set to process in a single request. If you encounter this issue, try breaking up the request into several with smaller chunks of data or use pagination where it's supported.

415

Unsupported media type

This error means the wrong value for content-type header has been supplied. For example, you can get this type of error if you supply 'Content-Type: application/xml'

instead of 'Content-Type: application/json' in the request header.

429

Rate limit reached

Client Credentials: 250 calls per minute; Authorization Code: 10 calls per minute. More details here .

500

Internal server error

Generic internal server error due to temporary unavailability of service. It is recommended to use an exponential backoff policy to ensure you are not overloading API network and the endpoint. For example, if your first request failed, wait 10 seconds before the retry. If the consequent request failed, wait for 20 seconds; then 40 seconds for a third time, and so on.

503

Service unavailable

Internal error due to overload or maintenance. It is recommended to use an exponential backoff policy to ensure you are not overloading API network and the endpoint.    For example, if your first request failed, wait 10 seconds before the retry. If the consequent request failed, wait for 20 seconds; then 40 seconds for a third time, and so on.

*** ## Fine-grained failure response As already mentioned earlier, the Criteo API error-handling mechanism is based on HTTP protocol to report the errors.  The errors section of the HTTP response is an array of errors providing finer details in conjunction with the error response code. An example where this would be a useful error information, is if you are requesting a Statistics report with the start date later than the end date (see the example below). If there are no errors, this section may be omitted. *** ## Error structure  In order to report domain-specific and validation errors  Criteo API responds with JSON-like object with the error details. Following is an example of such type of response: ```json theme={null} { "errors": [ { "traceId": "00000000-0000-0000-befd-7e28ff5a4d71", "type": "validation", "code": "start-after-end-date", "instance": "/report", "title": "The start date can not be after the end date." } ] } ``` * **traceId**: Technical identifier that allows Criteo engineering team to find correlation between your request and the error in the backend. Include traceId into the report when submitting a support request to us. Mandatory parameter. * **type**:  Machine-readable field that specifies error category. Use this value to properly inform your user about the outcome and apply the best recovery tactic.  The list of possible values is given below. * **instance**:  Machine-readable reference to the endpoint to help to identify the specific occurrence of the problem. * **code**: Machine-readable error code unique to each endpoint. * **title**: A human-readable description of the error. If your application has UI this can be displayed in **dialog title**: Mandatory parameter. * **detail**: A human-readable explanation of the problem. If your application has UI this can be displayed in dialog content. *** ## Warnings structure Semantically Criteo-API issued warnings are similar to compiler warnings. They indicate that problems may occur in the future. Structurally it is represented as an array returned in HTTP response, similar to error structure. *** ### Bulk request VS single entity endpoints * Bulk requests will always return a `200 OK` response, regardless of individual entity failures. If one or more entities cannot be processed, a warning will be included in the response body detailing the issues. These problematic entities will be excluded from further processing. * A `403 Forbidden` response will only be returned when the requested account does not exist or the requester lacks valid permissions (e.g., missing consent). * If the search criteria returns empty information, it will return: ```json theme={null} { "meta": { "totalItems": 0, "limit": 50, "offset": 0 }, "data": [], "warnings": [], "errors": [] } ``` * Warnings may be returned even for a successful response. *** ## Error category types

type

example code

example title

example details

access-control

insufficient-advertiser-permissions

"insufficient advertiser permissions"

"You do not have permission. to access this Advertiser"

availability

internal-error

"Campaigns are unavailable"

"Campaigns are temporarily unavailable, please try again"

deprecation

deprecated-field

"A field is deprecated"

" \ is deprecated, please use the field \ "

" \ is deprecated, please use the value \ "

where \ and \ are replaced by their actual values.

endpoint-deprecated

"Endpoint deprecated"

"Endpoint \ is deprecated, please upgrade to \ "

validation

required-field

campaign-not-found

"This field is required"

"Campaign is not found"

" \ is required"

"Campaign 3124159 does not exist"

invalid-date-format

"This field must be YYYY-MM-DD"

Example:

" \ must be YYYY-MM-DD format. Value: ' \ '"

invalid

"This field must be in list of required values"

" \ must be one of 'a', 'b', or 'c'. Value: ' \ ' "

invalid-range

"This field is not in the valid range"

" \ must be between \ and \ . Value: ' \ '"

invalid-timespan

"The date span is too large"

" \ to \ must be no more than \ days.  Value: ' \ '"

*** ## Authentication Error codes `authorization-token-missing`\ The authorization header is missing. Please make sure the authorization header with a valid token is attached to the request. `authorization-token-expired` The authorization token is expired. The token lifetime is 900 seconds from the moment of its generation. If a token is used after the expiration date the error will be thrown. If you would like to avoid manual token management consider [Criteo API librairies](/criteo-apis/docs/api-client-libraries): the librairies offer the token auto-refresh feature. Before a call to the endpoint, the library checks that the token is not expired and fetches a new one otherwise. `authorization-token-invalid` The authorization header is invalid: either the wrong format or wrong content of the authorization header was supplied. `authorization-issuer-invalid` The authorization issuer is invalid. The token originator could not be verified. If you receive this error please contact API support. `authorization-unknown` Unknown Authorization error. Please contact API support. If you receive this error please contact API support. *** ## Other Error codes More error code information can be found on the pages dedicated to the corresponding endpoints. ***
# API Error Types Source: https://developers.criteo.com/criteo-apis/docs/api-error-types # Introduction When working with the API you may encounter errors caused by implementation flaws, wrong input, or environmental differences. Criteo strives to reasonably ensure maximum possible stability of the API system, however in exceptionally rare cases internal server errors may occur. This document will help you to navigate through various types of error messages, the error message structure, and advise you on the common recovery mechanisms for the Criteo API. # Criteo API error types This section gives a high-level description of various error categories that can be generated from your interaction with the API to help you design error handling mechanism of your application. The following sections will explain in more detail how to handle each error type. ### Authorization & Authentication errors These types of errors may appear if you either don't possess a valid token or the token is lacking access permissions for the endpoint you are trying to reach. This error will also appear if the token has expired. For example, if an account administrator has revoked access for your application you will get HTTP error `403 - Forbidden`. A list of common HTTP errors and the recovery strategy can be found in the next section. ### Validation errors Validation errors are commonly caused by user-initiated requests and can be further classified into the following categories: * **User input validation**. Typically is evoked when the input supplied by the user is not valid. In this case your application should provide a specific error message to your user based on the error title and error detail. If the error detail is missing, the error title should contain sufficient description. * **Business logic validation**. This type of error is evoked when the current action is not possible due to the account configuration state. For example, launching an Ad Set without a positive balance is not possible. In the case of business validation failure, the right strategy would be to request an action from the end user of your application. * **Technical validation**. These validation errors are similar to the business logic validation errors, but are caused for technical reasons. For example, error code `campaign--ad-set-start-check--cannot-activate-archived-ad-set` should cause your application to mark requested Ad Set as archived in your local DB.\ For business-critical operations (e.g start/stop Ad Set) you may want to add the failed operation to a queue for the end user to review. ### Dependency failure Internal error due to temporary unavailability of internal dependency or data persistence failure. This error will have a detailed description of the error in the response body. ### Internal server error Generic server-side errors that are not part of business validation. This could be a temporary network failure or host unavailability. If your application has a UI you should immediately indicate an error in your UI so that the end user can attempt to retry the operation. Alternatively, you can retry automatically within set limit of maximum number of attempts using an exponential back-off strategy (see the next section). # HTTP error codes The initial information about the success/failure of a request is based on the conformance to the standard HTTP Status Codes. These status codes indicate at a broader level the kind of problem encountered client-side or server-side. The same HTTP status codes are sometimes not sufficient to convey enough information about an error to be helpful. In order to allow your application be more robust and user-friendly, Criteo provides pertinent information in the response body following [RFC-7807](https://tools.ietf.org/html/rfc7807) standard. This ensures consistency and predictability of integration by providing additional information about a problem encountered.

HTTP code

Description

Notes

400

Bad request, invalid syntax

Generic response will be provided in case of technical failure due to malformed HTTP-request has been received. For example, the request is missing body altogether, has incompatible header and body, or serialization error encountered.

In the case of business validation error, fine-grained error information will be provided in the response body.

401

Authentication error

If Criteo API responded with 401 it means that there is an issue with authentication, e.g invalid authentication credentials, or an expired token was supplied with the request. Please check Authentication for further information.

403

Forbidden

The request is forbidden due to missing permission on advertiser or domain. Make sure  your application requests all required permissions.

In addition, ensure the consent has been granted on the scope of the requested account. The consent has to be granted by the account owner.

If your connector has a UI  you can  relaunch the OAuth2 flow to reestablish your permission set on advertiser's account.

This error type may have additional information in response body.

Please note, non-existing resource or not enough permissions in case of request to the bulk endpoint requests will result in empty response and 200 response code (see note in the end)

404

Not found

Check correctness of the URL being called. Reference list of the endpoints can be found here .

413

Payload too large

This error may appear if your request payload contains more data then the web-server is set to process in a single request. If you encounter this issue, try breaking up the request into several with smaller chunks of data or use pagination where it's supported.

415

Unsupported media type

This error means the wrong value for content-type header has been supplied. For example, you can get this type of error if you supply 'Content-Type: application/xml'

instead of 'Content-Type: application/json' in the request header.

429

Rate limit reached

Limit is 100 requests per minute per application. More details here .

500

Internal server error

Generic internal server error due to temporary unavailability of service. It is recommended to use an exponential backoff policy to ensure you are not overloading API network and the endpoint. For example, if your first request failed, wait 10 seconds before the retry. If the consequent request failed, wait for 20 seconds; then 40 seconds for a third time, and so on.

503

Service unavailable

Internal error due to overload or maintenance. It is recommended to use an exponential backoff policy to ensure you are not overloading API network and the endpoint.    For example, if your first request failed, wait 10 seconds before the retry. If the consequent request failed, wait for 20 seconds; then 40 seconds for a third time, and so on.

# Fine-grained failure response As already mentioned earlier, the Criteo API error-handling mechanism is based on HTTP protocol to report the errors.  The errors section of the HTTP response is an array of errors providing finer details in conjunction with the error response code. An example where this would be a useful error information, is if you are requesting a Statistics report with the start date later than the end date (see the example below). If there are no errors, this section may be omitted. ## Error structure  In order to report domain-specific and validation errors  Criteo API responds with JSON-like object with the error details. Following is an example of such type of response: ```json theme={null} { "errors": [ { "traceId": "00000000-0000-0000-befd-7e28ff5a4d71", "type": "validation", "code": "start-after-end-date", "instance": "/report", "title": "The start date can not be after the end date." } ] } ``` **traceId**: Technical identifier that allows Criteo engineering team to find correlation between your request and the error in the backend. Include traceId into the report when submitting a support request to us. Mandatory parameter.\ **type**:  Machine-readable field that specifies error category. Use this value to properly inform your user about the outcome and apply the best recovery tactic.  The list of possible values is given below.\ **instance**:  Machine-readable reference to the endpoint to help to identify the specific occurrence of the problem.\ **code**: Machine-readable error code unique to each endpoint.\ **title**: A human-readable description of the error. If your application has UI this can be displayed in **dialog title**: Mandatory parameter.\ **detail**: A human-readable explanation of the problem. If your application has UI this can be displayed in dialog content. ## Warnings structure Semantically Criteo-API issued warnings are similar to compiler warnings. They indicate that problems may occur in the future. Structurally it is represented as an array returned in HTTP response, similar to error structure. **Note** * Bulk requests will always return HTTP response 200. If the request fails, partially failed entities will be returned in the array of errors. * If non-existing Ad Set is requested the error code 403 "insufficient-permissions" will be returned for a single entity endpoint. HTTP status code will be set as 200 for the *bulk* endpoints.\ For example, GET request to non-existing Ad Set via ad-sets`<AdSetId>` endpoint will return 403 response because ad-sets`<AdSetId>` is a single entity endpoint. At the same time, POST to ad-sets/search endpoint in case of insufficient permissions will return successful response with the following body:\ \{\ "data":\[]\ "warnings":\[]\ "errors":\[]\ }\ because ad-sets/search is a bulk endpoint. * Warnings may be returned even for a successful response. # Error category types

type

example code

example title

example details

access-control

insufficient-advertiser-permissions

"insufficient advertiser permissions"

"You do not have permission. to access this Advertiser"

availability

internal-error

"Campaigns are unavailable"

"Campaigns are temporarily unavailable, please try again"

deprecation

deprecated-field

"A field is deprecated"

" \ is deprecated, please use the field \ "

" \ is deprecated, please use the value \ "

where \ and \ are replaced by their actual values.

endpoint-deprecated

"Endpoint deprecated"

"Endpoint \ is deprecated, please upgrade to \ "

validation

required-field

campaign-not-found

"This field is required"

"Campaign is not found"

" \ is required"

"Campaign 3124159 does not exist"

invalid-date-format

"This field must be YYYY-MM-DD"

Example:

" \ must be YYYY-MM-DD format. Value: ' \ '"

invalid

"This field must be in list of required values"

" \ must be one of 'a', 'b', or 'c'. Value: ' \ ' "

invalid-range

"This field is not in the valid range"

" \ must be between \ and \ . Value: ' \ '"

invalid-timespan

"The date span is too large"

" \ to \ must be no more than \ days.  Value: ' \ '"

# Authentication Error codes *`authorization-token-missing`*\ The authorization header is missing. Please make sure the authorization header with a valid token is attached to the request. *`authorization-token-expired`* The authorization token is expired. The token lifetime is 900 seconds from the moment of its generation. If a token is used after the expiration date the error will be thrown. If you would like to avoid manual token management consider [installing Criteo librairies](/criteo-apis/docs/api-client-libraries): the libraries offer the token auto-refresh feature. Before a call to the endpoint the library checks that the token is not expired and fetches a new one otherwise. *`authorization-token-invalid`* The authorization header is invalid: either the wrong format or wrong content of the authorization header was supplied. *`authorization-issuer-invalid`* The authorization issuer is invalid. The token originator could not be verified. If you receive this error please contact API support. *`authorization-unknown`* Unknown Authorization error. Please contact API support. If you receive this error please contact API support. # Other Error codes More error code information can be found on the pages dedicated to the corresponding endpoints. # API Pattern Source: https://developers.criteo.com/criteo-apis/docs/api-pattern ## Base URL ```http theme={null} https://api.criteo.com//retail-media/{endpoint} ``` ## Request `type` In request payloads, `type` identifies the resource type you are sending. For requests, `type` is completely optional. You can omit it, but it can be useful in complex systems where you validate payload structure and data types before sending data to Criteo's API. The technical definition of each resource type is contained in the machine-readable [OpenAPI specification](/criteo-apis/docs/criteo-api-swagger). ### Example ```json theme={null} { "data": [ { "type": "AudienceSegment", "attributes": { "name": "{segmentName}", "description": "{segmentDescription}", "retailerId": "{retailerId}", "contactList": { "identifierType": "Email" } } } ] } ``` *** ## Synchronous Endpoints All campaign operations except for Catalogs are achieved through **synchronous endpoints**. Those will return a response in real-time.

Operation

Method

Endpoint

Create an entity

POST

/\{plural-parent-entity-name}/\{parentEntityId}/\{plural-entity-name}

Delete from a list

POST

/\{plural-parent-entity-name}/\{parentEntityId}/\{plural-entity-name}/delete

Append to a list

POST

/\{plural-parent-entity-name}/\{parentEntityId}/\{plural-entity-name}/append

Get all entities

GET

/\{plural-parent-entity-name}/\{parentEntityId}/\{plural-entity-name}

Get a specific entity

GET

/\{plural-entity-name}/\{entityId}

Update a specific entity

PUT

/\{plural-entity-name}/\{entityId}

* `Create` operations using the `POST` method expect every **Required (R)** field; omitting **Optional (O)** fields will set those fields to **Default** values. * `Update` operations using the `PUT` method expect every **Write (W)** field; omitting these fields is equivalent to setting them to `null`, if possible. *** ## Asynchronous Endpoints "Catalogs" and "Reports" are requested and retrieved through asynchronous endpoints. Those will send a response once the request is done processing (not in real-time).

Operation

Method

Endpoint

Create a resource request

POST

/\{plural-parent-entity-name}/\{parentEntityId}/\{plural-entity-name}

or

/\{plural-parent-entity-name}/\{plural-entity-name}

Retrieve the status of the requested resource

GET

/\{plural-entity-name}/\{entityId}/status

Retrieve the output of the requested resource

GET

/\{plural-entity-name}/\{entityId}/output

*** ## Bulk calls Please refer to[ this page](/criteo-apis/docs/bulk-calls) for more information about Bulk Calls. *** ## Error Codes When sending more than 50 IDs, you will get the following `400 Bad request` HTTP Response: ```json theme={null} { "errors": [ { "code": "exceeded-ids-cap", "title": "Requests are capped for 50 unique ids, 51 were provided", "type": "validation", "traceId": "aa47dd83-8ca9-4a79-a179-ad5be6932ff1", "instance": "/api/v1/reports/line-item", "detail": "ids Requests are capped for 50 unique ids, 51 were provided (Value: \"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51\")", "source": { "ids": "data/attributes/ids" } } ] } ``` This Contains: * Error code: `exceeded-ids-cap` * Error title: `Requests are capped for 50 unique ids, {count of ids requested} were provided` * Error Type: `validation` * A `traceId`: `aa47dd83-8ca9-4a79-a179-ad5be6932ff1` * Instance: the report requested (here `/api/v1/reports/line-item`) * Detail: Title with a list of requested IDs * Source: The parameter that caused the error (IDs in this case) *** # API Response Source: https://developers.criteo.com/criteo-apis/docs/api-response ## Introduction Our APIs respond with `data`, `errors`, and `meta`/`metadata` blocks where appropriate. For example: * `{entityId}` are unique across all Retail Media entities * `data` and `errors` blocks may be contained in responses expected to return multiple entities * `meta` (or `metadata`) appears only for paginated responses ### Response example ```json JSON expandable theme={null} { "data": [ { "id": "{entityId}", "type": "{entityType}", "attributes": { "{fieldName}": {numericValue}, "{fieldName}": "{stringValue}", // ... } }, // ... ], "errors": [ { "traceId": "{traceId}", "type": "{errorType}", "code": "{errorCode}", "instance": "{uri}", "title": "{errorTitle}", "detail": "{errorDetail}", "source": { "{fieldName}": "{fieldPath}", // ... } }, // ... ], "metadata": { "totalItemsAcrossAllPages": {numberOfEntities}, "currentPageSize": {pageSize}, "currentPageIndex": {pageIndex}, "totalPages": {numberOfPages}, "nextPage": "https://api.criteo.com/{endpoint}?pageIndex={pageIndex}&pageSize={pageSize}", "previousPage": "https://api.criteo.com/{endpoint}?pageIndex={pageIndex}&pageSize={pageSize}" } ``` *** ## Data Attributes

Attribute

Type

Description

id

string

Unique ID for the entity. Entity IDs are unique across all Retail Media entities

type

string

Resource data type returned in the response body (for example, RetailMediaRetailer )

attributes

object

Entity attributes - may be omitted entirely if an entity does not have additional attributes

*** ## Error Attributes

Attribute

Type

Description

traceId

string

Unique ID for the error response

type

string

Error category; machine-readable (e.g. validation )

code

string

Short machine-readable string for the error (e.g. required-field )

instance

string

URI referencing the endpoint that caused the error

title

string

Short human-readable string that summarizes the issue

detail

string

Human-readable explanation of the issue

source

object

Object referencing the field that caused the error

*** ## Pagination Endpoints that retrieve all entities under a specific context supports pagination to navigate through all existing elements. Currently, there are two different formats to access the different pages that are based on different sets of query parameters and response blocks. Results are returned in ascending order by `id` Examples of endpoints: 1. List all Accounts associated with your API credentials 2. List all Brands associated with the Account 3. List all Retailers associated with the Account ### Offset & Limit

Query Parameters

Type

Description

offset

integer

Defines the starting point from which records should be returned, i.e., will skip the first offset records (ordered by id ) and return the subsequent ones; defaults to 0 if omitted

limit

integer

Specifies the maximum number of entities returned in a single page; defaults to 500 entities per page (if no other value is specified at endpoint-level)

#### Response example ```json theme={null} { "data": [ { "id": "{entityId}", "type": "{entityType}", "attributes": { "{fieldName}": {numericValue}, "{fieldName}": "{stringValue}", // ... } }, // ... ], "meta": { "count": {numberOfEntities}, "offset": {offset}, "limit": {limit} } } ``` ### `pageIndex` & `pageSize`

Query Parameters

Type

Description

pageIndex

integer

Returns the specified page of results given a pageSize ; pages are 0-indexed

pageSize

integer

Specifies the maximum number of entities returned in a single page; defaults to 25 entities per page

### Response example ```json theme={null} { "data": [ { "id": "{entityId}", "type": "{entityType}", "attributes": { "{fieldName}": {numericValue}, "{fieldName}": "{stringValue}", // ... } }, // ... ], "metadata": { "totalItemsAcrossAllPages": {numberOfEntities}, "currentPageSize": {pageSize}, "currentPageIndex": {pageIndex}, "totalPages": {numberOfPages}, "nextPage": "https://api.criteo.com/{endpoint}?pageIndex={pageIndex}&pageSize={pageSize}", "previousPage": "https://api.criteo.com/{endpoint}?pageIndex={pageIndex}&pageSize={pageSize}" } } ``` *** ## Understanding `type` In the `data` block, `type` describes the resource data type returned in the response body. For example, retailer responses can return `type: "RetailMediaRetailer"`. The technical definition of each response type is contained in the machine-readable [OpenAPI specification](/criteo-apis/docs/criteo-api-swagger). The `type` field inside `errors` is different: it identifies the error category, such as `validation`. ### Example ```json theme={null} { "data": [ { "id": "1234", "type": "RetailMediaRetailer", "attributes": { "name": "{retailerName}" } } ] } ```
## Filter by ID All endpoints that retrieve all entities under a specific context supports an optional query parameter `limitToId` that can be used to retrieve the respective element. This param can also be combined multiple times to retrieve multiple elements at the same time. Examples: 1. Retrieve specific Account(s) from endpoint that lists all Accounts 2. Retrieve specific Brand(s) from endpoint that lists all Brands associated with the Account 3. Retrieve specific Retailer(s) from endpoint that lists all Retailers associated with the Account

Query Parameters

Type

Description

limitToId

integer

Limits results to the entity IDs specified; parameter key is repeated, e.g. limitToId=1\&limitToId=2

### Response example ```json theme={null} { "data": [ { "id": "1", "type": "{entityType}", "attributes": { "{fieldName}": {numericValue}, "{fieldName}": "{stringValue}", // ... } }, { "id": "2", "type": "{entityType}", "attributes": { "{fieldName}": {numericValue}, "{fieldName}": "{stringValue}", // ... } }, ], "meta": { "count": 2, "offset": 0, "limit": 500 } } ```
*** ## HTTP Response Codes

Response

Description

🔵

200 OK

Request successful

🔵

201 Created

The new entity was successfully created

🔵

204 No Content

Request succeeded and no returned content should be expected

🟡

207 Multi-Status

This may occur when operating on multiple entities, such as the call resulting in some successes but also some failures

🔴

400 Bad Request

For improper syntax, check your call structure

🔴

401 Unauthorized

If unauthenticated, refresh your access token

🔴

403 Forbidden

Insufficient rights to perform this action

🔴

404 Not Found

Resource not found, check your entity IDs in the call

🔴

408 Timeout

Request timed out

🔴

409 Conflict

Request conflicts with something, such as a campaign name that already exists

🔴

429 Too Many Requests

Too many requests

🔴

5xx

Something's wrong on Criteo's end...

*** # Troubleshooting Guide Source: https://developers.criteo.com/criteo-apis/docs/api-troubleshooting-guide ## Introduction This guide covers basic checks to identify the source of errors, common issue types, and data latency/discrepancy considerations. If the issue cannot be resolved after these steps, please see our [Escalation Guidelines](/criteo-apis/docs/escalation-guidelines). *** ## Does The Error Come From My app or the Criteo Server? These simple checks will help you to separate client-side issues from server bugs. ### Connectivity Requests failing at the origin or blocked by the firewall configurations are surprisingly common. Check your connection by attempting to open a page in your web browser or run the `curl` command in the terminal. Ensure your personal or organizational firewall is set up to allow connection to Criteo services. Here are the Criteo subnetworks to be whitelisted by region:

EMEA

APAC

Americas

178.250.0.0/21 185.235.84.0/22 91.212.98.0/24 91.199.242.0/24

2a02:2638::/32

74.119.116.0/22

199.204.168.0/22

177.73.128.0/21

2620: 100:a000::/44

116.213.20.0/22

182.161.72.0/22

2406:2600::/32

> 👍 Tip > > For best results, our recommendation is to **whitelist the ranges for all DCs** even if your server is located only in one of the regions. In some cases, connectivity issues can arise when persistent `HTTP/2` connection's termination command is either not issued properly by the server, or not correctly processed by the client. Typically, this results in a time-out from the endpoint. In such cases, turning off the `keep-alive` property of a connection may help. Here is an example for Python: ```python theme={null} s=requests.session(), s.keep_alive = False; .... /// add a parameter into requests: headers={'Connection':'close'}, req=requests(url, headers) ... ``` *** ### Incorrect request URLs If you are using variables or path parameters with your request, make sure that the final address is structured correctly. Variables lacking initialization can result in the response code `404`. *** ### Transient Issues Transient issues can be resolved by properly implemented retry mechanisms, such as [the exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) technique. *** ### Consent issues Usually, if the advertiser hasn't given a consent to your app, you will get an error in `4xx` range. In order to perform a quick check whether an advertiser has given consent to the app, you can query the `[/retail-media/accounts](/criteo-apis/docs/accounts-endpoints)` and see if it returns the advertiser ID that you expected. *** ### Implementation errors If the request is not formed according to the specification or an invalid request header is provided, the server will respond with an error in the `400` code series. If you are using variables or path parameters with your request, this would require making sure that the raw request is in expected format. To get more details on the next steps, you can turn on `verbose output` of your application. Here is how to turn the debug mode on for the Python3 *requests* library: ```python theme={null} import requests import logging # Enabling debugging at http.client level (requests->urllib3->http.client) # you will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA. # the only thing missing will be the response.body which is not logged. try: # for Python 3 from http.client import HTTPConnection except ImportError: from httplib import HTTPConnection HTTPConnection.debuglevel = 1 logging.basicConfig() # you need to initialize logging, otherwise you will not see anything from requests logging.getLogger().setLevel(logging.DEBUG) requests_log = logging.getLogger("urllib3") requests_log.setLevel(logging.DEBUG) requests_log.propagate = True requests.get('https://httpbin.org/headers') ``` See the next section to understand which additional information is helpful when submitting an investigation request to Criteo. *** ### Server bugs If you are getting an error in the `500` series consistently, this could indicate an issue on the Criteo server-side. You can always check the latest service availability status by visiting [this page.](https://status.criteo.com/) If the status page does not explain your issue, please get in touch with your Criteo contact. In your post, please share the following information: * `RequestId` or `TraceId`, if available * Endpoint and its version, * App name or `app ID`, * Payload without any identifiers or sensitive information, * Response message without any identifiers or sensitive information. If your query contains private or sensitive information, we will strive to get back to you in a timely fashion via email. In this case, we will also need the advertiser ID, the full payload, and the full response message. *** ## Is The Issue Due to Data Latency? Data latency can also be mistaken for causing issues. Some metrics may have several hours of latency, while others may seem to have longer delays. The following table provides the delays ranges for different metric groups. Different types of activity and attribution data become available at different times after the event or sale: * **Onsite activity data** is typically available within **6–8 hours** of the event. * **Offsite activity data** is typically available within **24 hours** of the event. * **Initial attribution data** is available within **7–9 hours** of the sale. * **Final attribution data** is processed and posted within **74 hours** after the sale. * Please note that potential minor updates can occur up to **120 hours** before finalization ### Caching Logic * Reporting responses may be cached to balance availability and performance. * Reports with an end date of today or yesterday are cached for **1 hour**. * Reports with an end date older than yesterday are cached for **24 hours**. * The exact cache expiration time is provided in the `expiresAt` field of the /status response. ### Retention Reporting data is retained for a rolling **3-year period**. Data freshness guidelines on this page are not official SLAs and therefore maximum delay values are not guaranteed. They reflect **the 95th and 50th percentile latency based on the last two weeks of import data**. It is your responsibility to assess the precision-error trade-off of your application based on the snapshot of historical data provided above. Official SLAs will be shared at a later date. *** ## Is the Issue Caused by a Data Discrepancy? Whether you are building an aggregator service with Criteo as one of the sources or simply trying to compare the numbers in the Commerce Max/Yield [Analytics UI](https://help.retailmedia.criteo.com/kb/guide/en/introduction-to-analytics-BkpzEf9F7t/Steps/1020437) and the API, you may have encountered a situation where the reported numbers in the UI and API are not the same. As a first step, we need to make sure we have an apples-to-apples comparison by making sure our views are closely aligned. Please visit our [Reporting Diagnostic Guide](/retail-media/docs/reporting-overview-diagnostic-guide) for more insights into UI vs API reporting discrepancies. *** ### Dates Aligning the timezones and the date ranges in the API request body and the platform UI (whether Criteo Commerce Max/Yield or a third-party platform) will resolve the issue most of the time. *** ### Attribution scope The naming pattern provided on [the metrics page](/criteo-apis/docs/metrics-and-dimensions) will help you understand how you're comparing the data in different systems. Ask yourself: * `[AttributionModel]`: Am I comparing custom attribution sales or default attribution sales? * `[LookbackWindow]`: Am I selecting the same attribution lookback period? In general, the Criteo API allows you to retrieve all possible metrics, while Commerce Max/Yield Analytics module is more focused on the metrics that are deemed relevant to a specific account and its settings. *** ### Technical Due to the specifics of the billing mechanism, the cost data for the day immediately preceding the current day may be adjusted within a 5% threshold soon after midnight. Please take this into account when determining the refresh window of your connector. *** ### Compliance In some cases, the metrics could be updated several days after a click occurs. For example, this can happen after removing IVT (invalid traffic). *** # Authentication Source: https://developers.criteo.com/criteo-apis/docs/authentication ## Introduction * To get started with our APIs, use the endpoint below to generate an Access Token with your API credentials. * The access token is a Bearer token to be included in the Authorization Header of all API requests. * Multiple tokens may be generated, each valid for 15 minutes or 900 seconds. *** ## Endpoint ```http theme={null} https://api.criteo.com/oauth2/token ``` If you receive a `401 Unauthorized` HTTP status code, it means your access token has expired. Generate a new access token to continue making requests. *** ## Parameters

Parameter

Description

client\_id

Set up your API credentials through our Developer Portal

client\_secret

Set up your API credentials through our Developer Portal

grant\_type

Must be client\_credentials or authorization\_code

For more info, check [OAuth App Implementation](/criteo-apis/docs/oauth-app-implementation). *** ## Generate an Access Token * This endpoint generates a new access token using your API credentials ```http theme={null} https://api.criteo.com/oauth2/token ``` ### Sample Request ```bash theme={null} curl -X POST "https://api.criteo.com/oauth2/token" \ -d 'client_id={client_id}' \ -d 'client_secret={client_secret}' \ -d 'grant_type=client_credentials' ``` ### Sample Response ```json theme={null} { "access_token": "<TOKEN STRING>", "token_type": "Bearer", "expires_in": 900 } ``` *** # Authorization Requests Source: https://developers.criteo.com/criteo-apis/docs/authorization-requests Advertisers must grant access to apps or integrations built with the API through an authorization request, with different permission levels available such as read-only or manage access. Advertisers can manage and revoke access through the consent dashboard. ## Introduction Before advertisers can start using an app or integration built with the API, they must grant it access through an authorization request. All apps need to send an authorization request to advertisers to read or manage actions on their behalf. fb32a85 api_consent_grant_rm *** ## Consent Granting Steps * On the Developer Dashboard, app developers set up the application, select the necessary permissions (domains), and activate the app. Once completed, the API app will need access to an account to use API endpoints. The developer will generate a consent URL and share it with the advertiser to request consent. * Advertisers choose which portfolios to grant or deny access. The following roles can grant or deny access: * Admin, * Business Managers, * Technical Managers. * The consent URL redirects the advertiser to the Criteo consent dashboard. * Log in using your Criteo credentials, and you'll be redirected to the `Access request` page. Here, consent granters can see the organization and API application requesting consent, the requested permission level, and the accounts they can grant access to. 8c96e00 image * Advertisers with the appropriate role select the account(s) and click "Approve" to grant the API app access. * Once approved, the API application can access the account via the endpoints. *** ## Types of Permissions Each app requests different permissions based on its purpose, linked to campaign aspects like Audiences, Budgets, Creatives, or Analytics. * **Read-only**: Grants access to view an advertiser’s data or campaign details without making changes. For example, an app that generates campaign reports. * **Manage**: Allows an app to modify campaigns, ad sets, or ads. For example, an app that automates CPC settings or uploads a Contact List. The access provided by each permission type depends on the application's requested domains.

Application

No access

Read

Manage

Analytics

Your application will not have

access to any of the retail

media analytics endpoints.

Your application will have access to retrieve reporting data using the retail media analytics endpoints.

Audiences

Your application will not have access to any of the retail media audience endpoints.

Your application will have access to retrieve audiences and make calls to GET endpoints only.

Your application will have access to all audience endpoints, which includes both GET and POST endpoints.

Campaigns

Your application will not have access to any of the retail media campaign management endpoints. This includes all campaign and line-item management features, balances, catalogs and creatives.

Your application can only retrieve campaign man agent details. This includes GET endpoints only.

Your application will have access to all campaign management endpoints, which includes all GET and POST endpoints.

*** ## Managing and Revoking Access The **consent dashboard** also lets advertisers view all apps with granted access, including the specific portfolios, permissions, and access dates. Access can be revoked by Admins, Business Managers, or Technical Managers for the Retail Media platform, following a process similar to granting consent. 1ad095f image *** # Bulk Calls Source: https://developers.criteo.com/criteo-apis/docs/bulk-calls This page describes how to perform bulk calls towards Criteo Retail Media API ## General Our "Reporting" endpoints allow for bulk operations. Specifically, through the two following endpoints:

POST

/reports/campaigns

POST

/reports/line-items

You will be able to send us several `CampaignIds` or `LineItemIds`, with a **maximum of 50 IDs per call.** To do so, please use the following attributes and terminology in one or the other endpoint (example below for the `POST` `/report/campaigns` endpoint, the same applies to the line-item endpoint): When requesting a single ID then use: `"id": "CampaignId1"` OR When requesting several IDs then use `"ids": ["CampaignId1", "CampaignId2", ..., "CampaignIdn"]` **Important** * Please make sure to **not use `id` and `ids` in the same call**, as this will lead to an invalid request. * There is a **100,000-row limit** for report output to keep in mind when making a bulk report request. *** ## Error Codes When sending more than 50 IDs, you will get the following `400 Bad request` HTTP Response: ```json theme={null} { "errors": [ { "code": "exceeded-ids-cap", "title": "Requests are capped for 50 unique ids, 51 were provided", "type": "validation", "traceId": "aa47dd83-8ca9-4a79-a179-ad5be6932ff1", "instance": "/api/v1/reports/line-item", "detail": "ids Requests are capped for 50 unique ids, 51 were provided (Value: \"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51\")", "source":{ "ids": "data/attributes/ids" } } ] } ``` This Contains: * Error code: `exceeded-ids-cap` * Error title: `Requests are capped for 50 unique ids, {count of ids requested} were provided` * Error Type: `validation` * A traceId: `aa47dd83-8ca9-4a79-a179-ad5be6932ff1` * Instance: the report requested (here `/api/v1/reports/line-item`) * Detail: Title with a list of requested IDs * Source: The parameter that caused the error (IDs in this case) *** # Get connected to the API Source: https://developers.criteo.com/criteo-apis/docs/connect-to-the-api ## Unlock the power of Criteo with our accessible APIs! Welcome to Criteo API! We're excited to offer our valued clients easy access to our powerful tools. In this documentation, we will walk you through every step to help you launch your Criteo API journey with confidence. Get started by registering your API developer account. Learn how to register your organization for a personalized API experience that aligns with your goals. Follow our guide to create and configure your Criteo API application, tailored to meet your business needs. Secure your authentication credentials and start using the Criteo API. # Consent URL Generation Source: https://developers.criteo.com/criteo-apis/docs/consent-url-generation ## Overview The Criteo API allows you to build custom apps that help the world's advertisers grow their businesses. In order for your app to function, your users will have to **delegate permissions** for one or more of the Criteo advertisers that they oversee. To do this, you will need to direct the user to a unique consent delegation page. The URLs for this type of page can be generated in one of two ways: manually from your Criteo App page, or programmatically using a cryptographic key. Both methods are described below. In this guide, we assume you have completed all the steps in the API application setup section, and you already have your application tokens. *** ## Generate Consent URL ### Client Credentials For client credential application, once you have logged in to the [ Criteo Partners Portal](https://partners.criteo.com/), find your application under `My apps` and navigate to your `Application details` page. fbfdafc image At the top of your `App` page, you will see a `Generate new URL` button. Click the button to generate a single consent URL which can be easily copied to your clipboard. 614681e consenturl The consent URL has two query parameters: ```http URL theme={null} https://consent.criteo.com/request?nonce=&hmac= ``` Each button click will generate a new URL. A fresh consent URL must be generated whenever a new authorization is needed from the advertiser. **Consent URL Expiration** The consent URL expires **30 days** after creation. It is valid for a single use, meaning once it has been used to grant consent, it cannot be reused for future authorizations. Share the consent URL with an **admin or business manager** of the advertiser account you need access to. The user will be redirected to the Criteo's consent portal to approve your API application access. For more details, consent granters should follow the instructions provided on the [Authorization Request page.](/criteo-apis/docs/authorization-requests) ### Authorization Code Generating a consent URL for authorization code applications requires a separate process. This option is not available under the `Application details` page. For guidance on generating the consent URL, refer to the instructions for the [Authorization Code](/criteo-apis/docs/oauth-app-authorization-code#21---consent-url-creation) application setup. *** ## Generate Consent URLs Programmatically To generate consent URLs dynamically, you need a public and private key pair for signing the URLs. To obtain this key pair, you must register a callback URL to receive confirmations. Details on the callback process are covered in a later section. Log in to the [Criteo Partners Portal](https://partners.criteo.com/) and navigate to your app page by selecting your app in the `My application details` section. Scroll to the `Connector Parameters` section and click `Create a new connector`. You will be prompted to enter a callback URL. After registration, the callback URL can be modified at any time, while the associated key pair remains the same. 39e9cb6 image Upon completion, your browser will download a `.txt` file containing your public and private key pair. **Signing Keypair Generation** The private signing key is shared only once when you register a callback URL. Please ensure to store it securely. If you lose your private key, you can delete and re-register your callback URL to obtain a new one. * With the signing key pair, you can programmatically generate a consent URL using the **HMAC-SHA512** hashing algorithm to create a `signature`. The consent URL has the following structure and parameters: ```http URL theme={null} https://consent.criteo.com/request?key=×tamp=<UNIX timestamp in seconds>&state=&redirect-uri=&signature= ```

Parameter

Description

key

Your public signing key

timestamp

The UNIX timestamp of when your URL was generated, in seconds

state

An arbitrary string to be included in the consent callback (e.g., the User ID of your app user)

redirect-uri

The URL to redirect the user to after consent delegation

signature

The HMAC-SHA512 hashed query string of the previous four parameters, in order

The `signature` is created by hashing the following string using the `key`, `timestamp`, `state`, and `redirect-uri` values: ```http URL theme={null} ?key=×tamp=<UNIX timestamp in seconds>&state=&redirect-uri= ``` Code examples for generating a Consent URL can be found below: ```javascript JavaScript theme={null} const sha512 = require('js-sha512').sha512; function generateConsentURL(publicSigningKey, signingSecret, redirect, state){ const timestamp = Math.round(Date.now() / 1000); const query = `?key=${publicSigningKey}×tamp=${timestamp}&state=${state}&redirect-uri=${redirect}`; return `https://consent.criteo.com/request${query}&signature=${sha512.hmac(signingSecret, query)}`; } const res = generateConsentURL('public key', 'private key', 'https://example.com/app-landing-page', 'userID'); console.log(res); ``` ```cs C# expandable theme={null} using System; using System.Text; using System.Security.Cryptography; /* Enter your public signing key and signing secret in between the quotations below. You can also choose to modify your redirect URL (where your consent giver will be redirected too after they accept your consent request). You can also choose to pass in parameters inside the state object. */ public class Program { public static void Main() { // MODIFY THIS var publicSigningKey = ""; var signingSecret = ""; var redirectUri = "https://developers.criteo.com/"; var state = "userID"; // long timestamp = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(); var signature = createSignature(publicSigningKey, timestamp, state, redirectUri, signingSecret); Console.WriteLine(generateUrl(publicSigningKey, timestamp, state, redirectUri, signature)); } public static string createSignature(string publicSigningKey, long timestamp, string state, string redirectUri, string signingSecret) { var message = $"?key={publicSigningKey}×tamp={timestamp}&state={state}&redirect-uri={redirectUri}"; return HmacUtil.Sign(message, Encoding.UTF8.GetBytes(signingSecret)); } public static string generateUrl(string publicSigningKey, long timestamp, string state, string redirectUri, string signature) { return $"https://consent.criteo.com/request?key={publicSigningKey}×tamp={timestamp}&state={state}&redirect-uri={redirectUri}&signature={signature}"; } } public static class HmacUtil { public static string Sign(string message, byte[] signingKeyBytes) { using (var hmac = new HMACSHA512(signingKeyBytes)) { var hashedMessage = hmac.ComputeHash(Encoding.UTF8.GetBytes(message)); var stringBuilder = new StringBuilder(); foreach (var value in hashedMessage) { stringBuilder.Append(value.ToString("x2")); } return stringBuilder.ToString(); } } } ``` *** ## Consent Delegation Callback After the user completes the Consent Delegation flow, an HTTP callback will be sent to the registered URL. The `POST` body will include a `Type` field, indicating whether the consent was successful (`ConsentGranted`) or unsuccessful (`ConsentDenied`). For a `ConsentDenied` callback, `AcceptedScopes` will be an empty array. **Callback Body Update** `CriteoService` values have been updated for consistency. Possible values are `MarketingSolutions` and `RetailMedia`. ```json theme={null} { "Type": "ConsentGranted", "Data": { "Key": "971062d8161ba4ef8f78f3201a6f361f", "Timestamp": 1614366053, "State": "", "ApplicationId": 2, "ApplicationName": "Test App", "RequestedScopes": [ { "AccessLevel": "Read", "Domain": "Analytics", "CriteoService": "MarketingSolutions" } ], "AcceptedScopes": [ { "AccessLevel": "Read", "Domain": "Analytics", "CriteoService": "MarketingSolutions" } ], "Advertisers": [ { "Id": "12345", "Name": "Example Advertiser" } ] } } ``` For Marketing Solutions apps, shared entities are listed under `Advertisers`, while for Retail Media apps, they are under `Accounts`. The callback request includes an HTTP header named `x-criteo-hmac-sha512`, which contains the `HMAC-SHA512` hash of the callback request body. Use your app's signing secret to validate the request's integrity and authenticity. **Callbacks only for programmatically generated URLs** Callbacks are sent only for dynamically generated consent URLs. You will not receive a `POST` when user consent is provided through a link generated directly from the Developer Dashboard.. *** ## User Redirection Once the Consent Delegation is complete, the `POST` request to the callback URL and user redirection to the redirect URI occur in sequence. The user is not redirected until the callback attempt resolves. If the first callback attempt fails, it is retried up to two more times before redirecting the user. After three failed attempts, the user is redirected, and Criteo logs the callback error. ***
# Create Your API Application Source: https://developers.criteo.com/criteo-apis/docs/create-your-app ## Introduction Once you have [created your organization](/criteo-apis/docs/create-your-organization), you can access the `My Apps` page to begin creating your application. This page is also where you will manage your Criteo API applications. To start creating your API application, click the `Create a New App` button in the top right corner of the page. This will initiate the application creation process. *** ## Step 1 - Create application ### App details * Provide a name for your application, along with an optional description and app image. Please ensure that **your application has a clear and identifiable name**, as this greatly assists our teams in providing faster and more effective support during troubleshooting. API applications cannot be deleted. Once this step is completed, your application will appear in the "My Apps" dashboard. ### Authentication method * Criteo’s API supports two OAuth authentication methods: [Client Credentials](/criteo-apis/docs/oauth-app-client-credentials) and [Authorization Code](/criteo-apis/docs/oauth-app-authorization-code). Each method has its own advantages, so before proceeding, we strongly recommend reviewing which authentication method is best suited to your application’s needs. 2ce3350 auth_methods2 **Trying to decide which OAuth method is right for you?** If you're unsure which authentication method to use, take a look at our [OAuth App Implementation](/criteo-apis/docs/oauth-app-implementation) guide for an overview of each authentication method. *** ## Step 2 - App activation Once you've selected the appropriate authentication method, proceed to choose the service you’ll be using. ### Services * Choose the Criteo service your API application will interact with: * **C-Growth and Marketing Solutions** * **C-Max and Retail Media** 6c1fa6d portal _step3_1 *** ## Step 3 - Authorizations ### Domains 1. Choose the domains that define the permission levels your application will need. These domains determine which endpoints your application can access. 2. After selecting the appropriate domains, click `Activate App`. Once activated, you won’t be able to change the name, description, image, or app scope. It should also be noted that your Domain Scopes operate under a different permission model than the UI. This is by design, so the API won’t mirror the UI’s User Profile permissions. If you’re working with both, it’s important to account for that distinction. *** ### Retail Media Domains

Domain

Description

Authorization Types

Accounts

Manages permissions to endpoints responsible for describing accounts' entities, with their properties and relationships, like parent/child accounts

No access / Read / Manage

Analytics

Manages permissions to generate reporting data for campaigns & line-items, considering desired list of dimensions & metrics

No access / Read

Audiences

Manages permissions to check/manage audiences available to campaigns

No access / Read / Manage

Balances

Manages permissions to endpoints responsible for configuring and retrieving balance entities, which define spending limits applied across campaigns linked to an account.

No access / Read / Manage

Billing

Manages permissions to generate billing data for campaigns & line items for a retailer partner

No access / Read

Campaigns

Manages permissions to endpoints responsible for campaigns management, including line-items, balances and creatives

No access / Read / Manage

Catalog

Manages permissions to check/manage products catalogs

No access / Read / Manage

`Account Manage`, `Balance Manage` and `Billing Read` permissions must be first requested to be activated by your Criteo contact to appear as options when creating your apps. Note that they cannot be added to existing applications. e78d65c9adb193a529a09e1b7fae330694c8941d1cd8a4d3d0af11fde3d33824 Google_Chrome_2025 01 28_11.46.31 Once you activate your application, you will be redirected to your application details page to complete the final steps of your application configuration. *** # Create Your Organization Source: https://developers.criteo.com/criteo-apis/docs/create-your-organization ## Introduction This article will guide you through creating an organization, a mandatory step to access the Partner Portal.\ You will be redirected to the `Create an Organization` screen after setting up your Criteo account. *** ## Create your organization a156da1 organization_registration * **Company Name** * Enter your company name, country, type, and email. We will use this email to send important Criteo API updates, including new features and critical changes. Please ensure that your company has a clear and identifiable name, as this greatly assists our teams in providing faster and more effective support during troubleshooting. * **Other Optional Details** * You can also provide your website and a brief company description. This helps us get to know your business better, ensuring we can offer more tailored services. Once your organization is registered, you will be redirected to the`My Apps` page in the Partner Portal. A confirmation email will be sent to verify your email address. After confirming, you'll be able to start building your first API application. Please note that by proceeding to this step, you acknowledge and agree to our [API Terms and Conditions](/criteo-apis/docs/criteo-api-terms-and-conditions). Do you need more information about company types? While this won't impact your experience in the developer portal, it helps us provide you with better support. Here are some details: ✔ Advertiser/Brand – You are a marketer from a retail, travel, or classifieds company, looking to use Criteo APIs on behalf of your own company. ✔ Agency – You work in a media agency and want to use the Criteo API for a Brand or an Advertiser. ✔ Inventory Supplier – You represent the supply side and want to use Criteo API for inventory-related activities. ✔ Data Supplier – Your business focuses on providing 1st or 3rd party audiences. ✔ Technology Company – You are part of the ad-tech ecosystem and plan to use Criteo APIs for services such as DCO, Marketing Dashboards, Measurement, or Brand Safety. ✔ Other – If none of the above categories apply to you. *** ## Creating Multiple Organizations If you need to create more than one organization, you can easily do so from your partner account. 1. Click on the organization button in the top-right corner of the `My Apps` screen. 2. A screen will appear where you can switch between different organizations. To create a new one, click on `Create an Organization`. 3. Your newly created organization will now appear in the list! ff76b44 createorg *** # Create Your Partner Account Source: https://developers.criteo.com/criteo-apis/docs/create-your-partner-account ## Process Overview This article will help you access your **Criteo Partner account**, giving you entry to the Partner Portal and other Criteo platforms. 1. To begin, log in via the [Criteo Partner Dashboard](https://partners.criteo.com/), **Criteo Login Required** Before creating your API application, you’ll need to log in to the Criteo Partner Portal using your **Criteo credentials**. If you don’t have credentials, please contact your Criteo account representative for access. 2. Login with your existing Criteo account, 3. After logging in, you will be redirected to the [Criteo Partner Dashboard](https://partners.criteo.com/). If the redirection fails, simply click on the Partner Portal link from your account screen. ***
# OpenAPI Specifications Source: https://developers.criteo.com/criteo-apis/docs/criteo-api-swagger As part of our [updated versioning policy](/criteo-apis/docs/versioning-policy), the **Preview** tier has been renamed to **Experimental**. The `/preview/` URL path remains available for backwards compatibility but `/experimental/` is the current name. ## Current specifications Direct links to the live OpenAPI specification files, organized by product and version. ### Retail Media | Version | URL | | ---------------- | ------------------------------------------------------------------------------------------------------------ | | 2026-07 (stable) | [open-api-specifications.json](https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json) | | Experimental | [open-api-specifications.json](https://api.criteo.com/experimental/retailmedia/open-api-specifications.json) | | 2026-01 | [open-api-specifications.json](https://api.criteo.com/2026-01/retailmedia/open-api-specifications.json) | | Preview (legacy) | [open-api-specifications.json](https://api.criteo.com/preview/retailmedia/open-api-specifications.json) | | 2025-10 | [open-api-specifications.json](https://api.criteo.com/2025-10/retailmedia/open-api-specifications.json) | | 2025-07 | [open-api-specifications.json](https://api.criteo.com/2025-07/retailmedia/open-api-specifications.json) | | 2025-04 | [open-api-specifications.json](https://api.criteo.com/2025-04/retailmedia/open-api-specifications.json) | | 2025-01 | [open-api-specifications.json](https://api.criteo.com/2025-01/retailmedia/open-api-specifications.json) | ### Marketing Solutions | Version | URL | | ---------------- | ------------------------------------------------------------------------------------------------------------------- | | 2026-07 (stable) | [open-api-specifications.json](https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json) | | Experimental | [open-api-specifications.json](https://api.criteo.com/experimental/marketingsolutions/open-api-specifications.json) | | 2026-01 | [open-api-specifications.json](https://api.criteo.com/2026-01/marketingsolutions/open-api-specifications.json) | | Preview (legacy) | [open-api-specifications.json](https://api.criteo.com/preview/marketingsolutions/open-api-specifications.json) | | 2025-10 | [open-api-specifications.json](https://api.criteo.com/2025-10/marketingsolutions/open-api-specifications.json) | | 2025-07 | [open-api-specifications.json](https://api.criteo.com/2025-07/marketingsolutions/open-api-specifications.json) | | 2025-04 | [open-api-specifications.json](https://api.criteo.com/2025-04/marketingsolutions/open-api-specifications.json) | | 2025-01 | [open-api-specifications.json](https://api.criteo.com/2025-01/marketingsolutions/open-api-specifications.json) | ### Commerce Grid | Version | URL | | ------- | -------------------------------------------------------------------------------------------------------- | | 2026-01 | [open-api-specifications.json](https://api.criteo.com/2026-01/commercegrid/open-api-specifications.json) | *** ## URL pattern All specification files follow the same URL structure: ```http URL theme={null} https://api.criteo.com/{version}/{criteo-service}/open-api-specifications.json ``` where: * `{version}`: Any stable version starting from `v2020-10` or higher (without the `v`), or `preview` / `experimental`. * `{criteo-service}`: * **`marketingsolutions`** for Marketing Solutions endpoints * **`retailmedia`** for Retail Media endpoints * **`commercegrid`** for Commerce Grid endpoints # Criteo API Terms and Conditions Source: https://developers.criteo.com/criteo-apis/docs/criteo-api-terms-and-conditions Version 2.0, March 2025 These Criteo API Terms and Conditions (“**API Terms**”) are an agreement between the person or legal entity detailed in your Criteo API account registration ("**you**", “**your**” or "**Partner**") and Criteo Technology SAS with an address at 32 rue blanche, Paris, France ("**Criteo**"), and relate to Your use of Criteo's Application Programming Interfaces ("**APIs**"). Criteo and Partner each may be referred to as a "**Party**", and together, the "**Parties**". Use of the APIs is conditional on your acceptance of these API Terms and is complementary to any services, data provision or any other agreement you may have with Criteo or with any Criteo Affiliate (“**Main Agreement**”). Should there be any conflict between these API Terms and the Main Agreement, the terms of the Main Agreement shall prevail. By clicking "**I confirm**" you are agreeing to these API Terms. If **Partner** is a corporate entity, by accepting these API Terms, you represent and warrant that you are authorized to legally bind Partner and enter into these API Terms on Partner's behalf. If you do not, or do not have authority to, accept these API Terms, you may not access and use the APIs. In consideration of the mutual promises contained in these API Terms and other good and valuable consideration, which the Parties acknowledge, it is agreed that: # 1. DEFINITIONS 1.1. In these API Terms, the following words and expressions shall have the following meanings unless the context requires otherwise: "**Affiliate**" means, in relation to a Party, any entity that directly or indirectly controls, is controlled by, or is under common control with that Party. "**API Terms**" means these terms and conditions, additional terms that may be subsequently and expressly agreed between the Parties and any terms, policies, exhibits or guidelines as made available by Criteo in relation to the APIs. "**Applicable Laws**" means all applicable laws, statutes, and regulations from time to time in force. "**Criteo Materials**" means all documents, information, items and material in any form, whether owned by Criteo or a third party, that are provided by Criteo to you in connection with the APIs. "**Data**" means all data made available via the APIs. "**Data Protection Laws**" means any and all applicable international, national, federal and state laws and regulations relating to data protection and privacy, including but not limited to: (a) the General Data Protection Regulation (“EU GDPR”), (b) the UK Data Protection Act (“UK GDPR”), (c) the California Consumer Privacy Act (“CCPA”) as amended by the California Privacy Rights Act of 2020, (d) the Virginia Consumer Data Protection Act (“VCDPA”), (e) the Colorado Privacy Act (“CPA”), (f) the Connecticut Data Privacy Act (“CTDPA”), (g) the Utah Consumer Privacy Act (“UCPA”), (h) the Oregon Consumer Privacy Act (“OCPA”), (i) the Texas Data Privacy and Security Act (“TDPSA”), (j) the Montana Consumer Data Privacy Act (“MTCDPA”), (k) Delaware Personal Data Privacy Act, (l) Iowa Consumer Data Protection Act, (m) Nebraska Data Privacy Act, (n) New Hampshire Data Privacy Act, (o) New Jersey Data Privacy Law, (p) the Korean Personal Information Protection Act (“PIPA”); each as implemented in each jurisdiction, and any amending or replacement legislation (or similar) from time to time. For the sake of clarity, Data Protection Law also includes all legally binding requirements issued by the competent data protection authorities i) governing the processing and security of information relating to individuals and providing rules for the protection of such individuals’ rights and freedoms with regard to the processing of data relating to them, ii) specifying rules for the protection of privacy in relation to data processing and electronic communications, or iii) enacting rights for individuals which are enforceable towards organizations with respect to the processing of their personal data, including rights of access, rectification and erasure. Any Data Protection Law listed herein only apply to the Partner to the extent this is provided for under the criteria set by law. "**Effective Date**" means the date you accept these API Terms. "**Intellectual Property Rights**" means any and all patent rights and inventions (whether patentable or not), design rights, copyright (including rights in computer software), database rights, trademarks, trade names, business names, domain names, and expertise. 1.2. Words in the singular shall include the plural and vice versa and use of any gender includes all genders. *** # 2. ACCOUNT REGISTRATION 2.1. In order to access and use the APIs, you are required to register an account with Criteo. You represent and warrant that the information provided at registration is true, accurate and current and you shall update Criteo in the event of any changes. 2.2. Criteo reserves the right to validate account registration information with you and you will cooperate with any reasonable request coming from Criteo. Furthermore, Criteo reserves the right to remove access to any part or all of the APIs, Data and/or your account after registration in Criteo's sole discretion at any time and for any reason. *** # 3. ACCESS AND USE OF THE APIS 3.1. Subject to your compliance with these API Terms, Criteo may make the APIs available to you as further detailed at [developers.criteo.com](/). Criteo may also make Criteo Materials available to you. You acknowledge that Criteo may modify, change or discontinue temporarily or permanently the APIs or Criteo Materials at any time. 3.2. You may use the APIs to develop, test and support "apps" and shall comply with the latest technical requirements and specifications Criteo may make available in writing from time to time. Depending on your use of the APIs, you may be required to enter into supplemental terms and conditions. 3.3. Your access to the Criteo developer dashboard will be regulated by a username and password. Your access to the APIs will be regulated by a client key and client secret or as otherwise detailed at [developers.criteo.com](/). You are responsible for the use and storage of your personal and confidential passwords and credentials and shall immediately notify Criteo in writing of any loss or involuntary disclosure. As between Criteo and you, you shall have all responsibility for all activities that may occur using your username and password. Criteo shall have no responsibility for any unauthorized use of your account. 3.4. Upon set-up and creation of your app, you shall select the relevant Criteo platform to which you require access, to whom access should be given (which may include yourself) and the functionalities to be made available in your app via the APIs. 3.5. API access and functionality are dependent upon approval of the relevant third party, as further detailed at [developers.criteo.com](/). Criteo shall facilitate an approval mechanism in relation to third parties but is not liable in relation to whether or not approval is granted, the extent of any such approval, or for any acts or omissions of any such third party. Should a particular third party later revoke or limit your access to their account, you shall promptly delete all Data relating to their account. 3.6. In accessing and using the APIs, you shall: 3.6.1. Use best efforts in limiting the number of calls made to the APIs;\ 3.6.2. Not conduct (either directly or indirectly) any stress tests (or similar) of the APIs;\ 3.6.3. Not compromise, break or circumvent any technical processes or security measures associated with the services that Criteo provides (including, without limitation, Criteo's own user interface solutions or platforms);\ 3.6.4. Not reverse engineer or otherwise derive source code, trade secrets or know-how in relation to the APIs, Criteo's services or technology;\ 3.6.5. Ensure that usage of the APIs is aligned with the declared purpose of your app(s);\ 3.6.6. Ensure that usage of the APIs is reasonable and not in excess of any guidance as may be made available by Criteo;\ 3.6.7. Access and use the APIs and Data only as permitted by, and on behalf of, the party that provided access to the Data being used or in accordance with the Main Agreement (“Permitted Use”);\ 3.6.8. Not disclose or otherwise permit access to any Data to any person or entity other than the party that provided you with access to the particular Data being disclosed.\ 3.6.9. You must ensure compliance with Criteo’s Advertising Guidelines (when submitting campaigns to Criteo) and/or Supply Guidelines (when providing inventory to Criteo) and/or [https://www.criteo.com/criteo-privacy-guidelines-for-clients-and-publisher-partners/](https://www.criteo.com/criteo-privacy-guidelines-for-clients-and-publisher-partners/), including by taking all reasonable steps to ensure that your clients, partners, and any third parties acting on your behalf comply with such guidelines. Criteo may, at its reasonable discretion, suspend or remove any campaigns or inventory it considers non‑compliant. 3.7. You shall use all reasonable legal, organizational, physical, administrative and technical measures, and security procedures to safeguard and ensure the security of the Data and to protect the Data from unauthorized access, disclosure, duplication, use, modification, or loss, including without limitation, the requirements contained set forth in Exhibit B. Furthermore, you shall implement technical and organizational measures as required by the Data Protection Laws to protect personal data (i) from accidental or unlawful destruction, and (ii) unauthorized loss, alteration, disclosure of, or access to the personal data (a “Security Incident”). In the event you suffer a Security Incident related to Data, you shall notify Criteo without undue delay and both Parties shall cooperate in good faith to agree and carry out such measures as may be necessary to mitigate or remedy the effects of the Security Incident. 3.8. Criteo reserves the right to audit your app and use of the APIs to ensure that it does not violate these API Terms. You agree to reasonably cooperate with any such inquiries made in relation to an audit and provide information as reasonably requested by Criteo. 3.9. Unless authorized by a separate agreement, you shall not make any public statements, including, without limitation, in promotional materials or sales collateral, stating or otherwise implying that you or your app has access to any Criteo partner, including, without limitation, ad inventory supply sources. 3.10. Criteo reserves all rights not expressly granted to you under these API Terms. *** # 4. INTELLECTUAL PROPERTY 4.1. Each Party remains sole owner of the Intellectual Property Rights it owned prior to the execution of these API Terms. Criteo is the sole owner of all Intellectual Property Rights in and to the APIs and Criteo Materials. Save where expressly stated, these API Terms shall not create any license in relation to Intellectual Property Rights of any party and in particular shall not grant Partner the right to use the trademark, trade name or logo of any other party, including any other Criteo partner. You shall not acquire any rights in the Data through these API Terms. 4.2. For the duration of these API Terms, Criteo grants to you a worldwide, royalty-free, non-transferable limited license to use the APIs in relation to your apps. 4.3. For the duration of these API Terms, you grant to Criteo (including Criteo Affiliates) a worldwide, royalty-free, non-transferable license to use, reproduce, distribute, adapt, modify, perform, display, publish, transmit, format, store and archive your trademarks and logos in relation to all materials and media promoting the APIs. Criteo shall seek prior authorization from you in relation to any press release using your trademarks or logos, such authorization not to be unreasonably withheld or delayed. *** # 5. TERM 5.1. These API Terms shall apply from the Effective Date until they are terminated in accordance with this section. 5.2. Either Party may terminate these API Terms on written notice to the other Party: (i) with immediate effect if the other commits a material breach of any of its obligations which cannot be remedied, or in the case of a remediable breach, fails to remedy it within 7 days of the date of receipt of a notice from the other specifying the breach and requiring it to be remedied; (ii) if a force majeure event occurs that has continued for a minimum period of one month; (iii) to the extent permitted by Applicable Laws in the event that either Party becomes insolvent, goes into liquidation, appoints an administrative receiver or analogous proceedings under relevant local law; or (iv) at any time for any reason upon 14 days' prior notice. 5.3. In case Partner is using the APIs in connection with Main Agreement, these API Terms shall be automatically terminated upon termination of the Main Agreement. 5.4. Upon termination of these API Terms, you shall immediately cease any use of the APIs and Data and promptly delete or return any Data and Criteo Materials to Criteo. 5.5. Expiration or termination (for any reason) of this these API Terms shall not affect any accrued rights or liabilities that either Party may then have, nor shall it affect any clause that is expressly or by implication intended to continue in force after expiration or termination, nor shall if affect any other agreements you may have with Criteo. *** # 6. CONFIDENTIALITY 6.1. "Confidential Information" means all non-public information disclosed by or for a Party in relation to these API Terms, including the APIs, Criteo Materials, and Data; and any information that a reasonable person would consider proprietary and confidential. Confidential Information does not include any information the receiving Party can demonstrate is: (a) already known by it without restriction; (b) rightfully furnished to it without restriction by a third party not in breach of any confidentiality obligation; (c) generally available to the public without breach of these API Terms; or (d) independently developed by it without reliance on such Confidential Information. 6.2. Except for the specific rights granted by these API Terms, the receiving Party shall not access, use, or disclose any of the disclosing Party's Confidential Information, and shall protect the disclosing Party's Confidential Information using at least the standard of care used to protect its own confidential information of like nature, but not less than reasonable care. The receiving Party shall ensure that its employees and contractors with access to such Confidential Information (a) have a need to know for the purposes of these API Terms and (b) have agreed to restrictions at least as protective of the disclosing Party's Confidential Information as these API Terms. Each Party shall be responsible for any breach of confidentiality by its employees and contractors. 6.3. A Party may disclose Confidential Information to comply with a court order or lawful requirement of a governmental agency, or when disclosure is required by operation of law (including disclosures pursuant to any applicable securities laws and regulations); provided that prior to any such disclosure, the receiving Party shall use reasonable efforts to: (a) promptly notify the disclosing Party in writing of such requirement to disclose; (b) cooperate with the disclosing Party in protecting against or minimizing any such disclosure or obtaining a protective order; and/or (c) otherwise limit the disclosure to the greatest extent possible under the circumstances. *** # 7. PRIVACY 7.1. You and your app must comply with all Applicable Laws, including without limitation that You shall use and disclose Data solely in accordance with applicable Data Protection Laws. 7.2. If you provide or have access to any identifying or personal data of any end user based on any use of or interaction with your app, you will (i) provide legally adequate privacy notices to such end user; (ii) obtain any necessary consent from the end user for the collection, use, transfer, and storage of such information; (iii) use and authorize others to access and use the information only for the purposes permitted by the end user; and (iv) ensure the information is collected, used, transferred, and stored in accordance with applicable privacy notice(s) and Applicable Laws. 7.3. The Parties further acknowledge and agree each party will process personal data received from the other party in their own right as separate and independent controllers/businesses for the Permitted Use. 7.4. You shall promptly notify Criteo if you can no longer comply with its obligations under these API Terms. You shall reasonably assist Criteo in meeting its obligations under Data Protection Laws. Both Parties have the right, upon notice, to take reasonable and appropriate steps to stop and remediate unauthorized use of personal data. You shall keep appropriate documentation on the processing activities carried out by you and on you compliance with Data Protection Laws. In the event of an investigation, proceeding, formal request for information or documentation, or any similar event in connection with a data protection authority in relation to use of Data under these API Terms, you shall promptly and adequately deal with enquiries from Criteo. 7.5. Transfers outside of EEA. To the extent the use of the Data involves the transfer or disclosure of personal data from the European Economic Area (EEA) to outside the EEA (either directly or via onward transfer) to any country or recipient which has not been recognized as ensuring an "adequate level of protection" under Data Protection Laws, the Parties shall comply with the conditions for transfer set out in Chapter V of the GDPR. The Parties shall comply with any other requirements for international data transfers set out in Data Protection Law. 7.6. Data Protection Officers. Criteo’s data protection office may be reached at: [dpo@criteo.com.](mailto:dpo@criteo.com.) 7.7. Data Retention. In respect of any Data provided hereunder, and unless otherwise stipulated in the Main Agreement or in your agreement with the party that provided you access to the Data being used, you represent and warrant that you will destroy or otherwise render unusable such Data within 30 days of receipt. *** # 8. WARRANTIES; INDEMNIFICATION 8.1. THE APIs, CRITEO MATERIALS AND DATA ARE PROVIDED "AS IS" AND CRITEO HEREBY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY OR OTHERWISE. CRITEO SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT, AND ALL WARRANTIES ARISING FROM COURSE OF DEALING, USAGE OR TRADE PRACTICE. CRITEO MAKES NO WARRANTY OF ANY KIND THAT THE API CRITEO MATERIALS AND DATA, OR ANY PRODUCTS OR RESULTS OF ITS USE, WILL MEET YOUR OR ANY OTHER PERSON'S REQUIREMENTS, OPERATE WITHOUT INTERRUPTION, ACHIEVE ANY INTENDED RESULT, BE COMPATIBLE OR WORK WITH ANY SOFTWARE, SYSTEM OR OTHER SERVICES, OR BE SECURE, ACCURATE, COMPLETE, FREE OF HARMFUL CODE, OR ERROR FREE. 8.2. Each Party warrants and represents that it has the right, power and authority to enter into these API Terms and perform its obligations as set out herein. 8.3. You warrant and represent to Criteo that: (i) the use, distribution, publication, adaption, modification, performance, display, transmission, formatting or storing of any Intellectual Property Rights pursuant to these API Terms will not infringe upon or violate any third-party rights, or cause any third-party payments to become due; (ii) you shall not, nor shall you allow any third party to, inject any software viruses, worms, Trojan horses or other harmful computer code into Criteo's systems or otherwise intentionally interfere with or disrupt the integrity or performance of Criteo's services more generally; (iii) any information provided under these API Terms is true, accurate, complete and current; and (iv) you will abide by Applicable Laws and Data Protection Laws at all times. 8.4. You agree to hold harmless, indemnify, and defend Criteo, its Affiliates, and its and their respective officers, directors, shareholders, agents, employees, licensees, successors and assigns against any and all damages, penalties, losses, liabilities, judgments, settlements, awards, costs, and expenses (including reasonable attorneys' fees and expenses) arising out of or in connection with any third-party claims, assertions, demands, causes of action, suits, proceedings, or other actions, whether at law or in equity ("Claim(s)") to the extent any Claim (i) arises out of your breach or alleged breach of these API Terms or (ii) relates to use of your app(s). You shall not make any settlement without Criteo's written consent (such consent not to be unreasonably delayed, conditioned or withheld). *** # 9. LIMITATION OF LIABILITY 9.1. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, NEITHER PARTY SHALL BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES IN CONNECTION WITH THESE API TERMS, EVEN IF SAID PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. FURTHERMORE, NEITHER PARTY SHALL BE LIABLE FOR ANY LOSS OF PROFIT, LOSS OF OR CORRUPTION TO DATA, DAMAGE TO REPUTATION OR GOODWILL OR LOSS OF OPPORTUNITY OR CONTRACT. 9.2. Neither Party shall have any liability for any failure or delay resulting from any event, beyond the reasonable control of that Party including, without limitation fire, flood, insurrection, war, terrorism, earthquake, power failure, civil unrest, explosion, embargo, strike, or any force majeure event. 9.3. For the avoidance of doubt, nothing in these API Terms excludes or limits either Party's liability for fraud, gross negligence, death or personal injury or any other matter to the extent such exclusion or limitation would be unlawful. 9.4. To the maximum extent permitted by Applicable Laws, Criteo's liability under these API Terms, for whatever cause, whether in contract or in tort, or otherwise, will be limited to direct damages and shall not exceed the amount of 10,000 United States Dollars. *** # 10. COMPLIANCE 10.1. Each Party warrants that neither it nor any Affiliates, officers, directors, employees, and agents is the subject of any sanctions administered by the Office of Foreign Assets Control of the U.S. Department of Treasury, the European Union, or any other applicable sanctions authority. Each Party agrees to perform its obligations hereunder in compliance with all embargoes, sanctions and export control regulations of the United States, France, the United Kingdom, and any applicable jurisdiction, as well as with all applicable anti-corruption laws, anti-terrorist financing legislation, and anti-money laundering laws. *** # 11. MISCELLANEOUS 11.1. Criteo reserves the right to modify these API Terms at any time. Updates to these API Terms are effective as soon as they are available at developers.criteo.com. They shall automatically apply to your continued use of the APIs. 11.2. These API Terms, including any additional terms that may be subsequently agreed to between the Parties and any terms, policies, exhibits or guidelines as made available by Criteo in relation to the APIs, constitute the entire agreement between the Parties and shall supersede any and all other prior understanding, commitments, representations or agreements, whether written or oral, between the Parties regarding the subject matter herein unless it has been expressly stipulated that such agreement shall prevail. 11.3. If any provision of these API Terms shall be found by any court or administrative body of competent jurisdiction to be invalid or unenforceable, that provision will be limited or eliminated to the minimum extent necessary so that these API Terms will otherwise remain in full force and effect and enforceable. 11.4. These API Terms may be made available in various language versions. However, in the event of any dispute between different language versions of these API Terms, the English-language version shall prevail. 11.5. In no event will any delay, failure or omission (in whole or in part) in enforcing, exercising or pursuing any right, power, privilege, claim or remedy conferred by or arising under these API Terms or by law, be deemed to be or construed as a waiver of that or any other right, so as to bar the enforcement of that, or any other right, power privilege, claim or remedy, in any other instance at any time or times subsequently. 11.6. Unless specified otherwise in these API Terms, no third party shall have any rights or obligations under the API Terms. 11.7. The Parties shall be independent contractors under these API Terms, and nothing herein will constitute either Party as the employer, employee, agent, or representative of the other Party, or both Parties as joint venturers or partners for any purpose. Nothing in these API Terms shall permit either Party to legally bind the other Party to any other agreement. Nothing in these API Terms shall create any exclusivity between the Parties in relation to its subject matter. 11.8. These API Terms shall be governed by and construed in accordance with the laws of France without regard to its conflicts of laws principles, and the Parties submit to the exclusive jurisdiction of the courts of Paris, France in respect of any dispute or matter arising out of or connected with these API Terms. 11.9. You may not assign these API Terms or any of Your rights and obligations hereunder, in whole or in part, without Criteo's prior written consent. Any purported assignment, delegation, or other transfer in contravention of this section is void.
These API Terms shall be binding upon and inure to the benefit of the Parties hereto and their successors, representatives, and permitted assigns. *** # EXHIBIT B – IT SECURITY POLICY The following schedule describes the security requirements and associated controls that must be maintained by Partner (including its subcontractors involved in the Data processing, if any) throughout the term of the API Terms. ## Security Governance and Management Partner must maintain an appropriate Security Management System, inclusive of other industry known privacy and security best practices and maintain appropriate security controls. This will include appropriate documentation (security policies, processes, guidelines, standards, configuration standards and associated security controls) to assure adequate protection of Data throughout the Data processing lifecycle, for the term of the API Terms. ## Security Roles and Responsibilities Partner will maintain defined responsibilities for security within their organization with a named contact, and escalation levels, to support Criteo security requirements, including answering general security questions, if required. ## Security and Privacy Awareness Training Partner shall ensure that it is sufficiently trained (at least annually) on necessary security and privacy content and supporting procedures. Such training shall include phishing simulations on a regular frequency. ## Security Assessments Criteo shall have the right, with thirty (30) business days advance notice, to perform security assessments related to Partner and associated use of Data. Criteo shall also have access to information security assessments performed by the Partner and/or any third parties on the use of Data. Additionally, Criteo may request an updated information security compliance report (“Compliance Report”) every twelve (12) months, or earlier if it reasonably considers there have been substantial changes in security requirements, to enable Criteo to assess ongoing compliance with Partner´s information security requirements set herein. If Criteo considers that the Compliance Report is not satisfactory, Partner will communicate, in timely manner, any additional information required by Criteo to demonstrate compliance with this IT Security Policy. ## Security Process Compliance Partner must report detected security incident with one (1) working day delay from the first discovery of the incident on detection to Criteo’s service desk and their assigned management and comply with Criteo security policies, processes and procedures. ## Security Breach Reporting Any detected security breach impacting Data must be immediately reported to Criteo and no more than one (1) working day after detection, with a detailed formal security incident report provided no later than two (2) working days after detection. All formal security incident reports must include root cause analysis and detailed forensic and log information, including total quantity of personal data records impacted, if applicable. ## Physical and Environmental Security Controls Partner will maintain appropriate physical and environmental security controls to protect against data security risks and to protect the confidentiality, the integrity and the availability of Data if processed, transmitted or stored within their premises. All such controls will be aligned to applicable industry, operational and security best practices protecting against physical and environmental security risk, including physical access controls, physical security monitoring and environmental protections against power disruptions, fire hazards, and related operational risks. ## Access Control Partner shall ensure that it maintains the following best practice controls for the accounts in charge of maintaining the activities within the API Terms with all granting of accounts based on defined roles and permissions: a) All accounts and permissions granted for the express use in relation to Data processing; any use sharing of granted accounts is a security breach unless expressly approved by Criteo.\ b) All accounts must apply appropriate password complexity, length and special characters. Multi-factor authentication (“MFA”) should be applied.\ c) Any compromise of a granted accounts or permissions must be reported as a security incident to Criteo’s service desk on detection.\ d) Use of service accounts must comply with Criteo’s application standards.\ e) All use of credentials and keys related to Criteo applications and Data must comply with applicable company configurations and standards. ## Device Security The following device security controls must be maintained throughout the duration of the API Terms where Partner utilizes its own devices: a) Device must be centrally managed by appropriate management systems to support active software and hardware security management.\ b) Antivirus or Endpoint Detection and Response (“EDR”) (in this case, the EDR should include an antivirus) must be maintained on all devices with 24x7x365 security monitoring and security response with appropriate controls to actively update and protect against most recent malware threats and risks.\ c) Device operating systems must be hardened with appropriate security configuration baselines maintained and regularly deployment of security updates deployed aligned to known operating system patching cycles.\ d) Device data storage and backups must be maintained, applied and tested on an appropriate frequency to ensure availability of data in response to data loss, ransomware.\ e) Data stored on devices must be appropriately encrypted. ## Network Security The following network security controls must be maintained if Partner accesses Criteo applications: a) An appropriate tiered and segmented network architecture must be maintained and monitored for production network.\ b) All traffic across internal or external Partner networks must be encrypted through secure protocols.\ c) Networks (WAN, LAN and WIFI) must be appropriate designed and maintained ensuring appropriate authentication and encryption applied. All networking components, appliances, devices and software must be current and patched appropriately.\ d) In the production network, network and network security must be monitored with appropriate levels of security event and logging present to support effective security incident detection and response.\ Data Backup and Storage: Partner will maintain appropriate data storage and backup routines and activities to ensure data availability, integrity and data recovery on an appropriate frequency to minimize data loss. ## Application Security and Secure Development Lifecycle (SDL) Security The following security controls are applicable if Partner supports processing, transmission or storage of Criteo Data within its service platforms or applications:\ a) Appropriate SDL controls must be maintained for software development aligned to industry recognized standards.\ b) Software must be deployed through controlled SDL with appropriate security and quality assurance tests applied before deployment into production.\ c) Software repositories must be secure through authenticated access controls applied to user and service accounts with code scans to ensure security monitoring and automated updates.\ d) Penetration Testing must be applied on a minimum of an annual frequency with summary findings and identified corrective actions provided to Criteo if requested. ## Vulnerability and Patch Management Partner will maintain appropriate controls for regular vulnerability management scans applied to any applications processing, transmitting or storing Data. Such scans should be a least monthly to identify critical vulnerabilities and support effective mitigation. Patch Management controls must be in place and automated to effectively support security and version updates to proactively protect Data. ## Business Continuity Management (BCM) System Partner, if processing, transmitting and/or storing Data, must maintain an appropriate Business Continuity Management System with supporting continuity and disaster recovery process and controls. Such activities must be appropriately maintained and tested with clear define roles, responsibilities and escalation protocols. # Manage Your Account, Organization and Apps Source: https://developers.criteo.com/criteo-apis/docs/developer-accounts-organizations-apps This section provides guidance on managing your Developer Account, Organization, and Apps once created. ## Manage your Developer Account ### Update account information If you need to update your account information, you can do so by logging into the Criteo Partner Portal. This guide will walk you through the steps to edit your account details. 1. Click the user icon in the top right corner of the page to access your account information. ab56229 image 2. You can edit your first name, last name, and display name on this page. If needed, you can also change your password. To change your password, you will be required to provide your current password for verification. Managing user's contact information in the Criteo partner portal. ### Request to delete an account If you wish to delete your Criteo account because you no longer work with Criteo, please contact your Criteo representative. *** ## Manage your Organization ### Overview From the main menu, you can manage your apps, teams and settings. We detail each of those in the sections below. 9d5bc81 image ### Managing team members You can invite multiple users to access your API application, allowing your development team members to collaborate. 1. Navigate to `Teams` to view all users with login access to the application. f273286 image 2. Under `Members`, click the plus (**+**) icon to open the form and invite new members. Enter the email addresses of the users you want to invite. 4c13aaa image Ensure you don't lose access to your API application. If a team member leaves your organization, ensure that at least one other member of your team has access to the Criteo API application. *** ### Settings 1. To update your organization's settings, click the top left corner of the page menu and select `Settings`. 2. Click the pencil icon to edit your current organization information, then save your changes. Capture d’écran 2020-10-02 201104.png 3. To update information for another organization: 1. Return to the My Apps screen, 2. Select the organization from the organization menu in the top right corner, 3. Change the Organization, 4. Follow steps 1 and 2. *** ## Manage your App This section explains how to edit your app information **before publication**. 1. Select an application you have previously created from your `My Apps` space. myapp1.png 2. Click "Edit" on the right side of the app name. myapp2.png 3. You can update the app name, description, or image. Note that these changes are only possible before the app is published. app3.png *** # Escalation Guidelines Source: https://developers.criteo.com/criteo-apis/docs/escalation-guidelines This page indicates which information to provide if you need to contact Criteo for assistance regarding the Retail Media API ## What to provide If you have an API issue that you cannot solve relying on the available documentation, please use the following requirements about what to include in an email to your Criteo team. This will allow our team to quickly and thoroughly assist. Please make sure you provide: * The **API Organization ID**, * The **API Application ID**, * The **full API request and response** (please make sure to not include your `Client ID` and `Secret ID` - these are for you only!), * The **Trace ID** that will appear in the problematic response (this will help us identify the exact error to troubleshoot). * **A brief explanation** of what you are trying to achieve and what went wrong. Please refer to the [Escalation Checklist](/criteo-apis/docs/escalation-guidelines#/escalation-checklist) below for steps to investigate. **Why provide your API org & App IDs?** We need these to identify any related logs to your request, to better help you with the issue you are encountering. **Quick checks** Please ensure the following: * You are using the correct `Account ID`. * You have consent to access the account in question. *** ## Where to find the required information You can find your API Organization by logging into [your partner portal account](https://partners.criteo.com). ### The organization ID On the first page will be a list of the Organizations you have access to. Select your organization in the list After selecting the organization in question, it will take you directly to a page showing the applications within. The URL should look like: `https://partners.criteo.com/dashboard/1111/apps` where `1111` is the `Organization ID`. *** ### The App ID From your organization page, click into the desired app. Then select the App you need assistance with The `app ID` will appear next to the app name, as well as in the URL at the top of the page, along with the `organization ID`. The URL will look like: `https://partners.criteo.com/dashboard/1111/apps/22222` where `1111` is the `Organization ID` and `22222` is the `App ID`. The App ID appears both in the URL and besides the App name. *** ### The Request and Response Please provide the full Curl request and the associated JSON response related to your issue. *** ### A short explanation Please provide us with some context about what you were trying to achieve when you encountered the issue. This will help us better understanding the problem and provide you with a better (faster) answer. Once you provide all the required information, our teams will get back to you shortly. You can also browse through our [endpoint guides](/criteo-apis/docs/accounts-endpoints) and the [API reference](/retail-media/reference/authorization/get-token) to learn more about the Criteo Retail Media API. *** # Escalation checklist **When to escalate** If you are unable to fix the problem, you can escalate if the issue is persistent and reproducible, and after you have completed all steps according to the error code faced. ## For 400 Series Errors (Client-side issues) These indicate that the request sent to the server is incorrect or cannot be processed. When this error type occurs, Criteo is typically communicating why the user who called the endpoint ran into the issue. Users should escalate after completing all the steps listed below for this error type. ### Step 1: Check the Request URL * Ensure the endpoint is correct. * Verify query parameters and path variables are properly formatted. * Check for missing or extra slashes, bad characters, or wrong parameters in the path. * Ensure you're using the correct method (`GET`, `POST`, `PUT`, `DELETE`). ### Step 2: Validate Headers * Confirm required headers (e.g., `Authorization`, `Content-Type`) are present and correctly formatted. ### Step 3: Inspect the Request Body * If you're sending JSON or form data, validate the structure and required fields. * Use a JSON validator to catch syntax errors. * Confirm all required fields are included. * Check for unexpected or misspelled keys. ### Step 4: Authentication & Authorization * Ensure your API key or token is valid and has the necessary permissions. * Check if the token has expired. * Re-authenticate and try again, especially if using an expiring token like `OAuth`. ### Step 5: Rate Limits * Look for headers like `X-RateLimit-Remaining` or `Retry-After`. You might be sending too many requests in a short time. ### Step 6: Error Message Details Many APIs return a helpful error message in the response body—read it carefully. *** ## For 500 Series Errors (Server-side issues) These indicate a problem on the server, but you can still do some checks. Users should escalate after completing steps 1 to 4. Steps 5 to 6 are helpful steps for having a healthy amount of logs to reference but are not mandatory. ### Step 1: Retry the Request Sometimes it's a temporary glitch. Try again after a short delay, of 10 to 30 minutes, if an arbitrary number is required. Test the same endpoint with example data from the API docs or a working request. ### Step 2: Check API Status Page Some APIs have a status page (e.g., [Criteo Services Status](https://status.criteo.com/)) where outages are reported. Also make sure to check the [changelog](https://developers.criteo.com/retail-media/changelog) for breaking changes in documentation. ### Step 3: Simplify the Request Try a minimal version of your request to see if a specific parameter or payload is causing the issue. ### Step 4: Escalate to Criteo After completing steps 1 to 3, you can escalate to your Criteo contact. Log the Full Request and Response. When reaching out, please include the following in your email. Providing the info below ensures Criteo can properly investigate and troubleshoot in a timely manner: * Capture headers, body, and status codes, * Full request and response. ### Step 5: Test with Tools Use tools like Postman or `curl` to isolate the issue from your codebase. ### Step 6: Retry Logic Implement exponential back off or retry mechanism, especially for `500` or `503` errors. *** # Get Your Credentials Source: https://developers.criteo.com/criteo-apis/docs/get-credentials ## Introduction Before making API calls, you need to generate your application credentials. These credentials consist of an **API Key** and an **API Secret**, which are linked to the permissions ([Domains](/criteo-apis/docs/create-your-app#step-3---authorizations)) set during the application creation process. *** ## Retrieving App Credentials ### Step 1 * Log in to the [Criteo Partner Dashboard](https://partners.criteo.com/), and from the **My Apps** page, select the application for which you want to retrieve credentials and click on **Create new key** to generate your set of credentials. 5d0cbb5 api_keys ### Step 2 A text file containing both your **API Key** and **API Secret** will automatically download. While you can copy the API Key from the credentials' dashboard, the API Secret is only available in the downloaded file. Make sure to store these keys securely! **Storing API Keys** Your API Secret is only available in the text file. If the file is lost, the API Secret cannot be retrieved, and you will need to create new API keys. So please make sure to store your keys in a safe location! Each application allows up to five keys at a time. ### Step 3 With your API credentials in hand, you can call the `POST` `/oauth2/token` endpoint to obtain your token. ```http theme={null} https://api.criteo.com/oauth2/token ``` More information about the Auth endpoint is available in [the API Reference documentation](/retail-media/reference/authorization/get-token) and in [our authentication guide](/criteo-apis/docs/authentication). The steps to obtain the token depend on your selected authentication method: [Client Credentials](/criteo-apis/docs/oauth-app-client-credentials#app-credentials) or [Authorization Code](/criteo-apis/docs/oauth-app-authorization-code#step-2-set-up-your-oauth-parameters). *** ## Best Practices * **Use the dashboard to manage your API keys**. You can delete a key, and it will remain valid for 15 minutes before deactivating. * **Rename your credentials directly in the dashboard** for easy identification, such as "Troubleshooting Credentials" or "Production Credentials." * You are limited to five API credentials per app, allowing for flexibility (e.g., 1 for production, 1 for troubleshooting, and others for various use cases). *** # OAuth App - Authorization Code Setup Source: https://developers.criteo.com/criteo-apis/docs/oauth-app-authorization-code This guide provides step-by-step instructions on setting up an API application using the authorization code workflow This guide describes OAuth App setup using the Authorization Code flow. If your application is a mobile app, single-page app (SPA), or other public client that cannot securely store a client secret, you must use the [Authorization Code with PKCE](/criteo-apis/docs/oauth-app-authorization-code-pkce-setup) instead. *** # Setting up an authorization code application ## Step 1. Authorization Code Setup ### Creating an authorization code app Log in to the Criteo Partners Portal and create a new app by clicking the ➕ button in the `My apps` section. 862451e image This will open a modal where you can select type of application. *** ### Create app #### App details * Provide your app name and description. Optionally, add an image to identify your application. * On your app page, you can define the scope of your application and OAuth parameters. For more details, please refer to [Getting connected to the API](/criteo-apis/docs/connect-to-the-api). abc222c portal _step1_1 *** #### Authentication method * Select your app's authentication method: choose between "*Client Credentials*" or "*Authorization Code*". * For this setup, we are selecting "*Authorization Code*", but you can review our [OAuth App implementation](/criteo-apis/docs/oauth-app-implementation) guide to determine the best option for your organization. 190da94 auth_methods *** ### App activation #### Service Choose the Criteo service your API application will use: select C-Growth for Marketing Solutions or C-Max for Retail Media. 4a14336 services *** ### Authorizations #### Domains Choose the domains that define the permission access your application needs. fb84380 portal _step4final_1 After completing these steps, click `Activate app` to activate the application. #### Redirect URI * For applications using the authorization code workflow, you need to specify a **Redirect URI** as part of your app scope. *** ## Step 2. Set Up Your OAuth Parameters After defining your application’s scope, set up the necessary parameters for the authorization code workflow.

Parameters

Description

client\_id

Your public key, accessible in the app credentials section. You can manage up to 5 pairs of credentials, even after the app has been activated.

client\_secret

Your secret key, accessible only once when creating a pair of client\_id and client\_secret . You can manage up to 5 pairs of credentials after app activation.

redirect\_uri

The URL to redirect the user to after consent. Requires HTTPS. You can add up to 30 redirect URIs, manageable after app activation.

You can now publish the app and initiate the authorization code workflow. *** ### Consent URL Creation Once your app parameters are set, you can implement the authorization code flow. #### Consent URL 1. To request access, create a Consent link that redirects the user, using the following structure: **Authorization Code v. Client Credentials Consent URLs** If you're familiar with the Client Credentials workflow, you might notice that the `Generate Consent URL` button is not present in the partner portal for the authorization code workflow. This is because, with the authorization code method, you need to provide a redirect URI specific to your organization. Therefore, these URLs must be configured directly within your workflow. You will need to construct a consent URL similar to the example below while passing the required parameters for your application: ```http URL theme={null} https://consent.criteo.com/request?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&state={state} ```

Parameters

Required

Description

response\_type=code

Yes

Indicates that an authorization code is expected as outcome.

client\_id

Yes

Your public key from the app credentials section.

redirect\_uri

Yes

The URL to redirect the user after consent. Must match the configured URI.

state

No

Optional string to prevent Cross-Site Request Forgery attacks.

2. The consent link directs users to the `Criteo Consent page`, where they can select which advertisers to grant access to and approve the request. The Criteo Consent page allows selecting the advertisers to grand access to
**Notes** A consent request will not be displayed if: * The `client_id` does not match a published API app. * The `redirect_uri` is unauthorized. * There is an unexpected backend error. In any of the cases above an error message will be displayed. *** ### Redirection and Access Code Upon completing the Consent Delegation, users are redirected to a URL similar to the example below: ```http URL theme={null} https://www.yourdomain.com/?code=58f4cd15-8087-48af-bab7-bba06d2df1da&state=4lr4e ``` This URL is forged with the authorized `redirect_uri` and the following query parameters:

Parameter

Description

code

A single-use authorization code valid for 60 seconds.

state

The originally provided state parameter, returned as-is.

If consent is denied, the redirect will include an `error` query parameter instead of a `code`. *** ## Step 3. Exchanging Access Code For Access Token With an authorization code, you can request an access token via a `POST` request: ```bash theme={null} curl -L 'https://api.criteo.com/oauth2/token' \ -d 'client_id=' \ -d 'client_secret=' \ -d 'redirect_uri=' \ -d 'code=' \ -d 'grant_type=authorization_code' ``` ### Example ```bash theme={null} curl -L 'https://api.criteo.com/oauth2/token?grant_type=authorization_code&client_id=&client_secret=&redirect_uri=' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=' \ -d 'client_secret=' \ -d 'redirect_uri=' \ -d 'code=' \ -d 'grant_type=authorization_code' ```

Parameter

Description

grant\_type=authorization\_code

Indicates that you are providing an authorization code

code

Authorization code returned during redirection

redirect\_uri

Must match the redirect\_uri used for the authorization request

client\_id

Your public key from the app credentials

client\_secret

Your secret key, accessible when creating credentials

The response from Criteo API will be the following: ```json theme={null} { "access_token": "eyJhbGciOixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "token_type": "Bearer", "refresh_token": "eyJhbGciOxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "expires_in": 900 } ```

Parameter

Description

access\_token

A short-lived (valid for 900 seconds) access token.

refresh\_token

A long-lived refresh token (that expires after 6 months) that can be used to renew the access token (see next section).

token\_type=Bearer

Type of token.

expires\_in

Lifetime of the token in seconds.

**Token Lifetime** The refresh token will be revoked if the user changes roles or leaves the organization. The account must be re-authorized through the consent flow by a new administrator. *** ### Using the refresh token To renew an access token, use the following request: ```bash theme={null} curl -X POST https://api.criteo.com/oauth2/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token&code={code}&redirect_uri={redirect_uri}&client_id={client_id}&client_secret={client_secret}" ```

Parameter

Description

grant\_type=refresh\_token

Indicates that you are providing a refresh token.

refresh\_token

Refresh token shared when requesting an access token.

client\_id

Your public key accessible in app credentials section.

client\_secret

Your secret key, accessible only once when creating a pair of client\_id and client\_secret in credentials section.

The response will be the same as when issuing an access token *** # Demo Below is a demo application code (index.js) in **NodeJS** using the **Express JS** framework: ```javascript JavaScript expandable theme={null} var express = require('express'); var passport = require('passport'); var OAuth2Strategy = require('passport-oauth2').Strategy; var app = express(); var port = 3000; // Passport setup passport.use(new OAuth2Strategy({ clientID: 'CLIENT_ID', // Enter your client_id here clientSecret: 'CLIENT_SECRET', // Enter your client_secret here authorizationURL: 'https://consent.criteo.com/request', callbackURL: `http://localhost:${port}/criteo-auth/callback`, tokenURL: 'https://api.criteo.com/oauth2/token', state: 'togorot' }, function(accessToken, refreshToken, profile, cb) { cb(null, { accessToken, refreshToken }); } )); app.use(passport.initialize()); // Route declarations app.get('/', function(req, res) { res.send('Link my Criteo account!'); }); app.get('/criteo-auth', passport.authenticate('oauth2')); app.get('/criteo-auth/callback', passport.authenticate('oauth2', { session: false }), function(req, res) { res.send(`
Authentication successful!
Access token:
Refresh token:
`); } ); console.log(`OAuth test app started on http://localhost:${port}`); app.listen(port); ``` ```json JSON theme={null} { "name": "oauth-node", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node index.js" }, "author": "", "license": "ISC", "dependencies": { "ejs": "^3.1.6", "express": "^4.17.1", "passport": "^0.4.1", "passport-oauth2": "^1.6.0" } } ```
*** ## Run the demo 1. Run `npm install`, 2. Connect to the developer portal and create an app. 3. Create an "Authorization code" app. 4. Generate app credentials and enter the `client_id `and `client_secret` in `index.js`. 5. Register "[http://localhost:3000/criteo-auth/callback](http://localhost:3000/criteo-auth/callback)" as the redirect URI. 6. Run `npm run start`, 7. Open [http://localhost:3000](http://localhost:3000). *** **What if my `client_id` and `client_secret` are compromised?** Delete the credentials in the App page and create new ones. Users will need to re-authorize access. *** # OAuth App – Authorization Code & PKCE Setup Source: https://developers.criteo.com/criteo-apis/docs/oauth-app-authorization-code-pkce-setup This guide provides step-by-step instructions for implementing OAuth 2.0 Authorization Code with PKCE, including authorization requests and token exchange. ## PKCE Overview Proof Key for Code Exchange (PKCE) is an extension of the OAuth 2.0 Authorization Code flow that enhances security for public or mobile clients that cannot safely store a client secret. It adds a verification step between the authorization request and token exchange to prevent intercepted authorization codes from being reused by malicious actors. You should use PKCE if your application is a mobile app, single-page app (SPA), or any client that cannot securely store a client secret. If your application is a traditional server-side (confidential) client, you can continue using the standard [Authorization Code flow](/criteo-apis/docs/oauth-app-authorization-code). PKCE (RFC 7636) is also available to developers as an extension of the authorization code flow. To enable it, toggle `PKCE` in the App details page. 5d438b48f6491e173c4f3f92e9c350000b1ff8497477459e6db264edc8026016 pkce gif Once PKCE is enabled, the application can only use the PKCE workflow. If PKCE parameters are not provided, the authorization code flow will fail. To switch back the toggle, the application should have no active keys. *** ## Step 1. Consent URL Once your app parameters are set, you can implement the authorization code flow. ### Consent URL To request access, create a Consent link that redirects the user. #### Authorization Code vs. Client Credentials Consent URLs If you're familiar with the [Client Credentials workflow](/criteo-apis/docs/oauth-app-client-credentials), you might notice that the **Generate Consent URL** button is not present in the partner portal for the authorization code workflow. This is because, with the authorization code method, you need to provide a redirect URI specific to your organization. Therefore, these URLs must be configured directly within your workflow. If the redirect URI is not declared in the application, the redirection will be blocked. If you have PKCE enabled, then the consent URL will require additional parameters: ```http URL theme={null} https://consent.criteo.com/request?response_type=code &client_id={client_id} &redirect_uri={redirect_uri} &state={state} &code_challenge={code_challenge} &code_challenge_method={code_challenge_method} ```

Parameter

Required

Description

response\_type=code

Yes

Indicates that an authorization code is expected as outcome.

client\_id

Yes

Your public key from the app credentials section.

redirect\_uri

Yes

The URL to redirect the user after consent. Must match the configured URI.

state

No

Optional string to prevent Cross-Site Request Forgery attacks.

code\_challenge

Yes when PKCE is enabled

A challenge derived from the code\_verifier that is sent in the authorization request, to be verified against later.

code\_challenge\_method

No

A method that was used to derive code\_challenge .

The methods available:

plain : no transformation (not recommended)

S256 : recommended & secure (hash + base64url)(also default when no method is provided)

*** ## Step 2. Exchanging the Access Code for the Access Token You can find more details about the OAuth endpoint in [our API Reference](/retail-media/reference/authorization/get-token). If you have PKCE enabled and made the consent request with PKCE parameters, your access token request must have one more parameter, which is `code_verifier`: ### Example Request ```bash theme={null} curl -L 'https://api.criteo.com/oauth2/token' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=' \ -d 'client_secret=' \ -d 'redirect_uri=' \ -d 'code=' \ -d 'grant_type=authorization_code' \ -d 'code_verifier=' ``` ### Example Response (Success) ```json theme={null} { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "bearer", "expires_in": 3600, } ``` ### Parameters All the following parameters are required in the context of PKCE.

Parameter

Description

grant\_type=authorization\_code

Indicates that you are providing an authorization code.

code

Authorization code returned during redirection.

redirect\_uri

Must match the redirect\_uri used for the authorization request.

client\_id

Your public key from the app credentials.

client\_secret

Your secret key, accessible when creating credentials.

code\_verifier

A high-entropy random string created by the client (usually 43–128 characters).

### Using the Refresh Token To renew an access token, use the following request: ```bash theme={null} curl -X POST https://api.criteo.com/oauth2/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=refresh_token&code={code}&redirect_uri={redirect_uri}&client_id={client_id}&client_secret={client_secret}" ```

Parameter

Description

grant\_type=refresh\_token

Indicates that you are providing a refresh token.

refresh\_token

Refresh token shared when requesting an access token.

client\_id

Your public key accessible in app credentials section.

client\_secret

Your secret key, accessible only once when creating a pair of client\_id and client\_secret in credentials section.

The response will be the same as when issuing an access token. ***
# OAuth App - Client Credentials Setup Source: https://developers.criteo.com/criteo-apis/docs/oauth-app-client-credentials This guide provides step-by-step instructions on setting up an API application using the client credentials workflow # Setting up an client credentials application ## Client Credential Log in to the Criteo Partners Portal and create a new app by clicking the ➕ button in the `My apps` section. ff276e4 image This opens a modal where you can choose the type of application. *** ### Step 1. Create app #### App details 1. Provide your app name and description. Please make sure to use a clearly identifiable name for your app, as it can be of great help with troubleshooting later on. Optionally, add an image to identify your application. On your app page, you can define the scope of your application and the OAuth parameters. For more details on defining your app scope, check [Create Your API Application](/criteo-apis/docs/create-your-app). 2. Upon clicking `Create new key`, the `client ID` and `client secret` will be generated and made available as a downloadable .txt file. ec2ea86 portal _clientcreds1 *** #### Authentication method 1. Select your app's authentication method: choose between "*Client Credentials*" or "*Authorization Code*". 2. For this setup, we are selecting "*Client Credentials*", but you can review our [OAuth App implementation](/criteo-apis/docs/oauth-app-implementation) guide to determine the best option for your organization. 74936ae client_credentials_option *** ### Step 2. App activation #### Service Choose the Criteo service your API application will use: select C-Growth for Marketing Solutions or C-Max for Retail Media. 4a14336 services *** ### Step 3. Authorizations #### Domains Choose the domains to specify which permissions your application requires. fb84380 portal _step4final_1 After this step, you can no longer change the name, description, image, or app scope. *** ## App Credentials ### Create new key To generate your `client_id` and `client_secret`, click the `Create new key` button. This will trigger a download of a text file containing your API keys. Make sure to store the keys securely for future access. 544d9f0 image *** ## Consent URL ### Generate new URL Once your API application is set up, you must request consent from the advertiser or publisher to access their assets. You can generate multiple URLs, but **each URL can only be used once**. b205ae3 consenturl * Click on `Generate new URL`. This will generate a fresh new consent URL every time this step is done. * Click the `Copy` icon to the right of the consent URL field. * Share this URL with a user who has access to the CMax account. Users with **Admin**, **Business Manager** or **Technical Manager** roles can grant consent to API applications in Retail Media. For more details, check [User Management](https://help.retailmedia.criteo.com/kb/en/user-management-127278) in our Help Center ***
# OAuth App Implementation Source: https://developers.criteo.com/criteo-apis/docs/oauth-app-implementation # Introduction The Criteo API enables the creation of custom apps to help advertisers grow their businesses. Whether you're a brand, agency, retailer, or third-party partner, the Criteo API offers various authentication methods to suit your application's needs. To get started, your users must delegate permissions for one or more Criteo advertisers they oversee for your application to function. Criteo supports OAuth client credentials and authorization code grant types. This guide explains the benefits of each grant type, helping you choose the best option for your application. This guide assumes you have a **partner account** and **Organization & API application** created within Criteo. Instructions for getting started are available on [Getting connected to the API](/criteo-apis/docs/connect-to-the-api). *** # OAuth 2.0 Grant Types Criteo provides OAuth client credentials and authorization code grant types. f9829c8 auth_methods2 *** ## Client Credentials The client credentials grant type is designed for straightforward API connections and apps that are authorized to access a few advertiser accounts. This method authenticates the client (the application or service) rather than an end-user, making it ideal for server-to-server interactions. Source: [Auth0 - Client Credentials Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) Client credentials are specific to each application or service, allowing resources to be isolated across different apps. Each app can have its client credentials and associated permissions, making this a suitable option if you plan to manage multiple applications with varying permissions. * **Case scenarios**: This workflow is ideal when the data owner and the application developer are the same, or when there is only a single data owner. It does not segregate data based on the accessed account. For more information, check out the app setup process for [OAuth App - Client Credentials Setup](/criteo-apis/docs/oauth-app-client-credentials). *** ## Authorization Code The authorization code grant type involves obtaining an authorization code, which is then exchanged for an access token. This method is used when an app needs to access a user’s (resource owner’s) resources and perform actions on their behalf. The app starts the process by redirecting the user to the authorization server’s login page. After successful authentication, the user is redirected back to the app with an authorization code. The app then exchanges this code for an access token and a refresh token, enabling access to user-specific resources. **Source**: [Auth0 - Authorization Code Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow) While the authorization code grant type may involve additional steps, particularly in managing the authorization code and token exchange, it is well-suited for scenarios requiring user consent and interaction. * **Case scenarios**: This workflow is appropriate when the application manages data for multiple data owners, as it segregates data behind separate access tokens. The consent process ensures data is bundled by each consent granter. For setup details, refer to [OAuth App - Authorization Code Setup](/criteo-apis/docs/oauth-app-authorization-code) *** # Welcome to our API Resources Source: https://developers.criteo.com/criteo-apis/docs/overview Shared platform guides for the Marketing Solutions API and Retail Media API — authentication, versioning, rate limits, and more. ## Shared platform guides Everything here applies to all Criteo public APIs. Whether you're integrating with Retail Media or Marketing Solutions, authentication, versioning, rate limits, and onboarding work the same way across both. Create your partner account, app, and credentials. Set up OAuth authentication. API patterns, response formats, bulk calls, rate limits, and error handling. Connectivity, debugging guides, error codes, and escalation guidelines. Client libraries, OpenAPI spec, and Postman collection. *** ## API-specific documentation Ready to dive in? Each API has its own guides, endpoint reference, and changelog. For Commerce Max and Commerce Yield users. Create, launch, and monitor retail media campaigns. For Commerce Growth users. Manage ad sets, audiences, campaigns, and analytics programmatically. # Postman Collection Source: https://developers.criteo.com/criteo-apis/docs/postman-collection ## Introduction Use the Criteo API Postman collection to quickly get started with Criteo API. This guide will help you to make your first request to Criteo API using Postman. The Criteo Postman Workspace is available [here](https://www.postman.com/realcriteo/workspace/criteo/overview). *** ## Pre-requisites To be able to use Criteo's Postman collections, please make sure you have: * Completed the [API setup steps](/criteo-apis/docs/connect-to-the-api) (partner account, app, and credentials), * Installed and set up the [Postman](https://www.postman.com/downloads/) client, as well as made sure your workspace visibility is set to the right settings (`private`, `public`, or`team`) based on the intended audience. *** ## Fork the Criteo API collection In this step, you set up the environment variables used to retrieve an access token. Go to [Criteo Postman Workspace](https://www.postman.com/realcriteo/workspace/criteo/overview) and click on the collection you would like to test. You will see the collection description on the right-hand side and the list configuration options on the left-hand side. Click `Create fork` and provide the fork label in the newly opened window, as shown on the following screenshots: Create a fork from your chosen Postman collection
Add a label and a location to your local collection After completing this step, you should have a local version of the Criteo API collection in your workspace. *** ## Configure authentication Go to the Criteo API [templated environment](https://www.postman.com/realcriteo/workspace/criteo/environment/12547236-5c1c73f6-1e41-4eec-9ae9-fab7f9ac6bf1). You will see collection of variables that you should customize according to your application credentials. Collection of variables to be customized Click `Fork` and add a local label to differentiate the environment in your workspace. Once forked, set up the fields as follows: * In `client_id` and `client_secret` fields, set the **CURRENT VALUE** column to the application `client_id` and `client_secret` values you received from the onboarding step, * You don't need to change the remaining rows as long as the application grant type is`client_credentials`. If you have a different application type, please get in touch with our support. These credentials input in the environment are used for authentication in the pre-request scripts. The pre-request script is a script attached to all Criteo API collections, to automatically fetch and supply an access token to protected endpoints. Finally, on the top right, verify that `MyCriteoConnector` Environment is selected in the dropdown as shown in the screenshot: Ensure the environment is "MyCriteoConnector" in Postman *** ## Your first API request Inside the versioned folder, you will find the requests for the various Criteo API endpoints you can call. To make your first call: * Expand the folder and then expand into the Advertiser folder, * Click `Api Portfolio Get` to open the portfolio request, * On the top right, select `Send`. Make your first call from the versioned folder You will receive a list of accounts consented to your application in the response. You have now successfully made a Criteo API call using a client credentials authentication. You can follow these steps to make other requests to Criteo API. As a reminder, each of the domains (Audience/Campaign/Analytics, etc.) requires a separate permission which is bound to your application at creation time. If your application does not include `Read` or `Manage` permission on a particular domain, you will get a permission error in response to performing a `GET/PATCH` operation on that domain. Learn more about application scopes and permissions in [Create your App](/criteo-apis/docs/create-your-app) More information about error handling can be found in [API Response](/criteo-apis/docs/api-response). *** ## Contributing to Criteo API Feel free to make your changes to the forked collection, and then hover over the collection top node and select `Create pull request`. The Criteo API team will review the change and merge the change wherever it makes sense. *** ## Questions If you keep getting a `code authorization-token-invalid` response when issuing a request to Criteo server, the most likely reason is incorrect `client_id`/`client_secret` or an uninitialized environment. The Postman community forum can be used for generic Postman usage questions. If you have a question or a bug report which is specific to Criteo API, please get in touch with your Criteo contact. ***
# Rate Limits Source: https://developers.criteo.com/criteo-apis/docs/rate-limits This page describes the Criteo API rate limit policy, and provides some best practices to help manage rate limits ## Introduction The Criteo API enforces a **rate limit**, which consists of a limitation in the number of calls you're able to perform on any of its endpoints. This limitation is enforced to provide all our API clients with stability towards our API infrastructure. *** ## Rate Limits Criteo provides different rate limits depending on the OAuth method used by your application. | OAuth Method | Rate limit | Applies at | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ----------------- | | [Client Credentials](/criteo-apis/docs/oauth-app-client-credentials) | **250 calls/min** (default endpoints)
**40 calls/min** (reporting endpoints) | Application level | | [Authorization Code](/criteo-apis/docs/oauth-app-authorization-code) | **10 calls/min** | Account level | **Rate limit exceptions** Some resource-sensitive endpoints, such as reporting endpoints, have stricter rate limits.\ For example, reporting endpoints are limited to **40 calls per minute**, compared to the default **250 calls per minute**. *** ### Auto-Scaling for Authorization Code Applications The auto-scaling only applies to Authorization Code flow and not Client Credentials. Authorization Code apps support dynamic rate limits based on the number of accounts each user has consented to: * **Base limit**: 10 calls/min per account per user, * **Example**: A user who consents to 3 accounts enables 30 calls/min for that app (3 × 10) Calls are shared across accounts, using all on one affects the others. This allows higher throughput when users consent to more accounts. *** ## Response If your application access token exceeds the given rate limit, you will receive a `429` HTTP response and be blocked from executing the action. The following information will be provided in the header:

Header

Description

Example response with a

limit set at 20 calls/minute

x-ratelimit-limit

the currently authorized limit for this caller

20

x-ratelimit-remaining

the remaining calls for this caller (so, limit - current rate)

0

x-ratelimit-reset

the timestamp at which a new call could be performed

1628249355

*** ## Rate Limit Best Practices For the best experience, while using Criteo API, we strongly encourage implementing best practices methods to help you attain the best API experience. In the steps below, we will provide guidance to help you manage your application rate limits. *** ### Implement Backoff Mechanics Exponential backoff mechanisms helps your application handle rate limit exceeded errors by introducing increasing intervals between retry attempts. This approach reduces the likelihood of overwhelming the API server with repeated requests, mitigating the risk of rate limit penalties. By gradually increasing the time between retries, exponential backoff allows the server to recover from transient failures or temporary congestion more effectively. In the event that your application runs into a `429` error, we recommend your application waits one second before retrying the call again. When a second error is experienced, have your application wait two seconds before attempting a new retry. Setting your application to gradually repeat these exponential backoff mechanisms will allow the server to recover from an overload of calls. *** ### Distribute load using access token best practices #### Client Credentials 1dc5ae4 image Managing a platform with multiple concurrent users using client credentials can be challenging when maintaining a stable rate limit. This is because client credentials rely on **a singleaccess token** , which can severely constrain the number of calls your application can make as the number of concurrent users increases. For example, if you have ten users logged in concurrently, the rate limit maximum for your platform would be 250 calls per minute. This means that each user can only make about 25 calls per minute (250 divided by 10). During peak hours, when more concurrent users are logged in, this number will decrease significantly, affecting the performance of your platform. However, with the right approach, you can ensure that your platform remains stable, even with many concurrent users logging into your platform. *** #### Authorization Code Self-service platforms provide users with a convenient way to manage their own data. However, when an application handles data for multiple users, it's crucial to ensure that each consenter (i.e., user who grants access) can only access their own information and is subject to their own resource limits. To support this, Criteo enforces **rate limiting per consenter**. Each consenter receives a dedicated **access token** and is assigned an individual rate limit. All API calls made with that token are counted against the consenter's quota, not a shared or global one. By choosing the authorization code workflow for your application, you ensure that activity from one consenter does not affect the experience of others. This isolation provides a more stable and predictable environment for all users. d27a3e6dcb5cdb5499666e1496c36669b4bd4b39ae0912f5f5d9d1c85c1fca4d image *** ### Export only the data you need, and avoid unnecessary calls We understand that having the most up-to-date data is essential to help advertisers make the best decisions. But in this section, we will explain how calls to analytics APIs may be unnecessary and can cause your access token to exceed its limits. **Limit your queries to attribution settings users most often look at, instead of pulling all potential combinations of settings** * Pulling all possible attribution settings will increase your needed API calls. Instead of pulling all combinations, allow users to draw the most commonly used settings **Limit your queries to four (4) days of consecutive data** * Pulling more than four (4) days of data is typically unnecessary, as most spend and attribution data stabilize within 72–74 hours. Minor updates may occur for up to 120 hours. Attributed sales are assigned to days on a sale-day basis, not event-day. So, multiple reporting calls can be reduced to ensure that you're getting just the data that you need to cache within your system. Different types of activity and attribution data become available at different times after the event or sale: * **Onsite activity data** is typically available within **6–8 hours** of the event. * **Offsite activity data** is typically available within **24 hours** of the event. * **Initial attribution data** is available within **7–9 hours** of the sale. * **Final attribution data** is processed and posted within **74 hours** after the sale. * Please note that potential minor updates can occur up to **120 hours** before finalization **Use bulk operations** * The analytics API also supports [Bulk Calls](/criteo-apis/docs/bulk-calls) for reporting. API calls can be structured to pass up to fifty (50) campaign or line-item IDs at a time to retrieve the data for each account. Private market retailers will also have the option to use bulk operations to pull data across multiple accounts. If you're a supply account partner, **reach out to your account representative** to get set up with this feature. *** # API Versioning Policy Source: https://developers.criteo.com/criteo-apis/docs/versioning-policy How Criteo API versions work, what the different version types mean, and how to know when you need to take action. Criteo releases two stable API versions per year — in **January** and **July**. Each version is supported for **12 months**. The final 3 months of that period serve as a deprecation window as notice to migrate before decommission. ## How API versions work Every API endpoint follows the same lifecycle from initial release to decommission: | Stage | Duration | Description | | --------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------- | | **Release Candidate** | Up to 6 months | Production-ready. Will roll directly into the next stable release. | | **Stable** | 12 months | Fully supported. No breaking changes — ever. In the final 3 months (months 9–12) we email deprecation reminders. | | **Decommissioned** | — | Returns `410 Gone`. Fall-forward applies. | *** ## Fall forward If an endpoint's contract hasn't changed between versions, Criteo automatically routes your requests to the current stable behavior — even after your version is decommissioned. This means you can stay on an older version indefinitely for any endpoint that has not been altered. You only need to migrate when an endpoint you use has a breaking change. If an endpoint has been removed or modified in all active versions, calling it on a decommissioned version returns `410 Gone`. Check the changelog for your API ([Retail Media](/retail-media/changelog/index) · [Marketing Solutions](/marketing-solutions/changelog/index)) to see which endpoints changed between versions and which ones fall forward safely. *** ## The three version types **For early exploration** * Test brand-new features before they're finalized * Contracts may change significantly at any time * Not suitable for production use URL: `api.criteo.com/experimental/...` **For integrating early** * Production-ready — will roll directly into the next stable release * Uses the **same URL** as the upcoming stable version * Integrate now, no changes needed when stable ships * Only minor changes possible (bug fixes) URL: e.g. `api.criteo.com/2026-07/...` (before July 2026) **For production use** * Fully supported for 12 months * No breaking changes — ever * Released every January and July * Deprecation notice in the final 3 months (months 9–12) URL: e.g. `api.criteo.com/2026-07/...` (from July 2026) **Why use a Release Candidate?** The RC and the upcoming stable version share the same URL. If you integrate `2026-07` while it's still a Release Candidate, you are already on the right version the moment it goes stable — zero migration effort. This replaces the old preview system where integrations had to be re-done once a version became stable. *** ## Keeping your integration current ### What does my status mean? You're in good shape. No action needed right now. Keep an eye on the release schedule so you can plan your next upgrade with plenty of lead time. You're entering the deprecation window. Start planning your migration now. Your version is in its final 3 months. Migrate to the current stable version before that date. Your version is no longer active. Update your base URL to the current stable version immediately. Endpoints that haven't changed may fall forward automatically — check the changelog to confirm which ones need manual updates. ### Migrating to a new version 1. **Find your current version** — check your API call URL. 2. **Find your deadline** — look up your version in the Release Schedule below. The Decommission date is your hard deadline. 3. **Check what's changed** — review the changelog for your API ([Retail Media](/retail-media/changelog/index) · [Marketing Solutions](/marketing-solutions/changelog/index)) to identify any breaking changes between your version and the target. Non-breaking additions require no code changes. 4. **Update your base URL** — change the version in your URL (e.g. `2025-10` → `2026-07`). That's usually the only change needed. 5. **Test before switching** — validate in a test environment before routing production traffic. 6. **Monitor after switching** — watch for `4xx` / `5xx` errors in the first 48 hours. Your old version is still live until its decommission date if you need to roll back. **The easiest migration is one you don't have to rush.** The Release Candidate for the next version is available up to 6 months before its stable release. Integrating early means you upgrade on your own schedule — not against a deadline. *** ## Release schedule Stable versions release every **January** and **July**. Each version is supported for 12 months — deprecation begins at month 9, decommission at month 12. | Version | Stable release | Deprecated from | Decommission | Status | | ------- | -------------- | --------------- | ------------ | -------------- | | 2025-07 | Jul 2025 | Apr 2026 | **Jul 2026** | DECOMMISSIONED | | 2025-10 | Oct 2025 | Jul 2026 | **Oct 2026** | DEPRECATED | | 2026-01 | Jan 2026 | Oct 2026 | **Jan 2027** | ACTIVE | | 2026-07 | Jul 2026 | Apr 2027 | **Jul 2027** | UPCOMING | | 2027-01 | Jan 2027 | Oct 2027 | **Jan 2028** | PLANNED | | 2027-07 | Jul 2027 | Apr 2028 | **Jul 2028** | PLANNED | **Migrating from Preview?** The legacy `preview` version is being deprecated in 2026. Move any preview integrations to `2026-01` (stable now) or start on the `2026-07` Release Candidate today to be auto-rolled over into the newest stable version. # Account Source: https://developers.criteo.com/retail-media/docs/account 860dcb7 l1 account A Retail Media Platform (RMP) account is unique, and the Criteo API enables external applications to make calls to the account once API access has been granted. The account endpoints are synchronized with the RMP platform and API, meaning any changes made through the API will be immediately reflected in the RMP account. **Currently, accounts are created by Criteo. Please contact your account representative if you need an account to be set up.** The Accounts endpoints will allow you to: * Check for available retailers you can serve ads on * Look out for brands available witin your account * Access your account basic settings You can learn more about Accounts in our [CMax Help Center](https://help.retailmedia.criteo.com/kb/guide/en/about-accounts-3c39AcNsJx/Steps/969774). ***
## What's next * [Accounts Endpoints](/retail-media/docs/accounts-endpoints) * [Account Creation and Management (Private Market)](/retail-media/docs/account-creation-and-management-private-market) * [Account Fees (Private Market)](/retail-media/docs/account-fees) * [Brands](/retail-media/docs/brands) * [Sellers](/retail-media/docs/sellers) * [Retailers](/retail-media/v2025.07/docs/retailers) # Account Creation and Management (Private Market) Source: https://developers.criteo.com/retail-media/docs/account-creation-and-management-private-market Account creation endpoints enable private market retailers to create both demand brand and marketplace seller accounts within the private market. The following endpoints will also provide access to manage the brand and seller mappings for each account types. **Limited Access** Private Market account creation and management access is currently only available for a selected group of API users. To access these endpoints, please get in touch with Criteo to have the correct permissions enabled. *** ## Endpoints

Verb

Endpoint

Description

GET

/accounts

Get all Accounts

GET

/account-management/accounts/\{parentAccountId}/private-market-child-accounts

Get all PM Demand Child (brand or seller) Accounts under the parent Supply Account (Retailer)

POST

/account-management/accounts/\{parentAccountId}/create-brand-account

Create a PM Demand-Brand Account under the Parent Supply Account

POST

/account-management/accounts/\{parentAccountId}/create-seller-account

Create a PM Demand-Seller Account under the Parent Supply Account

POST

/account-management/accounts/\{accountId}/brands/add

Map brands to a demand brand account

POST

/account-management/accounts/\{accountId}/brands/remove

Remove brand from a demand brand account

PUT

/account-management/accounts/\{accountId}/sellers

Map or remove sellers from demand seller account.

*** ## Account Attributes

Attribute

Data Type

Description

id

string

Account ID, from a demand or supply account, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

name

string

Account name, arbitrary and defined at account creation

Accepted values: up to 510-chars string

Writeable? Y / Nullable? N

type

enum

Account type, with supply being the account type for Retailers and demand the account type for the different types of advertisers (brand, marketplace sellers, agencies, etc)

Accepted values: demand , supply

Writeable? N / Nullable? N

subtype

enum

Account sub-type, specific for demand accounts

Accepted values: brand , seller

Writeable? N / Nullable? Y

brandId

list \

List of Brand IDs associated with a demand brand account. Required in the demand brand account creation.

Accepted values: list of string of int64

Writeable? Y / Nullable? N

sellerId

string

Seller ID from Retailer's Catalog , associated with a demand seller account. Required in the demand seller account creation.

Accepted values: string of int64

Writeable? Y / Nullable? N

retailerId

string

Retailer ID, associated with the demand seller account, generated internally by Criteo. Required in the demand seller account creation.

Accepted values: string of int64

Writeable? N / Nullable? N

companyName

string

This optional field, exclusively accessible to marketplaces within the European Union (in compliance with the Digital Service Act - DSA), will display the name of the company associated with the advertisement.

Accepted values: up to 255-chars string

Writeable? Y / Nullable? Y

onBehalfCompanyName

string

This optional field, exclusively accessible to marketplaces within the European Union (in compliance with the Digital Service Act - DSA), will display the name of the company (on behalf of companyName ) associated with the advertisement

Accepted values: up to 255-chars string

Writeable? Y / Nullable? Y

countries / countryIds

list \

Countries associated with the account

Accepted values: 2-chars country code (in ISO-3166 alpha-2 code; e.g. US , FR )

Writeable? N / Nullable? N

currency / currencyId

string

Default currency for bulling, budgeting, bid settings & campaign performance metrics

Accepted values: 3-chars currency code (in ISO-4217 ; e.g. USD , EUR )

Writeable? N / Nullable? N

parentAccountLabel

string

Label used to associate multiple accounts

Accepted values: up to 510-chars string

Default: same as name

Writeable? Y / Nullable? N

timeZone

string

Account time zone

Accepted values: time zone identifiers from IANA (TZ database) (e.g. America/New\_York , Europe/Paris , Asia/Tokyo , UTC )

Writeable? N / Nullable? N

### **Digital Service Act (DSA)** In compliance with the Digital Services Act (DSA), marketplaces within the European Union will receive information about the company name associated with each advertisement. *** ## Get all Accounts This endpoint lists all accounts accessible via your API credentials. Results are paginated using `pageIndex` and `pageSize` query parameters; if omitted, defaults to `0` and `25`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts ``` **View in the API Reference** You can also see this endpoint in the [API reference](/retail-media/reference/authorization/get-token). **Sample Request** ```bash theme={null} curl -L -X GET 'https://api.criteo.com/{version}/retail-media/accounts?pageIndex=0&pageSize=25' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json JSON expandable theme={null} { "metadata": { "totalItemsAcrossAllPages": 4, "currentPageSize": 25, "currentPageIndex": 0, "totalPages": 1 }, "data": [ { "id": "425730879617900544", "type": "RetailMediaAccount", "attributes": { "name": "Supply Private Market TEST Account", "type": "supply", "subtype": null, "countries": [ "US" ], "currency": "USD", "parentAccountLabel": "Supply Private Market TEST Account", "timeZone": "America/New_York", "companyName": "Supply Private Market TEST Account", "onBehalfCompanyName": "Supply Private Market TEST Account" } }, { "id": "568182612169883648", "type": "RetailMediaAccount", "attributes": { "name": "Demand Brand Account US", "type": "demand", "subtype": "brand", "countries": [ "US" ], "currency": "USD", "parentAccountLabel": "Supply Private Market TEST Account", "timeZone": "America/New_York", "companyName": "Brand ABC Corp.", "onBehalfCompanyName": "Brand ABC Corp." } }, // ... { "id": "569185968379719680", "type": "RetailMediaAccount", "attributes": { "name": "Town Supplies (seller)", "type": "demand", "subtype": "seller", "countries": [ "US" ], "currency": "USD", "parentAccountLabel": "Supply Private Market TEST Account", "timeZone": "America/New_York", "companyName": "Seller Test", "onBehalfCompanyName": "Seller Test LLC" } } ] } ``` *** ## Get Private Market Child Accounts This endpoint lists all Private Market child accounts (brand or marketplace seller accounts) that are associated with the given Retailer account. Response results will be provided in paginated form Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `500`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/account-management/accounts/{parentAccountId}/private-market-child-accounts ``` **Sample Request** ```bash theme={null} curl -L 'https://api.criteo.com/{version}/retail-media/account-management/accounts/425730879617900544/private-market-child-accounts?offset=0&limit=25' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json JSON expandable theme={null} { "metadata": { "count": 4, "offset": 0, "limit": 25 }, "data": [ { "id": "568182612169883648", "type": "RetailMediaChildAccount", "attributes": { "name": "Demand Brand Account US", "type": "demand", "subtype": "brand", "countryIds": [ "US" ], "currencyId": "USD", "timeZone": "America/New_York", "companyName": "Brand ABC Corp.", "onBehalfCompanyName": "Brand ABC Corp." } }, // ... { "id": "569185968379719680", "type": "RetailMediaChildAccount", "attributes": { "name": "Town Supplies (seller)", "type": "demand", "subtype": "seller", "countryIds": [ "US" ], "currencyId": "USD", "parentAccountLabel": "Supply Private Market TEST Account", "timeZone": "America/New_York", "companyName": "Seller Test", "onBehalfCompanyName": "Seller Test LLC" } } ] } ``` *** ## Create Brand Account This endpoint creates a new child Demand-Brand account under the provided parent Private Market account. ```http theme={null} https://api.criteo.com/{version}/retail-media/account-management/accounts/{parentAccountId}/create-brand-account ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST "https://api.criteo.com/{version}/retail-media/account-management/accounts/425730879617900544/create-brand-account" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "data": { "type": "AccountCreationDemandBrand", "attributes": { "name": "Demand Brand Account US", "companyName": "Brand ABC Corp.", "onBehalfCompanyName": "Brand ABC Corp.", "brands": [ "2151767311" ] } } }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": { "type": "AccountCreationDemandBrand", "attributes": { "name": "Demand Brand Account US", "companyName": "Brand ABC Corp.", "onBehalfCompanyName": "Brand ABC Corp.", "brands": [ "2151767311" ] } } }) headers = { 'Authorization': 'Bearer ', 'Content-Type': 'application/json', 'Accept': 'application/json' } conn.request("POST", "/{version}/retail-media/account-management/accounts/425730879617900544/create-brand-account", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, """ { "data": { "type": "AccountCreationDemandBrand", "attributes": { "name": "Demand Brand Account US", "companyName": "Brand ABC Corp.", "onBehalfCompanyName": "Brand ABC Corp.", "brands": [ "2151767311" ] } } } """); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/account-management/accounts/425730879617900544/create-brand-account") .method("POST", body) .addHeader("Authorization", "Bearer ") .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/account-management/accounts/425730879617900544/create-brand-account'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig([ 'follow_redirects' => TRUE ]); $request->setHeader([ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', 'Accept' => 'application/json' ]); $request->setBody(json_encode([ "data" => [ "type" => "AccountCreationDemandBrand", "attributes" => [ "name" => "Demand Brand Account US", "companyName" => "Brand ABC Corp.", "onBehalfCompanyName" => "Brand ABC Corp.", "brands" => [ "2151767311" ] ] ] ], JSON_PRETTY_PRINT)); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "attributes": { "name": "Demand Brand Account US", "companyName": "Brand ABC Corp.", "onBehalfCompanyName": "Brand ABC Corp.", "type": "Demand", "subType": "Brand", "countryIds": [ "US" ], "currencyId": "USD", "parentAccountLabel": "Supply Private Market TEST Account", "timeZone": "America/New_York" }, "id": "569225726270857216", "type": "RetailMediaAccount" }, "warnings": [], "errors": [] } ``` *** ## Create Seller Account This endpoint creates a new child Demand-Seller account under the provided parent Private Market account. ```http theme={null} https://api.criteo.com/{version}/retail-media/account-management/accounts/{parentAccountId}/create-seller-account ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/account-management/accounts/425730879617900544/create-seller-account' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer <ACCESS TOKEN>' \ -d '{ "data": { "type": "Demand", "attributes": { "name": "Town Supplies (seller)", "companyName": "Seller Test", "onBehalfCompanyName": "Seller Test LLC", "sellers": [ { "sellerId": "62a0871ffad67c541xxxxxxxxx", "retailerId": "1141" } ] } } }' ``` **Sample Response** ```json theme={null} { "data": { "attributes": { "name": "Town Supplies (seller)", "type": "Demand", "subType": "Seller", "countryIds": [ "US" ], "currencyId": "USD", "parentAccountLabel": "Supply Private Market TEST Account", "timeZone": "America/New_York", "companyName": "Seller Test", "onBehalfCompanyName": "Seller Test LLC" }, "id": "569185968379719680", "type": "RetailMediaAccount" }, "warnings": [], "errors": [] } ``` *** ## Add Brand to Account This endpoint adds a brand to a Private Market Demand-Brand account. ```http theme={null} https://api.criteo.com/{version}/retail-media/account-management/accounts/{accountId}/brands/add ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/account-management/accounts/568182612169883648/brands/add' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "MapBrandstoDemandAccount", "attributes": { "brandIds": [ "2151768660" ] } } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "RetailMediaBrands", "attributes": { "brandIds": [ 2149947741, 2151768660 ] } }, "warnings": [], "errors": [] } ``` *** ## Remove Brand from Account This endpoint removes a brand from a Private Market Demand-Brand account. Although `brandIds` is an array format, as of now, only one brand can be removed from an account at a time, this parameter should contain only one id per request. ```http theme={null} https://api.criteo.com/{version}/retail-media/account-management/accounts/{accountId}/brands/remove ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/account-management/accounts/568182612169883648/brands/remove' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "RemoveBrandfromDemandAccount", "attributes": { "brandIds": [ "2151768660" ] } } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "RetailMediaBrands", "attributes": { "brandIds": [ 2149947741 ] } }, "warnings": [], "errors": [] } ``` *** ## Add Seller to Account The endpoint map or removes sellers from a private market seller account. Note that PUT calls overrides existing values. Only the `sellerId` mapped in the payload will be the ones associated with the account. ```http theme={null} https://api.criteo.com/{version}/retail-media/account-management/accounts/{accountId}/sellers ``` **Sample Request** ```bash theme={null} curl -L -X PUT 'https://api.criteo.com/{version}/retail-media/account-management/accounts/569185968379719680/sellers' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "type": "MapSellertoAccount", "attributes": { "sellerId": "5ed6ad7b0b2a9xxxxxxxxxxx", "retailerId": "1141" } }, { "type": "MapSellertoAccount", "attributes": { "sellerId": "640a20bbc63745xxxxxxxxxxx", "retailerId": "1141" } } ] }' ``` **Sample Response** ```json theme={null} { "data": [ { "type": "RetailMediaSeller", "attributes": { "sellerId": "5ed6ad7b0b2a995f0427858e", "retailerId": 1141 } }, { "type": "RetailMediaSeller", "attributes": { "sellerId": "640a20bbc637455565a5c4a3", "retailerId": 1141 } } ], "warnings": [], "errors": [] } ``` *** ## Responses

Response

Description

🔵

200

Call completed successfully

🔵

201

Account created successfully

🔴

400

Validation Error - one or more required fields was not found. Confirm that all required fields are present in the API call

***
## What's next * [Account Fees (Private Market)](/retail-media/docs/account-fees) * [Brands](/retail-media/docs/brands) * [Sellers](/retail-media/docs/sellers) * [Retailers](/retail-media/v2025.07/docs/retailers) # Account Fees (Private Market) Source: https://developers.criteo.com/retail-media/docs/account-fees ## Introduction The **Account Fees API** allows Private Market retailers to manage fee settings for their accounts through the external API. This includes retrieving fees for one or more accounts and updating those fees where permitted. *** ## Endpoints

Verb

Endpoint

Description

POST

/accounts/fees/search

This endpoint allows users to retrieve fee settings for one or more accounts they have access to.

POST

/accounts/fees/update

This endpoint allows Private Market retailers to update fees for child seller or demand accounts.

*** ## Search Account Fees ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/fees/search ``` This endpoint allows users to retrieve fee settings for one or more accounts they have access to. You can find more details in the API reference for this endpoint [here](/retail-media/reference/accounts/account-fees-search). This endpoint does not require `Account Manage` scope nor consent to the parent supply account. *** ### Attributes

Attribute

Data Type

Description

accountIds

list

Account ID

Up to 25 account IDs can be queried at once.

Accepted values: string of int64

Writeable: Y/ Nullable: N

*** ### Optional Query Parameters

Query Parameters

Data Type

Description

offsite

integer

Pagination parameter, see API Response

limit

integer

Pagination parameter, see API Response

fields

list

Comma-separated list of optional attributes to include in the response.

Used to optimize response time and payload length.

*** ### Sample request ```bash cURL theme={null} curl -L -X POST "https://api.criteo.com/{version}/retail-media/accounts/fees/search" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "data": { "attributes": { "accountIds": [ "667131474078658560", "680116036401160192" ] }, "type": "AccountFeesSearchRequest" } }' ``` ```python Python expandable theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": { "attributes": { "accountIds": [ "667131474078658560", "680116036401160192" ] }, "type": "AccountFeesSearchRequest" } }) headers = { 'Authorization': 'Bearer ', 'Content-Type': 'application/json', 'Accept': 'application/json' } conn.request( "POST", "/{version}/retail-media/accounts/fees/search", payload, headers ) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder().build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, """ { "data": { "attributes": { "accountIds": [ "667131474078658560", "680116036401160192" ] }, "type": "AccountFeesSearchRequest" } } """); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/fees/search") .method("POST", body) .addHeader("Authorization", "Bearer ") .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/fees/search'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig([ 'follow_redirects' => TRUE ]); $request->setHeader([ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', 'Accept' => 'application/json' ]); $request->setBody(json_encode([ "data" => [ "attributes" => [ "accountIds" => [ "667131474078658560", "680116036401160192" ] ], "type" => "AccountFeesSearchRequest" ] ], JSON_PRETTY_PRINT)); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` Please note that: * `accountIds` is optional. * `accountIds: [""]` → returns an **empty response**. * `accountIds: []` → returns **all accounts the user has consent to**. * Up to **25 account IDs** can be queried at once in the request. * Must be sent as **an array** — not as a comma-separated string. *** ### Sample Response ```json expandable theme={null} { "metadata": { "count": 2, "offset": 0, "limit": 50 }, "data": [ { "type": "PrivateMarketAccountFees", "attributes": { "accountId": "667131474078658560", "fees": { "demandManaged": { "rate": 0.40 }, "managedService": { "rate": 0.20, "onsiteSponsoredProductsEnabled": false, "onsiteDisplayEnabled": false } } } }, { "type": "PrivateMarketAccountFees", "attributes": { "accountId": "680116036401160192", "fees": { "demandManaged": { "rate": 0.10 }, "managedService": { "rate": 0.15, "onsiteSponsoredProductsEnabled": true, "onsiteDisplayEnabled": false } } } } ], "warnings": [], "errors": [] } ``` *** ## Update Account Fees (Retailers Only) ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/fees/update ``` This endpoint allows **Private Market retailers** to update fees for child seller or demand accounts. You can find more details about this endpoint in our API reference [here](/retail-media/reference/accounts/update-account-fees). To use this endpoint, users must meet the following requirements: * **OAuth Scope**: `Account Manage` * **Consent**: * To the **parent supply account** * To the **child accounts** for which fees are being managed *** ### Attributes

Attribute

Data Type

Description

Writable

Nullable

accountIds

list

Account ID

Accepted values: string of int64

Y

N

fees

enum

Defines the set of fees you can set on the Account. Possible values:

  • demandManaged : DSP fee on private market demand account
  • managedService : Managed Service fee on private market demand account

N

N

rate

decimal

Value to apply as the demandManaged and/or managedService fee.

Accepted range: 0.00 to 1.00

Max precision: 2 decimal places

Y

N

managedService

enum

The managed service fee that is applied to the account.

Options:

  • onsiteDisplayEnabled
  • onsiteSponsoredProductsEnabled

N

N

onsiteDisplayEnabled

boolean

Indicates if Managed Service fee is enabled for Onsite Display.

Y

N

onsiteSponsoredProductsEnabled

boolean

Indicates if Managed Service fee is enabled for Sponsored Products.

Y

N

*** ### Feature flag This functionality is available only to retailers who have the **Private Market Fees** setting enabled in their UI. If you do not see this feature in your account, please contact your support team or account representative. To have access to this functionality, retailers must: * Have access to the fee configuration UI, * Enable either or both fee types: * **Managed Service Fee** * **Demand Managed Fee** *** ### Sample Request ```bash cURL theme={null} curl -L -X POST "https://api.criteo.com/{version}/retail-media/accounts/fees/update" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "data": { "attributes": { "accountIds": [ "618738804747743232" ], "fees": { "demandManaged": { "rate": "0" }, "managedService": { "onsiteDisplayEnabled": "true", "onsiteSponsoredProductsEnabled": "true", "rate": "0.01" } } }, "type": "AccountFeesUpdateRequest" } }' ``` ```python Python expandable theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": { "attributes": { "accountIds": [ "618738804747743232" ], "fees": { "demandManaged": { "rate": "0" }, "managedService": { "onsiteDisplayEnabled": "true", "onsiteSponsoredProductsEnabled": "true", "rate": "0.01" } } }, "type": "AccountFeesUpdateRequest" } }) headers = { 'Authorization': 'Bearer ', 'Content-Type': 'application/json', 'Accept': 'application/json' } conn.request( "POST", "/{version}/retail-media/accounts/fees/update", payload, headers ) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java expandable theme={null} OkHttpClient client = new OkHttpClient().newBuilder().build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, """ { "data": { "attributes": { "accountIds": [ "618738804747743232" ], "fees": { "demandManaged": { "rate": "0" }, "managedService": { "onsiteDisplayEnabled": "true", "onsiteSponsoredProductsEnabled": "true", "rate": "0.01" } } }, "type": "AccountFeesUpdateRequest" } } """); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/fees/update") .method("POST", body) .addHeader("Authorization", "Bearer ") .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/fees/update'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig([ 'follow_redirects' => TRUE ]); $request->setHeader([ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', 'Accept' => 'application/json' ]); $request->setBody(json_encode([ "data" => [ "attributes" => [ "accountIds" => [ "618738804747743232" ], "fees" => [ "demandManaged" => [ "rate" => "0" ], "managedService" => [ "onsiteDisplayEnabled" => "true", "onsiteSponsoredProductsEnabled" => "true", "rate" => "0.01" ] ] ], "type" => "AccountFeesUpdateRequest" ] ], JSON_PRETTY_PRINT)); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` *** ### Validation Rules * `accountIds` is **required** — omitting it returns a **400 error**. * `demandManaged.rate` must be a **decimal between 0 and 1**. * `managedService.onsiteDisplayEnabled` and `onsiteSponsoredProductsEnabled` must be **boolean** (`true` or `false`). *** ### Sample Response ```json theme={null} { "data": { "type": "AccountFeesUpdateResult", "attributes": { "successfullyUpdatedAccountIds": [ "618738804747743232" ], "failedUpdateAccountIds": [] } }, "warnings": [], "errors": [] } ``` *** ## Responses

Response

Title

🟢

200

Success

🔴

400

Bad Request: Model Validation Error. Check that the acceptable values for the attributes are correct.

🔴

403

API user does not have the authorization to make requests to the account ID. For an authorization request, follow

the authorization request steps

.

*** ### Error responses examples #### Invalid permission ```json theme={null} { "warnings": [], "errors": [ { "type": "authorization", "title": "Authorization error", "detail": "Resource access forbidden: does not have permissions" } ] } ``` #### Rate value is missing ```json theme={null} { "warnings": [], "errors": [ { "traceId": "bb1c3376097f47934484ea67bf8e2755", "type": "validation", "code": "model-validation-error", "title": "Model validation error", "detail": "Error converting value {null} to type 'System.Decimal'. Path 'data.attributes.fees.demandManaged.rate', line 9, position 20." }, { "traceId": "bb1c3376097f47934484ea67bf8e2755", "type": "validation", "code": "model-validation-error", "title": "Model validation error", "detail": "Required property 'rate' expects a value but got null. Path 'data.attributes.fees.demandManaged', line 10, position 9." } ] } ``` ***
# Accounts Endpoints Source: https://developers.criteo.com/retail-media/docs/accounts-endpoints ## Introduction An account represents a brand, agency, marketplace seller, or retailer. It serves as a business and billing entity that contains campaigns. Accounts are created by Criteo.\ Please reach out to your account representative. *** ## Endpoint

Method

Endpoint

Description

GET

/accounts

Get all Accounts

*** ## Account Attributes

Attribute

Data Type

Description

id

string

Account ID, from a demand or supply account (generated internally by Criteo)

Accepted values: string of int64

Writeable? N / Nullable? N

name

string

Account name, arbitrary and defined at account creation

Accepted values: up to 510-chars string

Writeable? Y / Nullable? N

type

enum

Account type, with supply being the account type for Retailers and demand the account type for the different types of advertisers (brand, marketplace sellers, agencies, etc.)

Accepted values: demand , supply

Writeable? N / Nullable? N

subtype

enum

Account sub-specific for demand accounts

Accepted values: brand , seller

Writeable? N / Nullable? Y

countries

list\\

Countries associated with the account

Accepted values: 2-chars country code (in ISO-3166 alpha-2 code; e.g. US , FR )

Writeable? N / Nullable? N

currency

string

Default currency for bulling, budgeting, bid settings & campaign performance metrics

Accepted values: 3-chars currency code (in ISO-4217; e.g. USD , EUR )

Writeable? N / Nullable? N

parentAccountLabel

string

Label used to associate multiple accounts

Accepted values: up to 510-chars string

Default: same as name

Writeable? Y / Nullable? N

timeZone

string

Account time zone

Accepted values: time zone identifiers from IANA (TZ database) (e.g. America/New\_York , Europe/Paris , Asia/Tokyo , UTC )

Writeable? N / Nullable? N

companyName

string

This optional field, exclusively accessible to marketplaces within the European Union (in compliance with the Digital Service Act - DSA), will display the name of the company associated with the advertisement.

Accepted values: up to 255-chars string

Writeable? Y / Nullable? Y

onBehalfCompanyName

string

This optional field, exclusively accessible to marketplaces within the European Union (in compliance with the Digital Service Act - DSA), will display the name of the company (on behalf of companyName ) associated with the advertisement

Accepted values: up to 255-chars string

Writeable? Y / Nullable? Y

### **Digital Service Act (DSA)** In compliance with the Digital Services Act (DSA), marketplaces within the European Union will receive information about the company name associated with each advertisement. *** ## Get All Accounts This endpoint lists all accounts accessible via your API credentials. Results are paginated using `pageIndex` and `pageSize` query parameters; if omitted, defaults to `0` and `25`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). **View in the API Reference** You can also see this endpoint in the [API reference](/retail-media/reference/authorization/get-token). **Sample Request** ```bash cURL theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/accounts?pageIndex=0&pageSize=25" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/accounts?pageSize=25&pageIndex=0" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts?pageSize=25&pageIndex=0") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts?pageSize=25&pageIndex=0'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "metadata": { "totalItemsAcrossAllPages": 2, "currentPageSize": 25, "currentPageIndex": 0, "totalPages": 1 }, "data": [ { "id": "5", "type": "RetailMediaAccount", "attributes": { "name": "Supply Demo Test Account", "type": "supply", "subtype": null, "countries": [ "US" ], "currency": "USD", "parentAccountLabel": "Supply Demo Test Account", "timeZone": "America/New_York", "companyName": "Supply Demo Test Account", "onBehalfCompanyName": "Supply Demo Test Account" } }, { "id": "368471940340928512", "type": "RetailMediaAccount", "attributes": { "name": "RM API Account", "type": "demand", "subtype": "brand", "countries": [ "US" ], "currency": "USD", "parentAccountLabel": "API Account", "timeZone": "America/New_York", "companyName": "RM API Account", "onBehalfCompanyName": "RM API Account" } } ] } ``` ## Responses

Response

Description

🟢 200

Call executed with success

***
## What's next * [Account Creation and Management (Private Market)](/retail-media/docs/account-creation-and-management-private-market) * [Account Fees (Private Market)](/retail-media/docs/account-fees) * [Brands](/retail-media/docs/brands) * [Sellers](/retail-media/docs/sellers) * [Retailers](/retail-media/v2025.07/docs/retailers) # Algebra Nodes Source: https://developers.criteo.com/retail-media/docs/algebra-nodes ## Introduction Algebra nodes are the way to mix different Audience Segments. For example, when you want to include users that belong to more than one segment at the time or if you want to exclude users of a specific segment. Each Audience has one Algebra Node, and within it, you can mix your segments to build the audiences you want. Also, algebra nodes can be mixed together in a flexible way. There are four types of nodes available, and they follow a JSON notation: * **Audience Segment nodes**: Segments with no operator. * **AND nodes**:To include the users that belong simultaneously to all the segments within it (like an intersection). * **OR nodes**: To Include users that belong to any of the segments within it. * **NOT nodes**: To not include the users that belong to the segments within it. *** ## Audience Segment node ```json Examples Audience Segment ID node theme={null} // Target users that belong to a single Audience Segment { "audienceSegmentId": "920472839472539402" } ``` ## AND node Use it to include the users that belong simultaneously to all the segments within it (like an intersection). ```json Examples AND node expandable theme={null} // Target users that belong to three Audience Segments "and": [ { "audienceSegmentId": "920472839472539402" }, { "audienceSegmentId": "233219483716673812" }, { "audienceSegmentId": "333772819393817832" } ] // Target users that belong to two groups of Audience Segments "and": [ { "or": [ { "audienceSegmentId": "920472839472539402" }, { "audienceSegmentId": "233219483716673812" } ] }, { "or": [ { "audienceSegmentId": "826202615157899221" }, { "audienceSegmentId": "100859273425167728" } ] } ] // Target users that belong to the first group of Audience Segments (42914 or 19234) but not on the last one (144219) "and": [ { "or": [ { "audienceSegmentId": "281929273626192303" }, { "audienceSegmentId": "625702934721171442" } ] }, { "not": { "audienceSegmentId": "194652937100327617" } } ] ``` ## OR node ```json Example OR node theme={null} // Target users that belong to any of these Audience Segments { "or": [ { "audienceSegmentId": "194652937100327617" }, { "audienceSegmentId": "100859273425167728" }, { "audienceSegmentId": "826202615157899221" } ] } ``` ## NOT node Use it to not include the users that belong to the segments within it. ```json Example NOT node theme={null} // Target users that do not belong to the single Audience Segment { "not": { "audienceSegmentId": "194652937100327617" } } // Target users that do not belong to any of these Audience Segments { "not": { "or": [ { "audienceSegmentId": "920472839472539402" }, { "audienceSegmentId": "826202615157899221" } ] } } // Target users that do not belong to these Audience Segments { "not": { "and": [ { "audienceSegmentId": "920472839472539402" }, { "audienceSegmentId": "826202615157899221" } ] } } ``` ***
# Demand Side Analytics (DSP) Source: https://developers.criteo.com/retail-media/docs/analytics The Criteo Retail Media Analytics API allows you to scale operations programmatically through our API and integrate Retail Media Platform (RMP) capabilities into your preferred UI or workflow tools. With the Criteo Retail Media API You will be able to download campaign and line item performance reports, including: * Product-level performance and attributed transaction logs, * Report attribution windows and time zones are fully customizable. *** ## Quick Start 1. Request a report 2. Poll for report status 3. Upon success, download the report output ***
## What's next * [Overview](/retail-media/docs/demand-side-analytics-overview) * [Migrating from the legacy reporting API](/retail-media/docs/dsp-analytics-migration-guide) * [Performance Report](/retail-media/docs/performance-report) * [Real-Time Performance Report](/retail-media/docs/real-time-performance-api) * [Missed Opportunities Report](/retail-media/docs/missed-opportunities-report) * [Attributed Transactions Report](/retail-media/docs/attributed-transactions-report) * [Reporting Diagnostic Guide](/retail-media/docs/reporting-overview-diagnostic-guide) # Attributed Transactions Report Source: https://developers.criteo.com/retail-media/docs/attributed-transactions-report POST /reports/attributed-transactions — transaction-level log of every purchase event attributed to Retail Media DSP campaigns. This endpoint enables Retail Media DSP partners to retrieve a transaction-level log of every purchase event attributed to their campaigns. Each row represents a single attributed transaction and captures the product advertised, the product purchased, the attribution rule applied, and the time elapsed between ad delivery and purchase. **This is not a performance report.** Aggregated metrics — impressions, clicks, spend, attributed sales totals — are not available here. Use [`POST /reports/performance`](/retail-media/docs/performance-report) for those. **Primary audience:** Data scientists and analysts auditing attribution methodology, understanding cross-sell and halo effects, or analyzing purchase behavior at the transaction level. Not a day-to-day campaign monitoring workflow. The endpoint supports asynchronous report generation. Submit a request, poll for status, and download the output when ready. *** ## Request ```http theme={null} POST /2026-07/retail-media/reports/attributed-transactions ``` ### Required fields `startDate`, `endDate`, `filters`, `dimensions`, and `metrics` are all required. `filters` must contain exactly one scope filter (`filters.accountIds[]`, `filters.campaignIds[]`, or `filters.lineItemIds[]`). | Field | Type | Description | | ----------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------- | | `startDate` | string | Start of the reporting period. ISO 8601 date (`YYYY-MM-DD`). Based on ad delivery date (`advertisedDate`). | | `endDate` | string | End of the reporting period. ISO 8601 date (`YYYY-MM-DD`). Must be ≥ `startDate`. | | `filters` | object | Required. Must contain exactly one of the scope filters below. | | `filters.accountIds[]` | array of strings | Scope to all line items under this account. Mutually exclusive with `campaignIds` and `lineItemIds`. | | `filters.campaignIds[]` | array of strings | Scope to all line items under this campaign. Mutually exclusive with `accountIds` and `lineItemIds`. | | `filters.lineItemIds[]` | array of strings | Scope to this line item. Mutually exclusive with `accountIds` and `campaignIds`. | | `dimensions` | array of strings | Output columns to return. See [Dimensions](#dimensions) below. | | `metrics` | array of strings | Measure columns to return. See [Metrics](#metrics) below. | ### Optional fields | Field | Type | Default | Description | | ------------------------ | ---------------- | -------------- | ----------------------------------------------------------------------------------------- | | `timezone` | string | `UTC` | Timezone for date fields. IANA format (e.g. `America/New_York`). | | `format` | string | `json-compact` | Output format: `json`, `json-compact`, `json-newline`, or `csv`. | | `clickAttributionWindow` | string | — | Attribution window for click-based conversions: `none`, `7D`, `14D`, or `30D`. | | `viewAttributionWindow` | string | — | Attribution window for view-based conversions: `none`, `1D`, `7D`, `14D`, or `30D`. | | `clickMatchLevel` | string | — | Match level for click attribution: `sameSku`, `sameCategory`, `sameBrand`, or `campaign`. | | `viewMatchLevel` | string | — | Match level for view attribution: `sameSku`, `sameCategory`, `sameBrand`, or `campaign`. | | `filters.mediaTypes[]` | array of strings | — | Filter by media type. | ### Example request ```http theme={null} POST /2026-07/retail-media/reports/attributed-transactions Authorization: Bearer {token} Content-Type: application/json { "data": { "type": "AsyncAttributedTransactionsReport", "attributes": { "startDate": "2026-05-01", "endDate": "2026-05-07", "filters": { "campaignIds": ["301234567890123456"] }, "dimensions": ["advertisedDate", "advertisedProductName", "purchasedProductName", "advertisedToPurchasedProductRelationship"], "metrics": ["attributedSales", "attributedUnits"] } } } ``` *** ## Response A successful request returns `200 OK` with a `reportId`: ```json theme={null} { "data": { "type": "StatusResponse", "id": "345a530c-923a-4571-b4c9-18e7e3e0f3ca", "attributes": { "status": "pending", "rowCount": 0, "fileSizeBytes": 0, "md5CheckSum": null, "createdAt": "2026-07-28T13:37:26.000Z", "expiresAt": null, "message": null, "id": "345a530c-923a-4571-b4c9-18e7e3e0f3ca" } } } ``` Poll for status until `status` is `success` or `failure`: ```http theme={null} GET /2026-07/retail-media/reports/{reportId}/status Authorization: Bearer {token} ``` ```json theme={null} { "data": { "type": "StatusResponse", "id": "345a530c-923a-4571-b4c9-18e7e3e0f3ca", "attributes": { "status": "success", "rowCount": 1221, "fileSizeBytes": 329013, "md5CheckSum": "25406ca38f9e9b7c9dde2136ec0a5739", "createdAt": "2026-07-28T13:37:26.000Z", "expiresAt": "2026-08-04T13:37:27.000Z", "message": "rows_count=1221", "id": "345a530c-923a-4571-b4c9-18e7e3e0f3ca" } } } ``` Download the output when status is `success`: ```http theme={null} GET /2026-07/retail-media/reports/{reportId}/output Authorization: Bearer {token} ``` **Output (first 5 of 1,221 rows):** ```json theme={null} { "columns": ["advertisedDate", "advertisedProductName", "purchasedProductName", "advertisedToPurchasedProductRelationship", "attributedSales", "attributedUnits"], "data": [ ["2026-04-17", "Brand X 36-in French Door Refrigerator - Stainless Steel", "Brand X Front Load Washer - Matte Black", "same brand", 879.99, 1], ["2026-04-17", "Brand X 36-in French Door Refrigerator - Stainless Steel", "Brand X Electric Dryer - Matte Black", "same brand", 879.99, 1], ["2026-04-17", "Brand X Front Load Washer & Dryer WashTower - Graphite Steel", "Brand X Laundry Pedestal with Storage Drawer - White", "same brand", 539.98, 2], ["2026-04-17", "Brand X Front Load Washer & Dryer WashTower - Graphite Steel", "Brand X Stackable Front Load Washer - White", "same category", 829.99, 1], ["2026-04-17", "Brand X Front Load Washer & Dryer WashTower - Graphite Steel", "Brand X Gas Dryer with Wrinkle Care - White", "same brand", 929.99, 1] ], "rows": 1221 } ``` `advertisedDate` reflects when the ad engagement (impression or click) happened, not when the purchase occurred. Because attribution can span several days (per your `clickAttributionWindow` / `viewAttributionWindow`), `advertisedDate` values in the output can fall outside the requested `startDate`/`endDate` range — the date range filters on the transaction date, not `advertisedDate`. Each row in the report output represents one attributed purchase event. *** ## Response Codes For the full list of status and error codes for this endpoint — including `404` (report not found) and `410` (report expired) — see [Response Codes](/retail-media/docs/demand-side-analytics-overview#response-codes) in the Overview. *** ## Metrics Select measures using the `metrics[]` array. `metrics` is required. | Metric | Description | | ----------------- | --------------------------------------------------------------------------- | | `attributedSales` | Revenue attributed to this transaction in the account's reporting currency. | | `attributedUnits` | Units sold in this attributed transaction. | *** ## Dimensions Select output columns using the `dimensions[]` array. `dimensions` is required. The advertised product (`advertised*`) and purchased product (`purchased*`) fields together give the bilateral view described below. Fields marked **Retailer catalog only** are available only for retailers that provide a product catalog to Criteo. For retailers without a catalog, they are not populated. | Dimension | Description | | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `advertisedDate` | Date the ad was delivered (`YYYY-MM-DD`). | | `advertisedHour` | Hour the ad was delivered (0–23). | | `advertisedEngagement` | Type of engagement that triggered attribution: `imp` (impression) or `click`. | | `attributionWindow` | Lookback window applied to this transaction. Format: `C{days}V{days}` (e.g. `C14V07`). | | `daysDifference` | Days between ad delivery and the attributed purchase. | | `advertisedToPurchasedProductRelationship` | Attribution rule that connected the ad to the purchase: `same sku`, `same parent sku`, `same taxonomy`, `same brand`, `same seller`. | | `advertisedProductId` | ID of the product that was advertised. References the Catalogs product ID. | | `advertisedProductName` | Name of the advertised product. | | `advertisedProductCategory` | Category of the advertised product. Standardized categories. **Retailer catalog only.** | | `advertisedProductGtin` | GTIN/EAN/UPC of the advertised product, if available. | | `advertisedProductMpn` | Manufacturer Part Number of the advertised product, if available. | | `purchasedDate` | Date the attributed purchase occurred. | | `purchasedHour` | Hour the attributed purchase occurred (0–23). | | `purchasedProductId` | ID of the product that was purchased. | | `purchasedProductName` | Name of the purchased product. | | `purchasedProductCategory` | Category of the purchased product. Standardized categories. **Retailer catalog only.** | | `purchasedProductGtin` | GTIN/EAN/UPC of the purchased product, if available. | | `purchasedProductMpn` | Manufacturer Part Number of the purchased product, if available. | | `salesChannel` | Channel through which the purchase was made: `online` or `offline`. | | `accountId` | Account ID. | | `accountName` | Account name. | | `campaignId` | Campaign ID. | | `campaignName` | Campaign name. | | `lineItemId` | Line item ID. | | `lineItemName` | Line item name. | | `retailerId` | Retailer ID where the line item served. | | `retailerName` | Retailer name where the line item served. | | `pageType` | Type of retailer page where the ad rendered: `home`, `search`, `productDetail`, `category`, `confirmation`, `checkout`, `merchandising`, `deals`. | | `keyword` | Keyword on the search page where the ad rendered, if applicable. | | `activitySellerId` | ID of the seller responsible for the advertising event. | | `activitySellerName` | Name of the seller responsible for the advertising event. | | `saleSellerId` | ID of the seller responsible for the sale. | | `saleSellerName` | Name of the seller responsible for the sale. | *** ## Understanding the advertised vs. purchased product fields The advertised product (`advertisedProduct*`) and purchased product (`purchasedProduct*`) are often the same — but not always. When the attribution rule is `same brand`, `same taxonomy`, or `same seller`, the ad may have driven a purchase of a related product rather than the exact item advertised. **Example:** An ad for a camping jacket is served. The shopper purchases a different jacket from the same brand. The row will show: * `advertisedProductId`: the advertised jacket * `purchasedProductId`: the purchased jacket * `advertisedToPurchasedProductRelationship`: `same brand` This bilateral product structure makes this endpoint useful for cross-sell and halo analysis — you can see exactly which advertised products drove purchases of which other products, and under which attribution rule. *** ## Data Retention This endpoint supports a lookback window of up to **3 years** (36 months). A request with a `startDate` older than that returns `400 Bad Request` — `StartDate cannot be older than 3 years.` Separately, a single report may span at most **100 days** between `startDate` and `endDate`, regardless of whether you scope by account, campaign, or line item. *** ## Migrating from `reportType: attributedTransactions` Replace your existing call on `/reports/campaigns` or `/reports/line-items` with a call to this endpoint. **Endpoint change:** ``` POST /reports/campaigns → POST /reports/attributed-transactions POST /reports/line-items → POST /reports/attributed-transactions ``` **Request shape changes:** * Replace the top-level `accountId` / `campaignId` / `lineItemId` fields with a `filters` object containing `accountIds[]`, `campaignIds[]`, or `lineItemIds[]` arrays (exactly one scope filter). * Add required `dimensions[]` and `metrics[]` arrays to select output columns — the fields listed above are no longer a fixed response schema; you choose which to return. * `startDate` and `endDate` are required (date-only `YYYY-MM-DD`). * Remove `reportType: attributedTransactions` — it is not accepted on this endpoint. **Field renames:** the `adv`-prefixed fields are now spelled out as `advertised*` (e.g. `advProductId` → `advertisedProductId`, `advDate` → `advertisedDate`, `advEngagement` → `advertisedEngagement`, `advToPurchasedProductRelationship` → `advertisedToPurchasedProductRelationship`). `pageTypeName` is now `pageType`. # Audience Endpoints Source: https://developers.criteo.com/retail-media/docs/audience-endpoints ## Introduction Audiences give the ability to advertisers to define subsets of retailer visitors to be targeted in their campaigns. Audiences are built of one or multiple audience segments that can be combined using logical [Algebra Nodes](/retail-media/docs/algebra-nodes) to define target campaigns' audiences. **Note on Audience Computation** Audience updates are processed daily at 0h UTC and 12h UTC and can take around 5 hours to reflect on a live campaign. This is important for audiences that are frequently updated as changes should be ready for processing prior to these two times. **Partial Approvals** Bulk operations (`create`, `update`, `delete`) use a **partial approval model**. Even if some items in the request fail, the response will return `200 OK`. Any failed items will be listed in the warnings section of the response with an error code and details. Examples of possible warning codes: * `audience-not-found` → Audience is not found. * `name-must-be-unique` → Audience name must be unique. * `name-must-not-be-empty` → Audience name property must not be empty. This list is not exhaustive. Additional warnings may be returned depending on the request context. *** ## Endpoints

Verb

Endpoint

Description

POST

/accounts/\{accountId}/audiences/search

Search for audiences by audience IDs, retailer IDs and/or segment IDs.

*** ## Audience Attributes

Attribute

Data Type

Description

id

string

Audience ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

name

string

Audience name

Accepted values: string

Writeable? Y / Nullable? N

description

string

Description of the Audience

Accepted values: string

Writeable? Y / Nullable? N

accountId

string

Account ID associated with the Audience, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

retailerId \*

string

Retailer ID, associated with the Audience Segment, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

algebra

object

Algebra node with the definition of how the different audience segments are combined together to create the audience, using logical operators and , or and not

Accepted values: see Algebra Nodes

Writeable? N / Nullable? N

createdAt

timestamp

Timestamp of Audience creation, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss.msZ (in ISO-8601 )

Writeable? N / Nullable? N

createdById

string

User ID who created the Audience ( null if created by a service)

Accepted values: string

Writeable? N / Nullable? Y

updatedAt

timestamp

Timestamp of last Audience update, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss.msZ (in ISO-8601 )

Writeable? N / Nullable? N

*\*Required for the`create` operation* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Search Audiences This endpoint returns a list of audiences that match the provided filters. If present, the filters are AND'ed together when applied. You can search audiences by audience IDs, retailer IDs and/or segment IDs. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `500`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). **Sample Request: searching by Retailer ID only** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audiences/search' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' -d '{ "data": { "type": "Audience", "attributes": { "audienceIds": null, "retailerIds": [ "12" ], "audienceSegmentIds": null } } } ``` **Sample Response** ```json expandable theme={null} { "meta": { "totalItems": 400, "limit": 50, "offset": 0 }, "data": [ { "attributes": { "name": "My audience A", "description": null, "createdAt": "2024-01-12T11:46:13.77Z", "updatedAt": "2024-02-12T11:46:13.77Z", "accountId": "625702934721171442", "retailerId": "12", "algebra": { "audienceSegmentId": "56159923678901880" }, "createdById": "j.doe" }, "id": "258216562069631686", "type": "RetailMediaAudience" }, // ... { "attributes": { "name": "My audience B", "description": null, "createdAt": "2024-01-22T14:41:32.489Z", "updatedAt": "2024-01-22T14:41:32.489Z", "accountId": "625702934721171442", "retailerId": "12", "algebra": { "audienceSegmentId": "225702933721195672" }, "createdById": "a.jack" }, "id": "920472839472539402", "type": "RetailMediaAudience" } ], /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` **Sample Request: searching by multiple filters** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audiences/search' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' -d '{ "data": { "type": "Audience", "attributes": { "audienceIds": [ "920472839472539402" ], "retailerIds": [ "12" ], "audienceSegmentIds": [ "225702933721195672" ] } } } ``` **Sample Response** ```json theme={null} { "meta": { "totalItems": 400, "limit": 50, "offset": 0 }, "data": [ { "attributes": { "name": "My audience", "description": null, "createdAt": "2024-01-22T14:41:32.489Z", "updatedAt": "2024-01-22T14:41:32.489Z", "accountId": "625702934721171442", "retailerId": "12", "algebra": { "audienceSegmentId": "225702933721195672" }, "createdById": "a.jack" }, "id": "920472839472539402", "type": "RetailMediaAudience" } ], /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` ***
## What's next * [Audience Segment Endpoints](/retail-media/docs/audience-segment-endpoints) # Audience Segment Endpoints Source: https://developers.criteo.com/retail-media/docs/audience-segment-endpoints ## **Introduction** **Audience Segments** represent groups of users, defined through `Contact Lists` provided externally. Multiple **Audience Segments** can be combined using logical [Algebra Nodes](/retail-media/docs/algebra-nodes) to define the desired target audience for your campaigns. **Partial Approvals** Bulk operations (`create`, `update`, `delete`) use a **partial approval model**. Even if some items in the request fail, the response will return `200 OK`. Any failed items will be listed in the warnings section of the response with an error code and details. Examples of possible warning codes: * `segment-not-found` → Segment is not found. * `name-must-be-unique` → Segment name must be unique. * `name-must-not-be-empty` → Segment name property must not be empty. This list is not exhaustive. Additional warnings may be returned depending on the request context. **Note on event-based targeting** Event-based targeting is currently **not** supported in the Stable version of this API. For event-based targeting, please refer to [the Preview documentation](/retail-media/v2026-preview/docs/audience-segments). **Note on Audience Computation** Audience updates are processed daily at 0h UTC and 12h UTC and can take around 5 hours to reflect on a live campaign. This is important for audiences that are frequently updated as changes should be ready for processing prior to these two times. *** ## Endpoints

Verb

Endpoint

Description

POST

/accounts/\{accountId}/audience-segments/create

Create a new Audience Segment

PATCH

/accounts/\{accountId}/audience-segments

Update an Audience Segment

POST

/accounts/\{accountId}/audience-segments/delete

Delete an Audience Segment

POST

/accounts/\{accountId}/audience-segments/search

Search for Audience Segments by segment IDs, retailer IDs and/or segment types

GET

/accounts/\{accountId}/audience-segments/\{audienceSegmentId}/contact-list

Retrieve contact list statistics

POST

/audience-segments/\{audienceSegmentId}/contact-list/add-remove

Add/remove identifiers in contact list Audience Segment

POST

/audience-segments/\{audienceSegmentId}/contact-list/clear

Clear all identifiers in contact list Audience Segment

*** ## Audience Segment Attributes

Attribute

Data Type

Description

id / audienceSegmentId

string

Audience Segment ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

name \*

string

Audience Segment name

Accepted values: string

Writeable? Y / Nullable? N

description

string

Description of the Audience Segment

Accepted values: string

Writeable? Y / Nullable? N

accountId

string

Account ID associated with the Audience Segment, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

retailerId \*

string

Retailer ID, associated with the Audience Segment, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

type

enum

Type of segment

Accepted values:

ContactList : users segment defined by list of contact identifiers, manageable by the other endpoints

Writeable? Y / Nullable? N

contactList

object

Setting to target users with contact list. Note, either one of contactList or events is required, however both cannot be leveraged at the same time

See below for more details

createdAt

timestamp

Timestamp of Audience Segment creation, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss.msZ (in ISO-8601 )

Writeable? N / Nullable? N

createdById

string

User ID who created the Audience Segment ( null if created by a service)

Accepted values: string

Writeable? N / Nullable? Y

updatedAt

timestamp

Timestamp of last Audience Segment update, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss.msZ (in ISO-8601 )

Writeable? N / Nullable? N

channels

list \

Channels associated to the audience

Accepted values: Onsite , Offsite , Unknown

Writeable? N / Nullable? N

*\*Required at create operation* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Contact List Segment Attributes

Attribute

Data Type

Description

isReadOnly

boolean

Indicates if the contact list can be edited

Accepted values: true , false

Writeable? N / Nullable? N

identifierType

enum

User identifier type from Contact list

Accepted values: Email , UserIdentifier , IdentityLink , CustomerId , Unknown

Writeable? N / Nullable? N

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Create Audience Segment This endpoint allows creating **Audience Segments** from `Contact List`. The corresponding App should have the "**Audiences Manage**" permission enabled. As of now, it is only possible to create Contact List segments through our API. For Users Events Segments, users can rely on the C-Max UI - for more details, check [(Onsite Display) Build an Audience](https://help.retailmedia.criteo.com/kb/guide/en/onsite-display-build-an-audience-5a0BoXiXmP/Steps/2360680) ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/audience-segments/create ``` **Sample Request**: ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/create' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "type": "AudienceSegment", "attributes": { "name": "CRM Users 2025", "description": "Segment made of CRM user emails", "retailerId": "1234", "contactList": { "identifierType": "Email" } } }, ] }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": [ { "type": "AudienceSegment", "attributes": { "name": "CRM Users 2025", "description": "Segment made of CRM user emails", "retailerId": "1234", "contactList": { "identifierType": "Email" } } }, ] }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer <TOKEN>' } conn.request("POST", "/{version}/retail-media/accounts/625702934721171442/audience-segments/create", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":[{\"type\":\"AudienceSegment\",\"attributes\":{\"name\":\"CRM Users 2025\",\"description\":\"Segment made of CRM user emails\",\"retailerId\":\"1234\",\"contactList\":{\"identifierType\":\"Email\"}}}]}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/create") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer <TOKEN>") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/create'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer <TOKEN>' )); $request->setBody('{"data":[{"type":"AudienceSegment","attributes":{"name":"CRM Users 2025","description":"Segment made of CRM user emails","retailerId":"1234","contactList":{"identifierType":"Email"}}}]}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": [ { "id": "738406688413290496", "type": "RetailMediaAudienceSegment", "attributes": { "accountId": "625702934721171442", "name": "CRM Users 2025", "description": "Segment made of CRM user emails", "retailerId": "1234", "type": "ContactList", "createdAt": "2025-07-30T14:44:32.81Z", "updatedAt": "2025-07-30T14:44:32.81Z", "createdById": "514277", "contactList": { "isReadOnly": false, "identifierType": "Email", "sharingStatus": "NotShared" }, "channels": [ "Offsite" ] } } ], "warnings": [], "errors": [] } ``` *** ## Update Audience Segment This endpoint allows updating **Audience Segments**from `Contact List`. Note: the corresponding App should have the "**Audiences Manage**" permission enabled. For `Contact List` segments, it's possible to update their metadata (name and description) but not their identity types. For those cases, create a new segment with the new desired identifier type. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/audience-segments ``` **Sample Request** ```bash cURL theme={null} curl -L -X PATCH 'https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "id": "738406688413290496", "type": "AudienceSegment", "attributes": { "name": "CRM User E-mails 2025 ", "description": "Segment made of CRM user e-mails", "retailerId": "1234", "contactList": { "identifierType": "Email" } } } ] }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": [ { "id": "738406688413290496", "type": "AudienceSegment", "attributes": { "name": "CRM User E-mails 2025 ", "description": "Segment made of CRM user e-mails", "retailerId": "1234", "contactList": { "identifierType": "Email" } } } ] }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer <TOKEN>' } conn.request("PATCH", "/{version}/retail-media/accounts/625702934721171442/audience-segments", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create( mediaType, "{\"data\":[{\"id\":\"738406688413290496\",\"type\":\"AudienceSegment\",\"attributes\":{\"name\":\"CRM User E-mails 2025\",\"description\":\"Segment made of CRM user e-mails\",\"retailerId\":\"1234\",\"contactList\":{\"identifierType\":\"Email\"}}}]}" ); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments") .method("PATCH", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer <TOKEN>") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments'); $request->setMethod(HTTP_Request2::METHOD_PATCH); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer <TOKEN>' )); $request->setBody('{"data":[{"id":"738406688413290496","type":"AudienceSegment","attributes":{"name":"CRM User E-mails 2025","description":"Segment made of CRM user e-mails","retailerId":"1234","contactList":{"identifierType":"Email"}}}]}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": [ { "id": "738406688413290496", "type": "RetailMediaAudienceSegment", "attributes": { "accountId": "4", "name": "CRM Users 2025", "description": "Segment made of CRM user emails", "retailerId": "1234", "type": "ContactList", "createdAt": "2025-07-30T14:44:32.81Z", "updatedAt": "2025-07-30T15:14:19.3566667Z", "createdById": "514277", "contactList": { "isReadOnly": false, "identifierType": "Email", "sharingStatus": "NotShared" }, "channels": [ "Offsite" ] } } ], "warnings": [], "errors": [] } ``` *** ## Delete Audience Segment This endpoint allows deleting **Audience Segments**, either one by one or multiple of them. The corresponding App should have the "**Audiences Manage**" permission enabled. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/audience-segments/delete ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/delete' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "id": "738406561971802112" } ] }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": [ { "id": "738406561971802112" } ] }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer <TOKEN>' } conn.request("POST", "/{version}/retail-media/accounts/625702934721171442/audience-segments/delete", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, '{"data":[{"id":"225702933721171456"}]}'); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/delete") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer <TOKEN>") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/delete'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer <TOKEN>' )); $request->setBody('{"data":[{"id":"225702933721171456"}]}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": [ { "id": "738406561971802112", "type": "RetailMediaAudienceSegment", "attributes": {} } ], "warnings": [], "errors": [] } ``` ### Partial `200 OK` response **Audience Segments cannot be deleted once they have served impressions**. Attempts to delete them will return `200 OK` but include a warning indicating the segment must first be removed from all audiences. ```json theme={null} { "data": [], "warnings": [], "errors": [ { "traceId": "0ab8cdc52e17ecfd1ba9e5d1dacd102a", "traceIdentifier": "0ab8cdc52e17ecfd1ba9e5d1dacd102a", "type": "validation", "code": "segment-must-not-be-used-in-audience", "instance": "@data/0", "title": "Segment must not be used in an audience", "detail": "The segment must be removed from all audiences to be able to delete it" } ] } ``` *** ## Search for Audience Segments This endpoint allows searching for existing **Audience Segments** that satisfy one or multiple attributes at the same time. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `500`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/audience-segments/search ``` **Sample Request:** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/search?limit=50&offset=0' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "AudienceSegment", "attributes": { "audienceSegmentIds": null, "retailerIds": [ "12" ], "audienceSegmentTypes": [ "ContactList", "Events" ] } }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ { "data": { "type": "AudienceSegment", "attributes": { "audienceSegmentIds": None "retailerIds": [ "12" ], "audienceSegmentTypes": [ "ContactList", "Events" ] } } } headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer <TOKEN>' } conn.request("POST", "/{version}/retail-media/accounts/625702934721171442/audience-segments/search?limit=50&offset=0", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, '{"data":{"type":"AudienceSegment","attributes":{"audienceSegmentIds":null,"retailerIds":["12"],"audienceSegmentTypes":["ContactList","Events"]}}}'); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/search?limit=50&offset=0") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer <TOKEN>") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/search?limit=50&offset=0'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer <TOKEN>' )); $request->setBody('{"data":{"type":"AudienceSegment","attributes":{"audienceSegmentIds":null,"retailerIds":["12"],"audienceSegmentTypes":["ContactList","Events"]}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "meta": { "totalItems": 400, "limit": 50, "offset": 0 }, "data": [ { "id": "203134567785554216", "type": "AudienceSegment", "attributes": { "name": "Segment Name", "type": "Events", "createdAt": "2024-01-15T12:23:18.180Z", "updatedAt": "2024-01-15T12:23:18.180Z", "accountId": "625702934721171442", "retailerId": "12", "events": { "shopperActivity": "View", "lookbackDays": "Last90Days", "categoryIds": [ "3590922" ], "brandIds": [] } } }, // ... { "id": "225702933721171456", "type": "AudienceSegment", "attributes": { "name": "Segment Name", "type": "ContactList", "createdAt": "2024-01-23T09:33:40.822Z", "updatedAt": "2024-01-23T09:33:40.822Z", "accountId": "625702934721171442", "retailerId": "12", "contactList": { "isReadOnly": "true", "identifierType": "Email" } } } ], "errors": [], "warnings": [] } ``` *** ## Get Contact List Segment Statistics This endpoint allows retrieving statistics from `Contact List` segments. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/audience-segments/{audienceSegmentId}/contact-list ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET 'https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/225702933721171456/contact-list' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } conn.request("GET", "/{version}/retail-media/accounts/625702934721171442/audience-segments/225702933721171456/contact-list", headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/225702933721171456/contact-list") .method("GET") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/625702934721171442/audience-segments/225702933721171456/contact-list'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer MY_ACCESS_TOKEN>' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "id": "225702933721171456", "identifierType": "AudienceSegment", "attributes": { "numberOfIdentifiers": 10000, "numberOfMatches": 5000, "matchRate": 0.5 } }, "errors": [], "warnings": [] } ``` *** ## Add/Remove identifiers in Contact List Audience Segment This endpoint allows to add/remove users in a specific `Contact List` segment. Note: the corresponding App should have the "**Audiences Manage**" permission enabled.

Attribute

Data Type

Description

operation

enum

Operation required for the sub-set of users provided in the request

Accepted values: add , remove

Writeable? N / Nullable? N

```http theme={null} https://api.criteo.com/{version}/retail-media/audience-segments/{audienceSegmentId}/contact-list/add-remove ``` **Sample Request** - adding users to existing audience segment ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "AddRemoveContactlist", "attributes": { "operation": "add", "identifierType": "email", "identifiers": [ "abc@gmail.com", "def@gmail.com", "aef@gmail.com" ] } } }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ { "data": { "type": "AddRemoveContactlist", "attributes": { "operation": "add", "identifierType": "email", "identifiers": [ "abc@gmail.com", "def@gmail.com", "aef@gmail.com", ] } } } headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer <TOKEN>' } conn.request("POST", "/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, '{"data":{"type":"AddRemoveContactlist","attributes":{"operation":"add","identifierType":"email","identifiers":["abc@gmail.com","def@gmail.com","aef@gmail.com"]}}}'); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer <TOKEN>") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer <TOKEN>' )); $request->setBody('{"data":{"type":"AddRemoveContactlist","attributes":{"operation":"add","identifierType":"email","identifiers":["abc@gmail.com","def@gmail.com","aef@gmail.com"]}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "type": "AddRemoveContactlistResult", "attributes": { "contactListId": 523103620165619700, "operation": "add", "requestDate": "2024-04-22T14:29:07.994Z", "identifierType": "email", "nbValidIdentifiers": 3, "nbInvalidIdentifiers": 0, "sampleInvalidIdentifiers": [] } }, /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` **Sample Request** - removing users from existing audience segment ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "ContactlistAmendment", "attributes": { "operation": "remove", "identifierType": "email", "identifiers": [ "example1@gmail.com" ] } } }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ { "data": { "type": "ContactlistAmendment", "attributes": { "operation": "remove", "identifierType": "email", "identifiers": [ "example1@gmail.com" ] } } } headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer <TOKEN>' } conn.request("POST", "/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, '{"data":{"type":"ContactlistAmendment","attributes":{"operation":"remove","identifierType":"email","identifiers":["example1@gmail.com"]}}}'); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer <TOKEN>") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/add-remove'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer <TOKEN>' )); $request->setBody('{"data":{"type":"ContactlistAmendment","attributes":{"operation":"remove","identifierType":"email","identifiers":["example1@gmail.com"]}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "type": "ContactlistAmendment", "attributes": { "operation": "remove", "requestDate": "2018-12-10T10:00:50.000Z", "identifierType": "email", "nbValidIdentifiers": 7342, "nbInvalidIdentifiers": 13, "sampleInvalidIdentifiers": [ "InvalidIdentifier" ] } }, /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` **Identifier List Size Limit** Note that there is a limit of **50,000 identifiers per single request**. If you are adding more than 50,000 users, please split them into chunks of 50,000 and make multiple requests. *** ## Clear all identifiers in Contact List Audience Segment This endpoint resets a `Contact List segment`, erasing all existing users identifiers. The corresponding App should have the "**Audiences Manage**" permission enabled. ```http theme={null} https://api.criteo.com/{version}/retail-media/audience-segments/{audienceSegmentId}/contact-list/clear ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/clear' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") payload = '' headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } conn.request("POST", "/{version}/retail-media/audience-segments/225702933721171456/contact-list/clear", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/clear") .method("POST", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/audience-segments/225702933721171456/contact-list/clear'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer MY_ACCESS_TOKEN>' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** 🟢 201 Created (empty response body) Note that this will only wipe all of the users from the audience segment and will not delete the audience segment itself. **Note on Audience Computation** Audience updates are processed daily at 0h UTC and 12h UTC and can take around 5 hours to reflect on a live campaign. This is important for audiences that are frequently updated as changes should be ready for processing prior to these two times. ***
# Audiences Source: https://developers.criteo.com/retail-media/docs/audiences An audience represents all users who interacted with specific brands or categories over a defined period, and can be specifically targeted for your campaigns. [Audience Endpoints](/retail-media/docs/audience-endpoints) [Audience Segment Endpoints](/retail-media/docs/audience-segment-endpoints) **CMax Help Center** You can find more information about audiences and audience segments in Criteo C-Max Help Center, on [this page](https://help.retailmedia.criteo.com/kb/guide/en/offsite-build-an-audience-bxFM6LtmvS/Steps/2973790,3269127) for Offsite, and [this page](https://help.retailmedia.criteo.com/kb/guide/en/onsite-display-build-an-audience-5a0BoXiXmP/Steps/2360680) for Onsite Display. ***
## What's next * [Audience Endpoints](/retail-media/docs/audience-endpoints) * [Audience Segment Endpoints](/retail-media/docs/audience-segment-endpoints) * [Algebra Nodes](/retail-media/docs/algebra-nodes) # Balances Source: https://developers.criteo.com/retail-media/docs/balances A balance represents the funds an account can allocate toward campaigns, acting as a spend cap across all campaigns linked to it. When the combined costs of all linked campaigns reach the balance amount, all associated campaigns will stop running, even if this occurs before their scheduled end date. *** ## About Balances * Campaigns must be assigned to **at least one balance** to run. * Balances provide an **additional budget management tool** alongside controls at the campaign or line item level. * In Demand accounts balances are `read-only` through the API; only Admins or Business Managers can create or modify them via the Billing portal. However, in Supply accounts or Private Market accounts balances can be created or modified via the API as long as the user has the proper permissions. *** ## Balance Statuses Balances can have one of the following statuses, which determine whether a balance is currently funding campaigns: * 🟢 **Active:** The balance has available funds, and today's date is within its start and end dates. Linked campaigns can spend from this balance. * 🕒 **Scheduled:** The balance has available funds, but its start date is in the future. Linked campaigns cannot spend from this balance yet. * 🔴 **Ended:** The balance has either run out of funds or is past its end date. Linked campaigns can no longer spend from this balance. *** **CMax Help Center**\ Learn more about balances in the [CMax Help Center](https://help.retailmedia.criteo.com/kb/guide/en/about-balances-dp2VSA0YeL/Steps/973366) ***
## What's next * [Balances Endpoints](/retail-media/docs/balances-endpoints) # Balances Endpoints Source: https://developers.criteo.com/retail-media/docs/balances-endpoints View and manage all available balances across campaigns **Getting Started** Learn more about balances [here](/retail-media/docs/balances#/). **Backward compatibility for balance endpoints:** * The `poNumber` field on balance responses is **removed** in `2026-01` and replaced by two separate fields: `retailerPoNumber` and `criteoPoNumber`. This is a breaking change for consumers of `GET /balances` on prior versions who rely on `poNumber`. * All other new fields (`retailerId`, `privateMarketBillingType`) are additive. Retailer budgets are hidden by default on prior API versions. You can learn more about retailer budgets [on this page](/retail-media/docs/retailer-budgets). *** ## Endpoints

Method

Endpoint

Description

GET

/accounts/\{accountId}/balances

Retrieve all balances associated with a specific account.

GET

/accounts/\{accountId}/balances/\{balanceId}

Retrieve a specific balance

POST

/accounts/\{accountId}/balances

Create a new balance for a specified account.

PATCH

/accounts/\{accountId}/balances/\{balanceId}

Modify balance's metadata (name, start/end date - for deposited funds, see below)

POST

/accounts/\{accountId}/balances/\{balanceId}/add-funds

Add/remove funds deposited in a specific balance.

GET

/balances/\{balanceId}/campaigns

Retrieve all campaigns linked to a specific balance.

POST

/balances/\{balanceId}/campaigns/append

Add campaigns to a specific balance.

POST

/balances/\{balanceId}/campaigns/delete

Remove campaigns from a specific balance.

GET

/balances/\{balanceId}/history

Retrieve all changes made historically to a balance

*** ## Balance Parameters

Attribute

Data Type

Description

id

string

Balance ID

Accepted values: string of int64

Writeable? N / Nullable? N

name \*

string

Balance name

Accepted values: up to 255-char strings

Writeable? Y / Nullable? N

deposited

decimal

Amount of funds deposited; uncapped if null

Accepted values: deposited ≥ 0.0

Writeable? Y / Nullable? Y

spent

decimal

Amount of funds already spent

Accepted values: 0 ≤ spent deposited

Writeable? N / Nullable? N

remaining

decimal

Amount of funds already spent

Accepted values: 0 ≤ remaining deposited (or null , if deposited not set)

Writeable? N / Nullable? Y

startDate \*

timestamp

Balance start date; if time zone is not set, will consider Account 's time zone as default

Accepted values: yyyy-mm-dd (in ISO-8601 )

Writeable? Y / Nullable? N

endDate

timestamp

Balance end date; if time zone is not set, will consider Account 's time zone as default

Accepted values: yyyy-mm-dd (in ISO-8601 )

Default: if null or absent, balance will be available indefinitely

Writeable? Y / Nullable? Y

status

enum

Balance current status

Accepted values: active , scheduled , ended , unknown

Writeable? N / Nullable? N

createdAt

timestamp

Timestamp of balance creation, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601 )

Writeable? N / Nullable? N

updatedAt

timestamp

Timestamp of last balance update, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601 )

Writeable? N / Nullable? N

memo

string

An optional memo note that can be set in the balance

Accepted values: up to 250-char strings

Writeable? Y / Nullable? Y

balanceType

enum

The balance type is computed based on the deposited amount:

Accepted values: capped , uncapped , unknown

Writeable? N / Nullable? N

  • capped : if the deposited amount is provided.
  • uncapped : when there is no amount defined (set to null )

spendType \*

enum

The type of balance that will be used based on the campaign type

Accepted values: onsite , offsite , offsiteAwareness , lockout , unknown

Writeable? N / Nullable? N

privateMarketBillingType

enum

Billing type of the balance

Accepted values: notApplicable , billByRetailer , billByCriteo

⚠️ Note :

  • balances created through the API will, automatically, be denoted as billByRetailer
  • only balances denoted as billByRetailer can be modified through the API
  • billByCriteo are balances created in our Commerce Max platform and can only be edited in our UI
  • notApplicable is an initial or default value if the privateMarketBillingType is not set yet. If it is observed it would be treated as the default value billByRetailer .

Writeable? N / Nullable? N

retailerId

string

Retailer this balance is scoped to.

Present only on retailer budgets.

Nullable? Y (null for balances without retailer budgets)

retailerPoNumber

string?

Retailer purchase order number. Replaces the removed poNumber field.

Nullable? Y

criteoPoNumber

string?

Criteo purchase order number.

Replaces the removed poNumber field.

Nullable? Y

poNumber

string

Purchase order number.

Removed since 2026.01 and replaced by retailerPoNumber and criteoPoNumber

Accepted values: up to 32-char strings

Writeable? Y / Nullable? Y

*\*Required for Balance creation* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Balance History Parameters

Attribute

Data Type

Description

dateOfModification

timestamp

Timestamp of balance update

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601 )

Writeable? N / Nullable? N

modifiedByUser

string

Username who modified the insertion order

Accepted values: strings in format "j.doe"

Writeable? N / Nullable? N

changeType

enum

Definition of the type of change in a balance

Accepted values: balanceCreated, balanceAdded, balanceRemoved, balanceCapped, balanceUncapped, balanceName, endDate, startDate, retailerPoNumber, criteoPoNumber, retailerId, valueAdd, unknown

  • BalanceCreated : new balance is created
  • BalanceUncapped : capped balance is changed to uncapped
  • BalanceCapped : uncapped balance is changed to capped
  • StartDate : start date is modified
  • EndDate : end date is modified

changeDetails

object

Structure with the change details (from Balance History endpoint)

Parameters:

  • previousValue : previous value of a property of the balance
  • currentValue : current value of a property of the balance
  • changeValue : change value of a property of the balance
*** ## Get all Balances for an Account This endpoint lists all balances in an account. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `25`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/balances ``` On API version `2026-07` and later, retailer budgets are included and `retailerId`, `retailerPoNumber`, and `criteoPoNumber` are returned. The old `poNumber` field is removed.\ Learn more on retailer budgets [here](/retail-media/docs/retailer-billed). **Legacy version behavior (`2026-01` and earlier):** Only standard Criteo budget balances are returned. `retailerId`, `retailerPoNumber`, and `criteoPoNumber` are not present in the response. The legacy `poNumber` field is present. **Sample Request** ```bash cURL theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances?offset=0&limit=25" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances?offset=0&limit=25" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances?offset=0&limit=25") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances?offset=0&limit=25'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response - Versions prior to `2026.07`** ```json JSON expandable theme={null} { "metadata": { "totalItemsAcrossAllPages": 94, "currentPageSize": 25, "currentPageIndex": 0, "totalPages": 4, "nextPage": "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances?pageIndex=1&pageSize=25" }, "data": [ { "id": "14094543095747588032", "type": "BalanceResponseV2", "attributes": { "name": "Balance 123", "poNumber": "13993827", "memo": "uncapped balance, free to spend!", "deposited": null, "spent": 42931.28, "remaining": null, "startDate": "2020-04-06", "endDate": null, "status": "active", "createdAt": "2020-04-06T00:02:41+00:00", "updatedAt": "2020-04-06T00:02:41+00:00", "balanceType": "uncapped", "spendType": "Onsite", "privateMarketBillingType": "notApplicable" } }, // ... { "id": "4237496305219757554", "type": "BalanceResponseV2", "attributes": { "name": "Balance 789", "poNumber": "", "memo": "10k for the special 2s-day promotion", "deposited": 10000.00, "spent": 923.40, "remaining": 9076.60, "startDate": "2025-02-01", "endDate": null, "status": "scheduled", "createdAt": "2025-01-06T00:48:11+00:00", "updatedAt": "2025-01-07T22:19:57+00:00", "balanceType": "capped", "spendType": "Onsite", "privateMarketBillingType": "notApplicable" } } ] } ``` **Sample response - Versions `2026.07`onward** ```json expandable theme={null} { "metadata": { "count": 135, "offset": 0, "limit": 25 }, "data": [ { "id": "100000000000000001", "type": "BalanceV1", "attributes": { "name": "Sample Name", "retailerPoNumber": null, "criteoPoNumber": "PO-CRITEO-123", "retailerId": null, "memo": "Sample memo", "deposited": 10.0, "spent": 10.0, "remaining": 0.0, "startDate": "2020-04-13", "endDate": null, "status": "ended", "createdAt": "2020-04-13T15:39:48+00:00", "updatedAt": "2023-06-13T13:35:53+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "notApplicable" } }, { "id": "100000000000000002", "type": "BalanceV1", "attributes": { "name": "Sample Name", "retailerPoNumber": "PO-RETAILER-123", "criteoPoNumber": "PO-CRITEO-123", "retailerId": 123, "memo": "Sample memo", "deposited": 100.0, "spent": 0.16, "remaining": 99.84, "startDate": "2026-03-24", "endDate": null, "status": "active", "createdAt": "2026-03-24T18:15:58+00:00", "updatedAt": "2026-05-20T17:17:40+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "notApplicable" } } ], "warnings": [], "errors": [] } ``` *** ## Get Specific Balance Retrieves the balance details of one specific balances belonging to an account. Returns a single balance including the retailer scoping fields. The `poNumber` field present on prior API versions will be removed in `2026-07`. **Legacy version behavior (`2026-01` and earlier):** Returns `400` with `"This version endpoint doesn't support retailer-sold balance. Use latest version instead."` when the requested balance is a retailer budget balance. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/balances/{balanceId} ``` **Sample Request** ```bash theme={null} curl -L 'https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/4237496305219757554' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json theme={null} { "data": { "id": "100000000000000001", "type": "BalanceV1", "attributes": { "name": "Sample Name", "retailerPoNumber": null, "criteoPoNumber": "PO-CRITEO-123", "retailerId": 123, "memo": "Sample memo", "deposited": 100.0, "spent": 0.16, "remaining": 99.84, "startDate": "2026-03-24", "endDate": null, "status": "active", "createdAt": "2026-03-24T18:15:58+00:00", "updatedAt": "2026-05-20T17:17:40+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "notApplicable" } }, "warnings": [], "errors": [] } ``` *** ## Create a New Account Balance This endpoint creates a new balance in the specified account. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/balances ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "name": "Balance 2025 Q1", "startDate": "2025-01-01", "spendType": "onsite", "retailerPoNumber": null, "deposited": 12500.00, "endDate": "", "memo": "Balance for campaigns in 2025 Q1" } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances" payload = json.dumps({ "data": { "attributes": { "name": "Balance 2025 Q1", "startDate": "2025-01-01", "spendType": "onsite", "retailerPoNumber": None, "deposited": 12500.00, "endDate": "", "memo": "Balance for campaigns in 2025 Q1" } } }) headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"attributes\":{\"name\":\"Balance 2025 Q1\",\"startDate\":\"2025-01-01\",\"spendType\":\"onsite\",\"retailerPoNumber\":null,\"deposited\":12500.00,\"endDate\":\"\",\"memo\":\"Balance for campaigns in 2025 Q1\"}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"attributes":{"name":"Balance 2025 Q1","startDate":"2025-01-01","spendType":"onsite","retailerPoNumber":null,"deposited":12500.00,"endDate":"","memo":"Balance for campaigns in 2025 Q1"}}}'); try{ $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "id": "697385288434028544", "type": "BalanceV1", "data": { "attributes": { "name": "Balance 2025 Q1", "retailerPoNumber": null, "criteoPoNumber": null, "memo": "Balance for campaigns in 2025 Q1", "deposited": 12500.00, "spent": 0.00, "remaining": 12500.00, "startDate": "2025-01-01", "endDate": null, "status": "active", "createdAt": "2025-04-08T10:00:09+00:00", "updatedAt": "2025-04-08T10:00:09+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "billByRetailer" } }, "warnings": [], "errors": [] } ``` *** ## Modify Balance Metadata This endpoint modifies the metadata of a specified balance, like `name`, `retailerPoNumber`, `startDate` or `endDate`. To modify deposited funds, check the following endpoint. Only Balances created through the API can be modified through this endpoint, i.e., with billing type `billByRetailer`.\ Retailer budget balances are **read-only via API**. Any `PATCH` request against a retailer budget balance returns `403` regardless of API version.\ Balance attributes (dates, PO numbers, amounts) are managed by Criteo on behalf of the retailer. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/balances/{balanceId} ``` **Sample Request** ```bash cURL theme={null} curl -L -X PATCH 'https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "startDate": "2025-01-01", "endDate": {"value": "2025-04-01"}, "retailerPoNumber": "PO 12345", "memo": "Balance for campaigns in 2025 Q1 (with start and end date)" } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544" payload = json.dumps({ "data": { "attributes": { "startDate": "2025-01-01", "endDate": {"value": "2025-04-01"}, "retailerPoNumber": "PO 12345", "memo": "Balance for campaigns in 2025 Q1 (with start and end date)" } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("PATCH", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"attributes\":{\"startDate\":\"2025-01-01\",\"endDate\":{\"value\":\"2025-04-01\"},\"retailerPoNumber\":\"PO 12345\",\"memo\":\"Balance for campaigns in 2025 Q1 (with start and end date)\"}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544") .method("PATCH", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"attributes":{"startDate":"2025-01-01","endDate":{"value":"2025-04-01"},"retailerPoNumber":"PO 12345","memo":"Balance for campaigns in 2025 Q1 (with start and end date)"}}}'); try{ $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "id": "697385288434028544", "type": "BalanceV1", "attributes": { "name": "Balance 2025 Q1", "retailerPoNumber": "PO 12345", "criteoPoNumber": null, "memo": "Balance for campaigns in 2025 Q1 (with start and end date)", "deposited": 12500.00, "spent": 0.00, "remaining": 12500.00, "startDate": "2025-01-01", "endDate": "2025-04-01", "status": "active", "createdAt": "2025-04-08T10:00:09+00:00", "updatedAt": "2025-04-08T10:00:09+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "billByRetailer" }, "warnings": [], "errors": [] } ``` *** ## Add or Remove Balance Funds This endpoint allows adding or removing funds deposited in a specific balance. Only Balances created through the API can be modified through this endpoint, ie, with billing type `billByRetailer` This endpoint only accepts `deltaAmount`, `retailerPoNumber`, and `memo`. Any other parameters (e.g. `endDate`) are silently ignored — no error is returned, but the value is not applied. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/balances/{balanceId}/add-funds ``` **Request Body Parameters**

Attribute

Data Type

Description

deltaAmount \*

decimal

Difference amount of fund to be added/removed from balance; it cannot reduce the current amount of funds deposited to less than zero

Accepted values: deltaAmount deposited \* (-1)

Writeable? N / Nullable? N

retailerPoNumber

string

New retailer purchase order number

Accepted values: up to 32-char strings

Writeable? Y / Nullable? Y

memo

string

A memo note that should be set in the balance together with this modification

Accepted values: up to 250-char strings

Writeable? Y / Nullable? Y

*\*Required* **Sample Request** ```bash cURL theme={null} curl -L -X PATCH 'https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544/add-funds' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "deltaAmount": -2500.00, "retailerPoNumber": "PO 12346", "memo": "Reduced balance for campaigns in 2025 Q1" } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544/add-funds" payload = json.dumps({ "data": { "attributes": { "deltaAmount": -2500.00, "retailerPoNumber": "PO 12346", "memo": "Reduced balance for campaigns in 2025 Q1" } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"attributes\":{\"deltaAmount\": -2500.00,\"retailerPoNumber\":\"PO 12346\",\"memo\":\"Reduced balance for campaigns in 2025 Q1\"}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544/add-funds") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances/697385288434028544/add-funds'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"attributes":{"deltaAmount":-2500.00,"retailerPoNumber":"PO 12346","memo":"Reduced balance for campaigns in 2025 Q1"}}}'); try{ $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "id": "697385288434028544", "type": "BalanceV1", "attributes": { "name": "Balance 2025 Q1", "retailerPoNumber": "PO 12346", "criteoPoNumber": null, "memo": "Reduced balance for campaigns in 2025 Q1", "deposited": 10000.00, "spent": 0.00, "remaining": 10000.00, "startDate": "2025-01-01", "endDate": "2025-04-01", "status": "active", "createdAt": "2025-04-08T10:00:09+00:00", "updatedAt": "2025-04-08T10:00:09+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "billByRetailer" }, "warnings": [], "errors": [] } ``` *** ## Get all Campaigns on a Specific Balance This endpoint lists all campaigns on the specified balance. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `25`, respectively — see [API Response](/criteo-apis/docs/api-response) ```http theme={null} https://api.criteo.com/{version}/retail-media/balances/{balanceId}/campaigns ``` **Response Body Parameters**

Attribute

Data Type

Description

id

string

Campaign ID, respective to the campaign(s) currently appended to the balance

Accepted values: string of int64

Writeable? N / Nullable? N

**Sample Request** ```bash cURL theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/balances/14094543095747588032/campaigns?offset=0&limit=25" \ -H "Authorization: Bearer " ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/balances/14094543095747588032/campaigns?offset=0&limit=25") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/balances/14094543095747588032/campaigns?offset=0&limit=25" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/balances/14094543095747588032/campaigns?offset=0&limit=25'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": [ { "id": "8343086999167541140", "type": "RetailMediaCampaign" }, { "id": "3683145960016759663", "type": "RetailMediaCampaign" } ], "metadata": { "count": 2, "offset": 0, "limit": 25 } } ``` *** ## Add Campaigns to a Specific Balance This endpoint adds one or more campaigns to the specified balance. The results are provided in a single page. In this example, a campaign had already existed on the balance before two new additions. The API enforces compatibility between the campaigns and the balance — all must share the same billing type, retailer (for retailer budget), and demand account. If any campaign in the request fails validation, **the entire request is rejected** and no campaigns are mapped. **Validation rules:** * All campaigns must be retailer budget campaigns when the balance is a retailer budget balance (and vice versa) — otherwise `BillingTypeMismatchWithBalance` * The `retailerId` on every campaign must match the balance's `retailerId` — otherwise `RetailerMismatchWithBalance` * All campaigns must belong to the same demand account as the balance — otherwise `403` ```http theme={null} https://api.criteo.com/{version}/retail-media/balances/{balanceId}/campaigns/append ``` **Request Body Parameters**

Attribute

Data Type

Description

data.attributes.ids

array of strings

Campaign IDs to append or remove from the balance

Accepted values: array of int64 strings

Writeable? Y / Nullable? N

**Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/balances/{balanceId}/campaigns/append' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "AppendCampaignsRequest", "attributes": { "ids": ["100000000000000001", "100000000000000002"] } } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "BalanceCampaignsV1", "attributes": { "ids": ["100000000000000001", "100000000000000002"] } }, "warnings": [], "errors": [] } ``` *** ## Remove Campaigns from a Specific Balance This endpoint removes one or more campaigns from the specified balance. The response contains the remaining mapped campaign IDs after removal. Legacy versions (`2025-10` and earlier) will return an error `500`. ```http theme={null} https://api.criteo.com/{version}/retail-media/balances/{balanceId}/campaigns/delete ``` **Request Body Parameters**

Attribute

Data Type

Description

data.attributes.ids

array of strings

Campaign IDs to append or remove from the balance

Accepted values: array of int64 strings

Writeable? Y / Nullable? N

**Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/balances/{balanceId}/campaigns/delete' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "DeleteCampaignsRequest", "attributes": { "ids": ["100000000000000001"] } } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "BalanceCampaignsV1", "attributes": { "ids": ["100000000000000002"] } }, "warnings": [], "errors": [] } ``` *** ## Get Balance History This endpoint lists all changes made to a specific balance. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `500`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). Additional query parameter `limitToChangeTypes` can be used to inform a comma-separated list of `changeType` values. **Retailer Budgets** Returns a chronological list of changes to a balance. PO number updates appear as separate entries keyed by `changeType` — not as field keys on every entry. **Observed `changeType` values:** `balanceCreated`, `balanceAdded`, `balanceRemoved`, `balanceCapped`, `balanceUncapped`, `balanceName`, `endDate`, `startDate`, `criteoPoNumber`, `retailerPoNumber`, `retailerId`, `valueAdd`, `unknown` Each entry's `changeDetails` carries: * `previousValue` — value before the change * `currentValue` — value after the change * `changeValue` — delta where applicable (e.g. `ValueAdd`); `null` otherwise **Legacy version behavior (`2026-01` and earlier):** Returns `400` with `”This version endpoint doesn't support retailer-sold balance. Use latest version instead.”` when the requested balance is a retailer budget balance. **Modified Users** `modifiedByUser` - When a balance is updated via Criteo's Retail Media UI, the user login name will be provided. For instance, if “Kip Heaney” updated the balance on 2023-11-07, it indicates that Kip made the change through the Criteo Retail Media UI. If a balance is updated through the Criteo API, the name of the API application responsible for the change will be shown. For example, on 2024-03-20, the balance was updated by the API application **Retail Media API Application.** ```http theme={null} https://api.criteo.com/{version}/retail-media/balances/{balanceId}/history ``` **Sample Request**: retrieve all changes ```bash theme={null} curl -L -X GET 'https://api.criteo.com/{version}/retail-media/balances/{balanceId}/history' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response**: retrieve all changes ```json theme={null} { “metadata”: { “count”: 4, “offset”: 0, “limit”: 25 }, “data”: [ { “type”: “BalanceHistoryChangeDataCaptureV1”, “attributes”: { “changeType”: “balanceCreated”, “changeDetails”: { “previousValue”: null, “currentValue”: “100.00”, “changeValue”: null }, “dateOfModification”: “2026-03-24T14:15:58-04:00”, “modifiedByUser”: “User123”, “memo”: null } }, { “type”: “BalanceHistoryChangeDataCaptureV1”, “attributes”: { “changeType”: “criteoPoNumber”, “changeDetails”: { “previousValue”: null, “currentValue”: “PO-CRITEO-123”, “changeValue”: null }, “dateOfModification”: “2026-03-24T14:16:28-04:00”, “modifiedByUser”: “User123”, “memo”: null } }, { “type”: “BalanceHistoryChangeDataCaptureV1”, “attributes”: { “changeType”: “retailerPoNumber”, “changeDetails”: { “previousValue”: null, “currentValue”: “PO-RETAILER-123”, “changeValue”: null }, “dateOfModification”: “2026-03-24T14:16:45-04:00”, “modifiedByUser”: “User123”, “memo”: null } } ], “warnings”: [], “errors”: [] } ``` *** ## Responses

Response

Title

Detail

Troubleshooting

🟢 200

Call executed with success

🟢 201

Balance request created with success

🔴 400

Error deserializing request

Field xyz is not valid

Review the value of field xyz provided in the request

🔴 400

Change data capture type xxx is not supported

Change data capture type xxx is not supported

The value of limitToChangeTypes is not supported for /balances/\{balanceId} /history * ensure to use a comma-separated list of available changeType values defined above

🔴 400

Invalid name

Balance name should be unique. There exists balance with the specified name. Balance creation/update has been canceled

Check value of name in the request trying to create/edit a balance. In case of editing, either provided a new name value or omit this parameter to maintain its same value

🔴 400

Invalid deltaamount

Can not decrease funds to less than zero

Review value of deltaAmount and make sure it's greater than current balance's deposited \* (-1)

🔴 400

Invalid operation

Can only change the field xxx of a balance not billed by retailer.

Cannot edit balances not created through the API; only balances with billing type billByRetailer can be modified

🔴 400

Invalid operation

Can not add funds to a balance not billed by retailer.

Cannot edit balances not created through the API; only balances with billing type billByRetailer can be modified

🔴 403

Authorization error

Resource access forbidden: does not have permissions

One of the permission levels was not respected. Make sure that the respective API app has access to:

  • Read/Manage the domain "Balance" (depending on the requested action). Review the Types of Permissions in Authorization Requests
  • the accountId or balanceId provided in the request
### Balance Append Endpoint Errors The "append" endpoint uses a different error code from campaign create: `code: "campaigns-balance-mapping-validation-error"`, `title: "Validation error"`. The specific mismatch type is identified by a bracketed prefix in the `detail` field. | Status | `code` | `detail` prefix | Description | | :------ | :------------------------------------------- | :------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------- | | 🔴`400` | `campaigns-balance-mapping-validation-error` | `[retailer-id-mismatch]` | The `retailerId` on one or more campaigns in `ids` doesn't match the balance's `retailerId`. Entire request rejected — no campaigns are mapped. | | 🔴`400` | `campaigns-balance-mapping-validation-error` | `[balance-type-mismatch]` | Billing type mismatch — e.g. retailer budget campaign appended to a Criteo budget balance, or vice versa. Entire request rejected. | | 🔴`403` | — | — | Campaigns in `ids` belong to a different demand account than the balance. | ### Balance Modify Endpoint Error | Status | Body | Meaning | | :------ | :--------------------------------------------- | :---------------------------------------------------------------------------------------------------- | | 🔴`403` | RFC 9110 HTTP Forbidden (no custom error body) | Retailer budget balances are read-only via API. `PATCH` is always rejected regardless of API version. | ### Legacy Version Access | Status | `code` | `title` | When | | :------ | :----------------- | :------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ | | 🔴`400` | `validation-error` | `"This version endpoint doesn't support retailer-sold balance. Use latest version instead."` | Accessing a retailer budget balance or its history via the account-scoped path on `2025-10` or earlier. | | 🔴`500` | (empty body) | — | `POST /balances/{balanceId}/campaigns/delete` on `2025-10` or earlier. | ***
# Bid Multipliers Source: https://developers.criteo.com/retail-media/docs/bid-multipliers ## Introduction The Criteo engine maximizes advertising performance while optimizing the shopper experience. It can automatically and intelligently control how much a line item delivers on each page type. In addition, bid multipliers provide campaign managers more control over managing bids at the line item level while also optimizing campaign performance goals at a page-type level. Bid multipliers are available at the Onsite Sponsored Products line items level. In addition, campaign managers can modify bids only on enabled page types. Bids can be **increased up to 500%** or **decreased up to 50%** on each page targeted at the line item level. **For example:** If a line item bid is \$1, with a bid multiplier, you can increase the Search page bid by 20% and decrease the homepage bid by 10%. The Criteo engine will optimize more delivery and performance on the search page while also allowing the control of which page types budget is mostly allocated towards. *** ## Endpoints

Verb

Endpoint

Description

GET

/line-items/\{lineItemId}/bid-multipliers

Returns all bid multipliers per page types of the specified line item.

PUT

/line-items/\{lineItemId}/bid-multipliers

Updates bid multipliers with new values or reset to default one.

*** ## Bid Multiplier Attributes

Attribute

Data Type

Description

id

string

Line item ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

home

decimal

Bid multiplier to the home page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 home 6.0

Default: 1.0

Writeable? Y / Nullable? N

search

decimal

Bid multiplier to the search page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 search 6.0

Default: 1.0

Writeable? Y / Nullable? N

category

decimal

Bid multiplier to the category page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 category 6.0

Default: 1.0

Writeable? Y / Nullable? N

productDetail

decimal

Bid multiplier to the productDetail page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 productDetail 6.0

Default: 1.0

Writeable? Y / Nullable? N

merchandising

decimal

Bid multiplier to the merchandising page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 merchandising 6.0

Default: 1.0

Writeable? Y / Nullable? N

deals

decimal

Bid multiplier to the deals page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 deals 6.0

Default: 1.0

Writeable? Y / Nullable? N

favorites

decimal

Bid multiplier to the favorites page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 favorites 6.0

Default: 1.0

Writeable? Y / Nullable? N

searchBar

decimal

Bid multiplier to the searchBar page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 searchBar 6.0

Default: 1.0

Writeable? Y / Nullable? N

categoryMenu

decimal

Bid multiplier to the categoryMenu page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 categoryMenu 6.0

Default: 1.0

Writeable? Y / Nullable? N

checkout

decimal

Bid multiplier to the checkout page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 checkout 6.0

Default: 1.0

Writeable? Y / Nullable? N

confirmation

decimal

Bid multiplier to the confirmation page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 confirmation 6.0

Default: 1.0

Writeable? Y / Nullable? N

aiAssistant

decimal

Bid multiplier to the aiAssistant page type

Note: bids can be increased up to 500% (6.0) or decreased up to 50% (0.50)

Accepted values: 0.50 aiAssistant 6.0

Default: 1.0

Writeable? Y / Nullable? Y

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Get Bid Multipliers Returns all bid multipliers for page types of the specified line item. This endpoint returns all possible page types supported by our platform, including the ones not currently supported by the respective retailer associated with the line item. For the effective list of supported page types, please refer to [Retailers](/retail-media/v2025.07/docs/retailers) ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/bid-multipliers ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET 'https://api.criteo.com/{version}/retail-media/line-items/347413132777078784/bid-multipliers' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer MY_ACCESS_TOKEN' ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/line-items/347413132777078784/bid-multipliers" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer MY_ACCESS_TOKEN' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/347413132777078784/bid-multipliers") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer MY_ACCESS_TOKEN") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/347413132777078784/bid-multipliers'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer MY_ACCESS_TOKEN' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "type": "LineItemBidMultipliersV2", "attributes": { "id": "347413132777078784", "home": 1.90, "search": 1.10, "category": 1.50, "productDetail": 1.60, "merchandising": 1.70, "deals": 2.00, "favorites": 2.30, "searchBar": 1.00, "categoryMenu": 1.10, "checkout": 2.50, "confirmation": 1.30 } }, "warnings": [], "errors": [] } ``` *** ## **Update Bid Multipliers** Replaces all existing bid multipliers with the provided bid multipliers or the default value, i.e., `1.0`. A **`PUT`** operation with empty attributes object will reset all values to their default values. ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/bid-multipliers ``` **Sample Request** ```bash cURL theme={null} curl -L -X PUT 'https://api.criteo.com/{version}/retail-media/line-items/347112182987198464/bid-multipliers' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer MY_ACCESS_TOKEN' \ --data-raw '{ "data": { "id": "347112182987198464", "type": "RetailMediaBidMultiplier" "attributes": { "home": "1.90", "search": "1.10", "category": "1.50", "productDetail": "1.60", "merchandising": "1.70", "deals": "2.00", "favorites": "2.30", "searchBar": "1.00", "categoryMenu": "1.10", "checkout": "2.50", "confirmation": "1.30" } } }' ``` ```python Python expandable theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/line-items/347112182987198464/bid-multipliers" payload = json.dumps({ "data": { "id": "347112182987198464", "type": "RetailMediaBidMultiplier", "attributes": { "home": "1.90", "search": "1.10", "category": "1.50", "productDetail": "0.49", "merchandising": "1.70", "deals": "2.00", "favorites": "2.30", "searchBar": "1.00", "categoryMenu": "1.10", "checkout": "2.50", "confirmation": "1.30", } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer MY_ACCESS_TOKEN' } response = requests.request("PUT", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"id\":\"347112182987198464\",\"type\":\"RetailMediaBidMultiplier\",\"attributes\":{\"home\":\"1.90\",\"search\":\"1.10\",\"category\":\"1.50\",\"productDetail\":\"1.60\",\"merchandising\":\"1.70\",\"deals\":\"2.00\",\"favorites\":\"2.30\",\"searchBar\":\"1.00\",\"categoryMenu\":\"1.10\",\"checkout\":\"2.50\",\"confirmation\":\"1.30\"}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/347112182987198464/bid-multipliers") .method("PUT", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer MY_ACCESS_TOKEN") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl( "https://api.criteo.com/{version}/retail-media/line-items/347112182987198464/bid-multipliers" ); $request->setMethod(HTTP_Request2::METHOD_PUT); $request->setConfig([ "follow_redirects" => true, ]); $request->setHeader([ "Content-Type" => "application/json", "Accept" => "application/json", "Authorization" => "Bearer MY_ACCESS_TOKEN", ]); $request->setBody('{"data":{"id":"347112182987198464","type":"RetailMediaBidMultiplier","attributes":{"home":"1.90","search":"1.10","category":"1.50","productDetail":"1.60","merchandising":"1.70","deals":"2.00","favorites":"2.30","searchBar":"1.00","categoryMenu":"1.10","checkout":"2.50","confirmation":"1.30"}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo "Unexpected HTTP status: " . $response->getStatus() . " " . $response->getReasonPhrase(); } } catch (HTTP_Request2_Exception $e) { echo "Error: " . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "id": 347112182987198464, "type": "LineItemBidMultipliersV2", "attributes": { "home": 1.90, "search": 1.10, "category": 1.50, "productDetail": 0.50, "merchandising": 1.70, "deals": 2.00, "favorites": 2.30, "searchBar": 1.00, "categoryMenu": 1.10, "checkout": 2.50, "confirmation": 1.30 } }, "warnings": [], "errors": [] } ``` *** ## Responses

Response

Description

🔵 200

Call executed with success

🔴 400

BidMultiplierOutOfRange

A bid multiplier provided is out of range of the expected range and could not be accepted

IllegalValueProvided

An invalid page type or poorly formatted bid multiplier was provided

🔴 401

Unauthorized

User doesnt have permission to edit a specified line item

🔴 404

LineItemDoesntExist

Attempted to fetch or manipulate a line item that does not exist

*** ## What's next * [Budget Overrides](/retail-media/docs/budget-overrides) * [Minimum Bid](/retail-media/docs/minimum-bid) # Billing Source: https://developers.criteo.com/retail-media/docs/billing ## Introduction The Partner Billing Report is a dedicated report that **enables retailers to bill their retailer-contracted advertisers, manage invoicing,** and **track payments for advertisers** who have contracted directly with them, especially in private market setups. It also enables the ability to **verify retailer-related fees and media costs associated with campaigns managed through CMax & CYield**. This ensures transparency and accuracy in financial reconciliations. *** ## Quick Start 1. Request a report 2. Poll for report status 3. Upon success, download the report output *** ## Things to Know * Reports are requested and retrieved via asynchronous endpoints. * The report date range supports a maximum window of 31 days. * Reports are generated at a [Line Items](/retail-media/docs/line-items) granularity, i.e., `Demand account` x `Campaign` x `Line-Item` * Data is processed and batched daily. * Reports are cached for, at least, 1 hour before expiration. Learn more in our Account & Billing section in [CMax Help Center](https://help.retailmedia.criteo.com/kb/en/account-billing-127261). ***
## What's next * [Partner Billing Report](/retail-media/docs/partner-billing-report) * [PBR Metrics](/retail-media/docs/pbr-metrics) # Brands Source: https://developers.criteo.com/retail-media/docs/brands ## Introduction A brand is a collection of products marketed and sold under a unified name. The brands associated with an account define the products that the account can promote on retailer sites. An account can have access to one or more brands, and this access is typically managed by Criteo. Brand attributes are standardized across retailers to ensure consistency. *** ## Endpoints

Method

Endpoint

Description

GET

/accounts/\{accountId}/brands

Get Brands

POST

/brands/search

Search for Brands by name in Retailer(s) Catalogs

*** ## Brand Attributes

Attribute

Data Type

Description

id

string

Brand ID, generated internally by Criteo and originated from brand name provided in retailer's Catalog

Accepted values: int64

Writeable? N / Nullable? N

name

string

Brand name, keyword to use as filter in the search (case-insensitive) or returned as final brand name available

Accepted values: string

Writeable? N / Nullable? N

retailerIds \*

list

List of Retailer IDs, to use as filter in the search or returned as containing the specific brand

Accepted values: list of strings of int32

Writeable? N / Nullable? N

brandType

enum

Type of brands, to consider in the search or returned as attribute of the specific brand

  • all : all brands
  • retailer : brands specific to the retailer
  • uc : brands referenced to our Universal Catalog

Accepted values: all , retailer , uc (case-insensitive)

Default: all

Writeable? N / Nullable? N

(\*) *Required* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Get all Brands This endpoint lists all brands associated with an account. Results are paginated using `pageIndex` and `pageSize` query parameters; if omitted, defaults to `0` and `25`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/brands ``` ### Sample Request ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/brands?pageIndex=0&pageSize=25" \ -H 'Accept: application/json' \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/accounts/4/brands?pageIndex=0&pageSize=25" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/4/brands?pageIndex=0&pageSize=25") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/4/brands?pageIndex=0&pageSize=25'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` ### Sample Response ```json theme={null} { "data": [ { "id": "7672171780147256541", "type": "RetailMediaBrand", "attributes": { "name": "Brand 123" } }, // ... { "id": "5979998329674492121", "type": "RetailMediaBrand", "attributes": { "name": "Brand 789" } } ], "metadata": { "totalItemsAcrossAllPages": 15, "currentPageSize": 25, "currentPageIndex": 0, "totalPages": 1, "nextPage": null, "previousPage": null } } ``` *** ## Search for Brands by name This endpoint searches for Brands, by name term, across one or multiple retailers. Results are paginated. ```http theme={null} https://api.criteo.com/{version}/retail-media/brands/search ``` ### Sample Request ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/brands/search?offset=0&limit=25' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "", "attributes": { "retailerIds": [ "123", "456" ], "name": "brand abc", "brandType": "all" } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/brands/search?offset=0&limit=25" payload = json.dumps({ "data": { "type": "", "attributes": { "retailerIds": [ "123", "456" ], "name": "brand abc", "brandType": "all" } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"type\":\"\",\"attributes\":{\"retailerIds\":[\"123\",\"456\"],\"name\":\"brand abc\",\"brandType\":\"all\"}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/brands/search?offset=0&limit=25") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/brands/search?offset=0&limit=25'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"type":"","attributes":{"retailerIds":["123","456"],"name":"brand abc","brandType":"all"}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` ### Sample Response ```json expandable theme={null} { "metadata": { "count": 2, "offset": 0, "limit": 25 }, "data": [ { "id": "2149023412134133", "type": "BrandIdSearchResult", "attributes": { "id": "2149023412134133", "name": "brand abcdef", "brandType": "Retailer", "retailerIds": [ 123 ] } }, { "id": "62342", "type": "BrandIdSearchResult", "attributes": { "id": "62342", "name": "Brand ABC", "brandType": "UC", "retailerIds": [ 123, 456 ] } } ], "warnings": [], "errors": [] } ``` *** ## Responses

Response

Error

Message

Description

🟢 200

Call completed successfully

🔴 400

Validation Error

One or more validation errors occurred.

One of the parameters provided in the request does not match the format accepted. Check the error details and the parameters informed in the call

🔴 403

Authorization Error

Resource access forbidden: does not have permissions

API user does not have the authorization to make requests to the account ID. For an authorization request, follow the authorization request steps

***
## What's next * [Sellers](/retail-media/docs/sellers) * [Retailers](/retail-media/v2025.07/docs/retailers) # Budget Overrides Source: https://developers.criteo.com/retail-media/docs/budget-overrides This feature provides more flexibility that allow advertisers to override a line-item budget for specific days or months. ## Introduction You can set a monthly/daily budget override to temporarily spend more or less than the current monthly/daily budget for the months you specify. The override will take effect at midnight in your time zone on the first day of the month or first day of the range you select. *** ## Endpoints

Method

Endpoint

Description

GET

/campaigns/\{campaignId}/campaign-budget-overrides

Retrieves all existing budget overrides at the campaign level.

PUT

/campaigns/\{campaignId}/campaign-budget-overrides

Replaces all existing campaign budget override settings. Use this endpoint can be used to add/remove or update existing budget overrides.

GET

/line-items/\{lineItemId}/line-item-budget-overrides

Retrieves all existing budget overrides at the line-item level.

PUT

/line-items/\{lineItemId}/line-item-budget-override

Replaces all existing line-item budget override settings. Use this endpoint to add/remove or update existing budget overrides.

*** ## Budget Override Attributes

Attribute

Data Type

Description

monthlyBudgetOverrides

list \

Line item budget override monthly part, chronological order restricted

Parameters:

  • startMonth
  • duration
  • maxMonthlySpend
  • status

dailyLineItemBudgetOverrides

list \

Line item budget override daily part, chronological order restricted

Parameters:

  • startDate
  • duration
  • maxDailySpend
  • status

startMonth

string

Start month of monthly budget override.

  • *Note*\*: if null , the startMonth would be the following month of the last item in the override sequence.

Accepted values: strings of date YYYY-MM

Writeable? Y / Nullable? Y

startDate

date

Start date of daily budget override

  • *Note*\*: if null , the startDate would be the following date of the last item in the override sequence

Accepted values: YYYY-MM-DD

Writeable? Y / Nullable? Y

duration

string

The number of months (for monthly Budget Override) or days (daily Budget Override) that the override is active, from startMonth or startDate , respectively

Accepted values:

  • 1M , 2M , 3M ... for monthly override (must end with M or m )
  • 1D , 2D , 3D ... for daily override (must end with D or d )

Writeable? Y / Nullable? N

maxMonthlySpend

decimal

Monthly budget override maximum monthly spend amount

Accepted values: maxMonthlySpend ≥ 0.0

Writeable? Y / Nullable? N

maxDailySpend

decimal

Daily budget override maximum daily spend amount

Accepted values: maxDailySpend ≥ 0.0

Writeable? Y / Nullable? N

status

enum

Monthly or daily budget override computed status

Accepted values: Expired , Active , Upcoming

Writeable? N / Nullable? N

*** ## Get Campaign Budget Override Retrieves all existing budget overrides at campaign level: ```http theme={null} https://api.criteo.com/{version}/retail-media/campaigns/{campaignId}/campaign-budget-overrides ``` **Sample Request** ```bash theme={null} # Request curl -L 'https://api.criteo.com/{version}/retail-media/campaigns/446397494514737152/campaign-budget-overrides' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json expandable theme={null} { "data": { "type": "CampaignBudgetOverrides", "attributes": { "monthlyBudgetOverrides": [ { "startMonth": "2023-12", "duration": "1M", "maxMonthlySpend": 100.00, "status": "Expired" }, { "duration": "1M", "maxMonthlySpend": 200.00, "status": "Active" }, { "startMonth": "2024-03", "duration": "1M", "maxMonthlySpend": 150.00, "status": "Upcoming" } ], "dailyBudgetOverrides": [ { "startDate": "2023-12-01", "duration": "10D", "maxDailySpend": 50.00, "status": "Expired" } ] } }, "warnings": [], "errors": [] } ``` *** ## Update Campaign Budget Override ```http theme={null} https://api.criteo.com/{version}/retail-media/campaigns/{campaignId}/campaign-budget-overrides ``` **Sample Request** ```bash expandable theme={null} # Request curl -L -X PUT 'https://api.criteo.com/{version}/retail-media/campaigns/446397494514737152/campaign-budget-overrides' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "UpdateBudgetOverride", "attributes": { "dailyBudgetOverrides": [ { "duration": "15d", "maxDailySpend": "1", "startDate": "2024-01-01", "status": "Active" }, { "duration": "15d", "maxDailySpend": "2", "startDate": "2024-01-16", "status": "Active" } ], "monthlyBudgetOverrides": [ { "duration": "1M", "maxMonthlySpend": "10", "startMonth": "2024-01", "status": "Active" } ] } } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "CampaignBudgetOverrides", "attributes": { "monthlyBudgetOverrides": [ { "startMonth": "2024-01", "duration": "1M", "maxMonthlySpend": 10.00, "status": "Active" } ], "dailyBudgetOverrides": [ { "startDate": "2024-01-01", "duration": "15D", "maxDailySpend": 1.00, "status": "Active" }, { "duration": "15D", "maxDailySpend": 2.00, "status": "Upcoming" } ] } }, "warnings": [], "errors": [] } ``` *** ## Get Line Item Budget Override Retrieves all existing budget overrides at line item level: ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/line-item-budget-overrides ``` **Sample Request** ```bash theme={null} # Request curl -L 'https://api.criteo.com/{version}/retail-media/line-items/446397611671216128/line-item-budget-overrides' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json expandable theme={null} { "data": { "type": "LineItemBudgetOverrides", "attributes": { "monthlyLineItemBudgetOverrides": [ { "startMonth": "2023-12", "duration": "2M", "maxMonthlySpend": 100.00, "status": "Upcoming" } ], "dailyLineItemBudgetOverrides": [ { "startDate": "2023-07-13", "duration": "19D", "maxDailySpend": 10.00, "status": "Expired" }, { "startDate": "2023-12-01", "duration": "15D", "maxDailySpend": 10.00, "status": "Upcoming" } ] } }, "warnings": [], "errors": [] } ``` *** ## Update Line Item Budget Override ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/line-item-budget-overrides ``` Be careful with overlapping different overrides Budget overrides cannot overlap. When scheduling a new override make sure it doesn't overlap with the duration of other overrides to avoid `400` validation errors. fdb6c02 image **Sample Request** ```bash expandable theme={null} // Sample Request curl -L -X PUT 'https://api.criteo.com/{version}/retail-media/line-items/446397611671216128/line-item-budget-overrides' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "", "attributes": { "dailyLineItemBudgetOverrides": [ { "duration": "5D", "startDate": "2023-12-01", "maxDailySpend": "5", "status": "Upcoming" }, { "duration": "5D", "startDate": "2023-12-06", "maxDailySpend": "2", "status": "Upcoming" }, { "duration": "2D", "startDate": "2023-12-11", "maxDailySpend": "5", "status": "Upcoming" } ], "monthlyLineItemBudgetOverrides": [ { "duration": "3M", "maxMonthlySpend": "12", "startMonth": "2023-12", "status": "Upcoming" }, { "duration": "3M", "maxMonthlySpend": "12", "startMonth": "2024-03", "status": "Upcoming" } ] } } }' ``` **Sample Response** ```json expandable theme={null} { "data": { "type": "LineItemBudgetOverrides", "attributes": { "monthlyLineItemBudgetOverrides": [ { "startMonth": "2023-12", "duration": "6M", "maxMonthlySpend": 12.00, "status": "Upcoming" } ], "dailyLineItemBudgetOverrides": [ { "startDate": "2023-12-01", "duration": "5D", "maxDailySpend": 5.00, "status": "Upcoming" }, { "duration": "5D", "maxDailySpend": 2.00, "status": "Upcoming" }, { "duration": "2D", "maxDailySpend": 5.00, "status": "Upcoming" } ] } }, "warnings": [], "errors": [] } ``` *** ## **Responses**

Response

Description

🔵 200

Call executed with success

🔵 201

Budget override was created with success

🔴 400

  • *validation-errors*\*:
  • *Budget override dates must not overlap any existing budget overrides for this campaign / line item*
  • *Duration of daily budget override must end with D or d*
  • *Duration of monthly budget override must end with M or m*
***
## What's next * [Minimum Bid](/retail-media/docs/minimum-bid) # Campaigns Source: https://developers.criteo.com/retail-media/docs/campaign This page is an overview of how to get started with Campaigns ## The Campaign Level Campaigns are created at the account level and are composed of one or several Line Items. 1f0bfaf l2 campaign *** ## Open Auction Campaigns An Open Auction campaign operates on a first-price auction model using cost-per-click (CPC). Advertisers set their bid for each shopper interaction with their ad, competing in an inventory auction to secure ad placements. **Important to know:** * A campaign represents a marketing objective and includes line items. * Campaigns can contain line items across multiple brands and retailers. * Campaigns offer optional controls for budgeting and attribution windows. * Budgets can also be managed at the line item level. * Various [reports](/retail-media/docs/report-types) are available to track and measure campaign performance. * Accounts are capped at 100,000 active campaigns. * Currently, only Open Auction campaigns are supported via the API. *** ## Quick Start 1. **Select products** to promote from your account catalog. 2. **Create a campaign** to define your marketing objective. 3. **Create a line item** within the campaign. 4. **Add products to the line item** to specify what you are promoting. 5. **Assign the campaign** to an account balance to manage spending. 6. **Activate your line item** to start running the campaign! ***
## What's next * [Campaigns Endpoints](/retail-media/docs/campaigns-endpoints) # Campaigns Endpoints Source: https://developers.criteo.com/retail-media/docs/campaigns-endpoints View and manage all your campaigns ## Endpoints | Method | Endpoint | Description | | ------------------------------------------------------------- | -------- | ----------- | | Create a new campaign for the specified account. | | | | Retrieve all campaigns associated with the specified account. | | | | Retrieve details of a specific campaign by its ID. | | | | Update details of a specific campaign by its ID. | | | **Create Operations:** * When using the `POST` method to create a resource, all Required fields must be included. Any Optional fields that are omitted will be set to their default values. **Update Operations:** * When using the `PUT` method to update a resource, all Write fields can be specified. Omitting any of these fields is treated as setting them to `null`, where applicable. *** ## Campaign Attributes | Attribute | Data Type | Description | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | ----------- | | Campaign ID, generated internally by Criteo Accepted values: int64 Writeable? N / Nullable? N | | | | Accepted values: int64 Writeable? N / Nullable? N | | | | Accepted values: up to 255-chars string Writeable? Y / Nullable? N | | | | Campaign type If the attribute is passed in the call, a value must be specified Writeable? Y / Nullable? N | | | | Note that preferred campaign types cannot have budgets as these campaign types must be uncapped Accepted values: equals/greater than zero Writeable? Y / Nullable? Y | | | | Amount the campaign has already spent Accepted values: equals/greater than zero Writeable? N / Nullable? N | | | | Writeable? N / Nullable? Y | | | | Accepted values: list of strings Default: empty list Writeable? N / Nullable? N | | | | Post-click attribution window Writeable? Y / Nullable? N | | | | Post-view attribution window Writeable? Y / Nullable? N | | | | Post-click attribution scope Writeable? Y / Nullable? N | | | | Post-view attribution scope Writeable? Y / Nullable? N | | | | Default: empty list Writeable? Y / Nullable? N | | | | Writeable? N / Nullable? N | | | | The maximum monthly spend allowed for the campaign in the currency of the account. The spend is constrained by remaining account balance and total budget of the campaign. Monthly budget spend reset monthly at the start of the month based on the account timezone Writeable? Y / Nullable? Y | | | | Writeable? Y / Nullable? Y | | | | Writeable? Y / Nullable? N | | | | Campaign start date. The campaign starts inactive if invalid start date is not today or end date is in previous day. Default: creation timestamp Writeable? Y / Nullable? Y | | | | Campaign end date. The campaign starts inactive if invalid start date is not today or end date is in previous day Writeable? Y / Nullable? Y | | | | Timestamp of campaign creation, in UTC Writeable? N / Nullable? N | | | | Timestamp of last campaign update, in UTC Writeable? N / Nullable? N | | | | This optional field, exclusively accessible to marketplaces within the European Union (in compliance with the Digital Service Act - DSA), will display the name of the company associated with the advertisement. Accepted values: up to 255-chars string Writeable? Y / Nullable? Y | | | | Accepted values: up to 255-chars string Writeable? Y / Nullable? Y | | | | The retailer this campaign is associated with. Required when using a retailer budget balance. Writeable? Y (at create) / Nullable? Y (for non-retailer-budget campaigns) | | | (\*) *Required for create operations* ### **Digital Service Act (DSA)** In compliance with the Digital Services Act (DSA), marketplaces within the European Union will receive information about the company name associated with each advertisement. *** ## Create a Campaign This endpoint creates a Sponsored Products (`type: auction`) or Onsite Display (`type: preferred`) campaign. **Retailer budget vs Criteo budget:** Including `retailerId` in the request creates a retailer budget campaign. Omitting `retailerId` (or setting it to `null`) creates a standard Criteo budget campaign — `retailerId` will be `null` in the response. **Balance mapping at create time:** You may optionally include `drawableBalanceIds` to map the campaign to one or more retailer budget balances at creation. All compatibility rules apply (same retailer, same billing type, same demand account). You can also map balances separately after creation using `POST /balances/{balanceId}/campaigns/append`. **Note on `403` vs `400`** A `403` on campaign create means the `retailerId` you set is not recognized as an authorized retailer for your account. A `400` with a specific mismatch code means the retailer is valid but incompatible with the balance you included (see [Error responses](#responses)). **Legacy version behavior (`2025-10` and earlier):** Returns `400` when attempting to create a retailer budget campaign. **Retailer Budgets Campaigns** When creating a campaign for a retailer-budget balance, `retailerId` must be provided and must match the `retailerId` of the balance. Mismatched values will return a `RetailerMismatchWithBalance` error. Learn more about Retailer budgets [here](/retail-media/docs/retailer-budgets). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/campaigns ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/campaigns' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "Campaign", "attributes": { "name": "My Retailer Budget Campaign", "type": "auction", "retailerId": "123", "drawableBalanceIds": ["100000000000000001"], "startDate": "2026-06-01T00:00:00+00:00", "clickAttributionWindow": "30D", "viewAttributionWindow": "none", "clickAttributionScope": "sameSkuCategory", "viewAttributionScope": "sameSkuCategory", "isAutoDailyPacing": false } } }' ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "100000000000000001", "type": "RetailMediaCampaignV202301", "attributes": { "accountId": "123", "promotedBrandIds": [], "budgetSpent": 0.0, "budgetRemaining": null, "status": "inactive", "createdAt": "2026-05-29T20:33:27+00:00", "updatedAt": "2026-05-29T20:33:27+00:00", "type": "auction", "drawableBalanceIds": ["100000000000000001"], "clickAttributionWindow": "30D", "viewAttributionWindow": "none", "retailerId": 123, "name": "My Retailer Budget Campaign", "budget": null, "monthlyPacing": null, "dailyPacing": null, "isAutoDailyPacing": false, "startDate": "2026-06-01T00:00:00+00:00", "endDate": null, "clickAttributionScope": "sameSkuCategory", "viewAttributionScope": "sameSkuCategory", "companyName": null, "onBehalfCompanyName": null } } } ``` *** ## Get All Campaigns by Account ID This endpoint returns all campaigns for an account. As of `2026-01`, `retailerId` is included in each campaign's attributes. Use the `retailerId` query parameter to filter campaigns by retailer. **Legacy version behavior (`2025-10` and earlier):** Retailer budget campaigns are not returned; `retailerId` is not present in the attribute set. Results are paginated using `pageIndex` and `pageSize` query parameters; if omitted, defaults to `0` and `25`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/campaigns ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET 'https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/campaigns' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json expandable theme={null} { "metadata": { "totalItemsAcrossAllPages": 2533, "currentPageSize": 2, "currentPageIndex": 8, "totalPages": 153, "currentPageSize": 25, "currentPageIndex": 0, "totalPages": 102 }, "data": [ { "id": "100000000000000001", "type": "RetailMediaCampaignV202301", "attributes": { "accountId": "123", "promotedBrandIds": [], "budgetSpent": 0.0, "budgetRemaining": null, "status": "inactive", "createdAt": "2026-05-29T20:00:47+00:00", "updatedAt": "2026-05-29T20:00:47+00:00", "type": "auction", "drawableBalanceIds": ["100000000000000002"], "clickAttributionWindow": "30D", "viewAttributionWindow": "none", "retailerId": 123, "name": "Sample Name", "budget": null, "monthlyPacing": null, "dailyPacing": null, "isAutoDailyPacing": false, "startDate": "2026-06-01T00:00:00+00:00", "endDate": null, "clickAttributionScope": "sameSkuCategory", "viewAttributionScope": "sameSkuCategory", "companyName": null, "onBehalfCompanyName": null } } ] } ``` *** ## Get a Specific Campaign This endpoint retrieves the specified campaign. As of `2026-07`, `retailerId` is included in the response attributes. Retailer budget campaigns also surface `criteoPoNumber` and `retailerPoNumber` from the mapped balance. **Legacy version behavior (`2026-01` and earlier):** Returns `400` for retailer budget campaigns. ```http theme={null} https://api.criteo.com/{version}/retail-media/campaigns/{campaignId} ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET 'https://api.criteo.com/{version}/retail-media/campaigns/{campaignId}' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "100000000000000001", "type": "RetailMediaCampaignV202301", "attributes": { "accountId": "123", "promotedBrandIds": [], "budgetSpent": 0.0, "budgetRemaining": null, "status": "inactive", "createdAt": "2026-05-29T20:00:47+00:00", "updatedAt": "2026-05-29T20:00:47+00:00", "type": "auction", "drawableBalanceIds": ["100000000000000002"], "clickAttributionWindow": "30D", "viewAttributionWindow": "none", "retailerId": 123, "name": "Sample Name", "budget": null, "isAutoDailyPacing": false, "startDate": "2026-06-01T00:00:00+00:00", "endDate": null, "clickAttributionScope": "sameSkuCategory", "viewAttributionScope": "sameSkuCategory", "companyName": null, "onBehalfCompanyName": null } } } ``` *** ## Update a Specific Campaign This endpoint allows you to update a specified campaign. The following example demonstrates how to switch to an uncapped campaign budget and modify the post-view attribution window. **Legacy version behavior (`2025-10` and earlier):** Returns `400` for retailer budget campaigns. ```http theme={null} https://api.criteo.com/{version}/retail-media/campaigns/{campaignId} ``` **Sample Request** ```bash cURL theme={null} curl -L -X PUT 'https://api.criteo.com/2026-01/retail-media/campaigns/{campaignId}' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "Campaign", "attributes": { "name": "Updated Campaign Name", "endDate": "2026-12-31T23:59:59+00:00" } } }' ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "100000000000000001", "type": "RetailMediaCampaignV202301", "attributes": { "accountId": "123", "promotedBrandIds": [], "budgetSpent": 0.0, "budgetRemaining": null, "status": "inactive", "createdAt": "2026-05-29T20:00:47+00:00", "updatedAt": "2026-05-29T20:00:47+00:00", "type": "auction", "drawableBalanceIds": ["100000000000000002"], "clickAttributionWindow": "30D", "viewAttributionWindow": "none", "retailerId": 123, "name": "Sample Name", "budget": null, "isAutoDailyPacing": false, "startDate": "2026-06-01T00:00:00+00:00", "endDate": null, "clickAttributionScope": "sameSkuCategory", "viewAttributionScope": "sameSkuCategory", "companyName": null, "onBehalfCompanyName": null } } } ``` *** ## Responses All validation errors on **campaign create** use `code: "validation-error"`. The error type is identified by a bracketed prefix in the `title` field. | Status | Title | Description | | :------- | :------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 🟢 `200` | | Call completed with success | | 🟢 `201` | | Campaign was created successfully | | 🔴 `400` | `[retailer-id-mismatch]` | The `retailerId` on the campaign doesn't match the `retailerId` on one of the balances in `drawableBalanceIds`. Also returned when balances from multiple retailers are included. | | 🔴 `400` | `[balance-type-mismatch]` | Billing type mismatch — e.g. retailer budget campaign with a Criteo budget balance. | | 🔴 `400` | `[account-mismatch]` | The balance in `drawableBalanceIds` belongs to a different demand account than the campaign being created. | | 🔴 `403` | `authorization-unknown` | The `retailerId` in the request is not recognized as an authorized retailer for this account. Use `GET /retailers/search` to discover eligible retailers first. | | 🔴 `400` | Invalid `isAutoDailyPacing` | Cannot turn on `IsAutoDailyPacing` and add a `DailyPacing` value. `IsAutoDailyPacing` and `Daily Pacing` cannot be active at the same time. | | 🔴 `400` | Invalid `Budget` | Budget is not allowed for the Preferred campaign. | | 🔴 `400` | `RetailerMismatchWithBalance` | Campaign `retailerId` does not match the balance `retailerId`. Ensure the `retailerId` in campaign settings matches the `retailerId` on the balance you are associating. | | 🔴 `400` | `BillingTypeMismatchWithBalance` | The billing type on the campaign doesn't match the billing type on the balance. | | 🔴 `400` | `AccountMismatchWithBalance` | The balance in `drawableBalanceIds` does not belong to the request account. | | 🔴 `400` | `RetailerMismatchWithCampaign` | The line item `targetRetailerId` does not match the campaign's `retailerId`. | ***
# Catalog Endpoints Source: https://developers.criteo.com/retail-media/docs/catalog-endpoints Generate and download a copy of retailer's inventory # Endpoints

Method

Endpoint

Description

POST

/accounts/\{accountId}/catalogs

Create a catalog request to generate a new catalog for Brand account

POST

/accounts/\{accountId}/catalogs/sellers

Create a catalog request to generate a new catalog for Seller account

POST

/accounts/\{accountId}/brand-catalog-export

Create a request to export existing catalogs from a Brand account

POST

/accounts/\{accountId}/seller-catalog-export

Create a request to export existing catalogs from a Seller account

GET

/catalogs/\{catalogId}/status

Retrieve the status of a specific catalog request.

GET

/catalogs/\{catalogId}/output

Download the output of a specific catalog once it's ready.

*** # Attributes ## Catalog Creation Request Attributes All catalog creation requests must wrap the body parameters in a `data` object with a mandatory `type` field: ```json theme={null} { "data": { "type": "RetailMediaCatalogStatus", "attributes": { ... } } } ``` | Field | Required | Description | | ----------------- | -------- | ------------------------------------------------------ | | `data.type` | Yes | Must be `"RetailMediaCatalogStatus"`. | | `data.attributes` | Yes | Object containing the request parameters listed below. | ### Brand accounts

Attribute

Data Type

Description

format

enum

Format of the catalog data returned.

Accepted values: json-newline

Default: json-newline

Writeable? N / Nullable? Y

brandIdFilter

list \

Brand ID(s) used to filter down catalog results based on specified brands.

Accepted values: list of string or int64

Writeable? N / Nullable? N

retailerIdFilter

list \

Retailer ID(s) used to filter catalog results based on specified retailers. If not specified, all retailers are included.

Accepted values: list of int64

Writeable? N / Nullable? Y

modifiedAfter

timestamp

Includes only SKUs modified after the specified time. Must be within the last 18 hours; otherwise, a full export is required.

Format: yyyy-mm-ddThh:mm:ss±hh:mm (ISO-8601)

Writeable? N / Nullable? Y

includeFields

list \

Optional fields to include in the export. If not provided, those fields will return with null values.

Accepted values:

RetailerName , Description , BrandName , GoogleCategory , Category , ImageUrl

Writeable? N / Nullable? Y

*** #### Seller accounts

Attribute

Data Type

Description

sellers

list \

List of required seller pairs retailerId and sellerId associated with the catalog to be generated

Parameters:

  • retailerId : Retailer ID, generated internally by Criteo
  • sellerId : Seller ID in the respective retailer's catalog, used to filter down catalog products

Writeable? N / Nullable? N

modifiedAfter

timestamp

Includes only SKUs modified after the specified time. Must be within the last 18 hours; otherwise, a full export is required.

Format: yyyy-mm-ddThh:mm:ss±hh:mm (ISO-8601)

Writeable? N / Nullable? Y

includeFields

list \

Optional fields to include in the export. If not provided, those fields will return with null values.

Accepted values:

RetailerName , Description , BrandName , GoogleCategory , Category , ImageUrl

Writeable? N / Nullable? Y

*** ## Catalog Status Response Attributes

Attribute

Data Type

Description

id

string

ID of the catalog creation request, to be used to retrieve its status and output (using other endpoints below - async)

Accepted values: string of int64

Writeable? N / Nullable? N

status

enum

Possible status of respective catalog creation

Accepted values: pending , success , failure , expired , unknown

Default: pending

Writeable? N / Nullable? N

currency

enum

Currency of the products in the catalog

Accepted values: 3-chars currency code (in ISO-4217 ; e.g. USD , EUR )

Writeable? N / Nullable? Y

rowCount

integer

Number of products available in the catalog (available when reach success status)

Accepted values: int32

Writeable? N / Nullable? Y

fileSizeBytes

integer

File size of catalog, in bytes (available when reach success status)

Accepted values: int32

Writeable? N / Nullable? Y

md5Checksum

string

MD5 checksum of catalog's content (available when reach success status)

Accepted values: 32-char alpha-numeric strings

Writeable? N / Nullable? Y

createdAt

timestamp

Timestamp of catalog creation, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601 )

Writeable? N / Nullable? N

message

string

Optional informative message, for developer consumption

Accepted values: string

Writeable? N / Nullable? Y

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Catalog Output Response Attributes

Attribute

Data Type

Description

id

string

Product ID, defined by the retailer.

Accepted values: case-insensitive, up to 50 characters, no quotation marks, ASCII characters

Writeable? N / Nullable? N

name

string

Product name, defined by the retailer.

Accepted values: up to 500 characters

Writeable? N / Nullable? N

description

string

Product description, defined by the retailer.

Accepted values: up to 5000 characters

Writeable? N / Nullable? Y

category

string

Product category, defined by the retailer.

Accepted values: up to 1000 characters

Writeable? N / Nullable? Y

categoryId

string

Category ID associated with the product, derived from the retailer catalog.

Writeable? N / Nullable? Y

googleCategory

string

Category associated with the product, derived from the Google Product Taxonomy .

Writeable? N / Nullable? Y

brandId

string

Brand ID of the product.

For brand accounts, it is derived from the Universal Catalog.

For retailer accounts, it is derived from the Retailer Catalog.

Writeable? N / Nullable? N

brandName

string

Brand name of the product; brands are standardized across retailers.

Accepted values: up to 70 characters

Writeable? N / Nullable? Y

sellerId

string

Seller ID(s) in the respective retailer’s catalog, used to filter down catalog items.

Accepted values: case-insensitive, up to 50 characters, no quotation marks, ASCII characters

Writeable? N / Nullable? Y

sellerName

string

Name of the seller associated with the sellerId .

Accepted values: up to 200 characters

Writeable? N / Nullable? Y

retailerId

string

Retailer ID that contains the product offer.

Accepted values: string of int64

Writeable? N / Nullable? N

retailerName

string

Name of the retailer that contains the product offer.

Accepted values: up to 100 characters

Writeable? N / Nullable? N

price

decimal

Current product price in the respective retailer.

Accepted values: up to 14 characters

Writeable? N / Nullable? Y

isInStock

boolean

Flag indicating if the product is currently in stock.

Accepted values: true , false

Writeable? N / Nullable? N

minBid

decimal

Minimum CPC (Cost-Per-Click) bid required for the product, as set by the retailer.

Any Line Item with this product must have its targetBid meet this value.

Accepted values: > 0.0

Writeable? N / Nullable? Y

gtin

string

Global Trade Item Number (GTIN), if available. Also known as EAN or UPC.

Accepted values: up to 14 digits

Writeable? N / Nullable? Y

mpn

string

Manufacturer Part Number (MPN), if available.

Accepted values: up to 70 characters

Writeable? N / Nullable? Y

imageUrl

string

HTTP URL of the product image, as provided by the retailer.

Accepted values: up to 2000 characters

Writeable? N / Nullable? N

updatedAt

timestamp

Timestamp of the last product update, in UTC.

Format: yyyy-mm-ddThh:mm:ss±hh:mm (ISO-8601)

Writeable? N / Nullable? N

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. **Catalog Asynchronous Workflow: Step 1 of 3** 1. Create a request for the latest catalog of the specified account using the appropriate endpoint. 2. This action generates a `catalogId` that represents the account's catalog. 3. Catalog requests are **cached for 1 hour**, meaning repeated requests within this timeframe will return the same `catalogId` and output. *** # Create a Catalog Request for Brand account This endpoint creates a request for the latest available catalog for a specific account ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/catalogs ``` **Best Practice Tip!** To speed up catalog downloads, you can narrow down the results by using the `brandIdFilter` body parameter. This allows you to filter the catalog by specific brands, helping to return results faster. **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ --data-raw '{ "data": { "type": "RetailMediaCatalogStatus", "attributes": { "format": "json-newline", "brandIdFilter": [ "40115", "9092" ] } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs" payload = json.dumps({ "data": { "type": "RetailMediaCatalogStatus", "attributes": { "format": "json-newline", "brandIdFilter": [ "4768" ] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"data\": {\n \"type\": \"RetailMediaCatalogStatus\",\n \"attributes\": {\n \"format\": \"json-newline\",\n \"brandIdFilter\": [\n \"4768\"\n ]\n }\n }\n}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{\n "data": {\n "type": "RetailMediaCatalogStatus",\n "attributes": {\n "format": "json-newline",\n "brandIdFilter": [\n "4768"\n ]\n }\n }\n}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "id": "1122850670915847014", "type": "RetailMediaCatalogStatus", "attributes": { "status": "pending", "currency": null, "rowCount": null, "fileSizeBytes": null, "md5Checksum": null, "createdAt": "2024-04-06T05:11:41.351+00:00", "message": null } } } ``` **Catalog Asynchronous Workflow: Step 2 of 3** After generating a `catalogId`, use it to poll the catalog status endpoint to check the progress. Continue polling until the catalog is successfully created and ready for download. *** # Create a Catalog Request for Seller account This endpoint creates catalog for a particular Seller account: ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/catalogs/sellers ``` **Sample Request** ```bash cURL theme={null} curl --location 'https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs/sellers' \ --header 'Content-Type: application/json' \ --header 'Accept: text/plain' \ --header 'Authorization: Bearer <TOKEN>' \ --data '{ "data": { "type": "RetailMediaCatalogStatus", "attributes": { "sellers": [ { "retailerId": "123", "sellerId": "60axxxxxxxxxxxxxxxx" } ] } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs/sellers" payload = json.dumps({ "data": { "type": "RetailMediaCatalogStatus", "attributes": { "sellers": [ { "retailerId": "123", "sellerId": "60axxxxxxxxxxxxxxxx" } ] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"data\": {\n \"type\": \"RetailMediaCatalogStatus\",\n \"attributes\": {\n \"sellers\": [\n {\n \"retailerId\": \"123\",\n \"sellerId\": \"60axxxxxxxxxxxxxxxx\"\n }\n ]\n }\n }\n}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs/sellers") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/catalogs/sellers'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{\n "data": {\n "type": "RetailMediaCatalogStatus",\n "attributes": {\n "sellers": [\n {\n "retailerId": "123",\n "sellerId": "60axxxxxxxxxxxxxxxx"\n }\n ]\n }\n }\n}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json JSON theme={null} { "data": { "id": "1122850670915847014", "type": "RetailMediaCatalogStatus", "attributes": { "status": "success", "currency": "USD", "rowCount": 369318, "fileSizeBytes": 216634050, "md5Checksum": "713f2d3c0ed718125a1acdef05224df5", "createdAt": "2025-01-17T22:45:11.44+00:00", "message": null } } } ``` *** ## Get Status of a Specific Catalog This endpoint retrieves the status of a specific catalog. Status can be `pending`, `success`, `failure`, or `expired` ```http theme={null} https://api.criteo.com/{version}/retail-media/catalogs/{catalogId}/status ``` **Sample Request** ```bash cURL theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/catalogs/1122850670915847014/status" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/status" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/status") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/status'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "id": "1122850670915847014", "type": "RetailMediaCatalogStatus", "attributes": { "status": "success", "currency": "USD", "rowCount": 1001, "fileSizeBytes": 353293, "md5Checksum": "2c15b77740028435ca476823df7fb4f8", "createdAt": "2020-04-06T05:11:41.351+00:00", "message": null } } } ``` **Catalog Asynchronous Workflow: Step 3 of 3** Once the catalog is successfully created, use the catalog output endpoint to download the collection of catalog products. Note that catalog outputs are typically available for 72 hours before they expire, so be sure to download them within this time frame. *** ## Download Output of a Specific Catalog This endpoint returns the products in a specific catalog as a [newline-delimited JSON byte stream](https://en.wikipedia.org/wiki/JSON_streaming) ```http theme={null} https://api.criteo.com/{version}/retail-media/catalogs/{catalogId}/output ``` **Sample Request** ```bash cURL theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/catalogs/1122850670915847014/output" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") payload = '' headers = { 'Accept': 'application/x-json-stream', 'Authorization': 'Bearer ' } conn.request("GET", "/{version}/retail-media/catalogs/357957813719011328/output", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/output") .method("GET", body) .addHeader("Accept", "application/x-json-stream") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/output'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/x-json-stream', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response - Brand Catalog** ```json Newline-Delimited JSON expandable theme={null} { \ "id": "sku1", \ "name": "Product One", \ "category": "category1", \ "brandId": "7672171780147256541", \ "brandName": "Brand 123", \ "retailerId": "3239117063738827231", \ "retailerName": "Retailer 123", \ "price": 1.00, \ "isInStock": true, \ "minBid": 0.30, \ "gtin": "abc123", \ "mpn": "789xyz", \ "imageUrl": "/image1.jpg", \ "updatedAt": "2020-04-06T02:23:07Z" \ } // ... newline-delimited, no comma { \ "id": "product-1001", \ "name": "Product One Thousand and One", \ "category": "category2", \ "brandId": "7672171780147256541", \ "brandName": "Brand 123", \ "retailerId": "18159942378514859684", \ "retailerName": "Retailer 789", \ "price": 5.00, \ "isInStock": false, \ "minBid": 0.45, \ "gtin": "none", \ "mpn": "none", \ "imageUrl": "/image1001.jpg", \ "updatedAt": "2020-04-06T01:07:23Z" \ } ``` **Sample Response - Seller Catalog** ```json Newline-Delimited JSON expandable theme={null} { \ "id": "86833674", \ "name": "Flat Front Short 46 x 10.5\" - Black", \ "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \ "categoryId": "3051218", \ "brandId": "40095", \ "brandName": "Test Brand", \ "retailerId": "131", \ "retailerName": "Retailer Name", \ "price": 39.99, \ "isInStock": true, \ "minBid": 0.4000, \ "gtin": "1234567890", \ "mpn": null, \ "imageUrl": "https://example.com/is/image/a610-881aa9a71c93", \ "updatedAt": "2024-07-25T19:52:30Z", \ "sellerId": "60axxxxxxxxxxxxxxxx", \ "sellerName": "Test Seller" \ } // ... newline-delimited, no comma { \ "id": "86833235", \ "name": "Pleated Front Short 52 x 10.5\" - String", \ "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \ "categoryId": "3051218", \ "brandId": "40095", \ "brandName": "Test Brand", \ "retailerId": "131", \ "retailerName": "Retailer Name", \ "price": 39.99, \ "isInStock": true, \ "minBid": 0.4000, \ "gtin": "1234567890", \ "mpn": null, \ "imageUrl": "https://example.com/is/image/a610-881aa9a71c93", \ "updatedAt": "2024-07-25T19:52:30Z", \ "sellerId": "60axxxxxxxxxxxxxxxx", \ "sellerName": "Test Seller" \ } ``` ## Responses

Response

Description

🟢

200

Success

🔴

400

The indicated catalog is not available for retrieval, wait for a success status

🔴

403

API user does not have the authorization to make requests to the account ID. For an authorization request, follow the

authorization request

steps

*** # Export Catalog of a Specific Account ## Brand account This endpoint allows you to generate the most up-to-date catalog for a specific brand account. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/brand-catalog-export ``` **Best Practice Tip!** If you wish to filter SKUs modified within the last 18 hours, you can use `modifiedAfter` field. The request should be formatted according to ISO 8601 standards. Although the example provided uses Eastern Standard Time (EST), you can specify any time zone. Important: If the specified time exceeds the 18-hour limit, the request will return a 400 response, advising you to perform a full catalog export instead. **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/4/brand-catalog-export' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ --data-raw '{ "data": { "type": "RetailMediaCatalogStatus", "attributes": { "brandIdFilter": [ "123" ], "retailerIdFilter": [ "456" ], "modifiedAfter": "2025-03-21T08:00:00-5:00", "includeFields": ["ImageUrl","GoogleCategory", "RetailerName", "Category", "BrandName","Description"] } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/accounts/4/brand-catalog-export" payload = json.dumps({ "data": { "type": "RetailMediaCatalogStatus", "attributes": { "brandIdFilter": [ "123" ], "retailerIdFilter": [ "456" ], "modifiedAfter": "2025-03-21T08:00:00-5:00", "includeFields": ["ImageUrl","GoogleCategory", "RetailerName", "Category", "BrandName","Description"] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"data\": {\n \"type\": \"RetailMediaCatalogStatus\",\n \"attributes\": {\n \"brandIdFilter\": [\n \"123\"\n ],\n \"retailerIdFilter\": [\n \"456\"\n ],\n \"modifiedAfter\": \"2025-03-21T08:00:00-5:00\",\n \"includeFields\": [\"ImageUrl\",\"GoogleCategory\", \"RetailerName\", \"Category\", \"BrandName\",\"Description\"]\n }\n }\n}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/4/brand-catalog-export") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/4/brand-catalog-export'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{\n "data": {\n "type": "RetailMediaCatalogStatus",\n "attributes": {\n "brandIdFilter": [\n "123"\n ],\n "retailerIdFilter": [\n "456"\n ],\n "modifiedAfter": "2025-03-21T08:00:00-5:00",\n "includeFields": ["ImageUrl","GoogleCategory", "RetailerName", "Category", "BrandName","Description"]\n }\n }\n}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "id": "1122850670915847014", "type": "RetailMediaCatalogStatus", "attributes": { "status": "pending", "currency": null, "rowCount": null, "fileSizeBytes": null, "md5Checksum": null, "createdAt": "2025-01-22T23:10:12.21+00:00", "message": null } } } ``` *** ## Seller account This endpoint allows you to generate the most up-to-date catalog for a specific seller account. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/seller-catalog-export ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/4/seller-catalog-export' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ --data-raw '{   "data": {     "type": "RetailMediaCatalogStatus",     "attributes": {       "sellers": [         {           "retailerId": "123",           "sellerId": "5e0axxxxxxxxxx"         }       ],       "modifiedAfter": "",       "includeFields": [         "ImageUrl",         "Description"       ]     }   } }' ``` ```python Python expandable theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/accounts/4/seller-catalog-export" payload = json.dumps({ "data": {     "type": "RetailMediaCatalogStatus",     "attributes": {       "sellers": [         {           "retailerId": "123",           "sellerId": "5e0axxxxxxxxxx"         }       ],       "modifiedAfter": "",       "includeFields": [         "ImageUrl",         "Description"       ]     }   } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"data\": {\n \"type\": \"RetailMediaCatalogStatus\",\n \"attributes\": {\n \"sellers\": [\n {\n \"retailerId\": \"123\",\n \"sellerId\": \"5e0axxxxxxxxxx\"\n }\n ],\n \"modifiedAfter\": \"\",\n \"includeFields\": [\n \"ImageUrl\",\n \"Description\"\n ]\n }\n }}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/4/seller-catalog-export") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/4/seller-catalog-export'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{\n "data": {\n "type": "RetailMediaCatalogStatus",\n "attributes": {\n "sellers": [\n {\n "retailerId": "123",\n "sellerId": "5e0axxxxxxxxxx"\n }\n ],\n "modifiedAfter": "",\n "includeFields": [\n "ImageUrl",\n "Description"\n ]\n }\n }}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "id": "1122850670915847014", "type": "RetailMediaCatalogStatus", "attributes": { "status": "pending", "currency": null, "rowCount": null, "fileSizeBytes": null, "md5Checksum": null, "createdAt": "2025-01-22T23:10:12.21+00:00", "message": null } } } ``` ***
# Catalog Source: https://developers.criteo.com/retail-media/docs/catalogs A catalog is a snapshot of all catalog products from the brands and retailers associated with an account, typically updated once a day. Each account has a single catalog listing all the products that the account is eligible to promote. **Important to Know** * Catalogs are requested and retrieved through asynchronous endpoints. * Product attributes are scoped to the retailer, except for universal identifiers such as GTIN, if available. * Brand attributes are standardized across retailers. * Catalogs are provided in the currency of the retailer. * Catalog outputs are UTF-8 encoded. * Catalogs are returned as a [newline-delimited JSON byte stream](https://en.wikipedia.org/wiki/JSON_streaming) ***
## What's next * [Catalog Endpoints](/retail-media/docs/catalog-endpoints) # Category Search Source: https://developers.criteo.com/retail-media/docs/category-search ## Introduction The `Category Search` endpoint enables you to explore and discover available product categories within a retailer's hierarchical taxonomy structure. Product categories allow retailers to create a hierarchical structure that helps narrow down products into unique groups or subgroups based on shared characteristics. This endpoint provides the ability to see what categories are available to serve against a retailer's inventory, making it an essential tool for understanding targeting options and campaign planning. Unlike recommendation endpoints, `Category Search` allows you to actively explore the retailer's category structure through flexible search parameters. You can search for categories using category IDs to find specific categories and their relationships, or use text substring matching to discover categories by name. The endpoint supports pagination for large result sets, making it easy to browse through extensive category hierarchies efficiently. This functionality is particularly valuable for **campaign setup**, **category discovery**, and **understanding the breadth of targeting options available within a retailer's ecosystem**. *** ## Endpoint

Method

Endpoint

Description

POST

/retailers/\{retailerId}/categories/search

Searches for available categories within a retailer's taxonomy

*** ## Attributes table

Attribute

Data Type

Description

retailerId \*

string

Unique identifier for the retailer.

Found using the GET retailer's endpoint.

Required in URL path.

Writable? N / Nullable? N

categoryIds

array

Array of category ID strings for search filtering.

Must be positive integer strings.

Writable? Y / Nullable? Y

textSubstring

string

Text string to search for in category names.

Used for category name filtering.

Writable? Y / Nullable? Y

offset

integer

Pagination offset for search results.

Default: 0 .

Query parameter.

Writable? Y / Nullable? Y

limit

integer

Maximum number of results to return.

Default: 500 .

Query parameter.

Writable? Y / Nullable? Y

\**Required* *** ## Search Categories This endpoint enables searching for available categories within a retailer's hierarchical taxonomy structure. You can search by category IDs or text substring, with pagination support for large result sets. Results are paginated using offset and limit query parameters; if omitted, defaults to 0 and 500, respectively. **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/retailers/12345/categories/search?offset=0&limit=50' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "categoryIds": [ "520020" ], "textSubstring": "headphones" }, "type": "CategoriesSearchRequestV1" } }' ``` **Sample Response** ```json theme={null} { "metadata": { "count": 2, "offset": 0, "limit": 50 }, "data": [ { "id": "673311", "type": "CategoryV1", "attributes": { "text": "Electronics|Audio|Headphones|Wireless", "name": "Wireless Headphones", "parentId": "683708" } }, { "id": "4830673", "type": "CategoryV1", "attributes": { "text": "Electronics|Audio|Headphones", "name": "Headphones", "parentId": "683706" } } ], "warnings": [], "errors": [] } ``` *** ## Responses

Code

Meaning

Troubleshooting Hint

🟢 200

Success

Request processed successfully with pagination metadata

🔴 400

Bad Request

Check that categoryIds are positive integer strings and retailerId is valid in URL path

🔴 403

Forbidden

Verify authorization and retailer access permissions

*** ### Common Error Scenarios **Invalid Category ID Format** ```json theme={null} { "metadata": null, "data": null, "warnings": [], "errors": [ { "type": "validation", "code": "InvalidCategoryId", "title": "Validation error", "detail": "Category ids can only be positive integer strings." } ] } ``` **Invalid Retailer ID** ```json theme={null} { "warnings": [], "errors": [ { "traceId": "954eab48899860c9b18880eb0018fd3f", "type": "validation", "code": "model-validation-error", "title": "Model validation error", "detail": "The value ':retailerId' is not valid." } ] } ``` ***
# Overview Source: https://developers.criteo.com/retail-media/docs/demand-side-analytics-overview ## Before Starting The following information is important to know regarding Demand Side Analytics. ### Asynchronous Workflow `POST /reports/performance`, `POST /reports/missed-opportunities`, and `POST /reports/attributed-transactions` are all **asynchronous**: you submit a request, poll the returned `reportId` for status, and download the output once processing succeeds. 1. **Submit** the report request — a successful call returns `200 OK` with a `reportId` and a `status` of `pending`. 2. **Poll for status** at `GET /reports/{reportId}/status` until `status` is `success` or `failure`. 3. **Download the output** at `GET /reports/{reportId}/output` once `status` is `success`. The [Real-Time Performance API](/retail-media/docs/real-time-performance-api) is the exception: it is a **synchronous** endpoint (`POST /retail-media/reports/sync/real-time-performance`) that returns data directly in the response, with no `reportId`, polling, or output step. ### Granularity Most reports are generated at a **daily granularity**, except for the Attributed Transactions report, which is provided at an **hourly granularity**. ### Report Date Range The report date range supports a maximum window of **100 days** per report, regardless of whether you scope by account, campaign, or line item, with data retained for up to **3 years**. ### Report Row Limits Reports are limited to **10MM rows**. If a report reaches this limit, the data may be incomplete due to truncation. To avoid this, consider reviewing the following parameters for bulk requests: * Number of campaign or line item IDs * Start and end date range * Report type ### Report Attribution * Report attribution windows and time-zones are fully configurable. * Data is processed and batched **hourly**. Same-day data may be partially available. * While reports with an end date of today or yesterday are cached for 1 hour, reports with an end date older than yesterday are cached for **24 hours.** * The exact expiration time is provided in the `expiresAt` field of the /status response. ### Rate Limits You can find more details about rate limits on [this page](/criteo-apis/docs/rate-limits).

OAuth Method

Rate limit

Rate limit applies at level

Client Credentials

250 calls per minute for default endpoints

40 calls per minute for reporting endpoints

Application level

Authorization Code

10 calls per minute

Account

### Data Latency Please refer to [our troubleshooting guide](/criteo-apis/docs/api-troubleshooting-guide#/is-the-issue-that-my-data-is-late) for more data latency details. Different types of activity and attribution data become available at different times after the event or sale: * **Onsite activity data** is typically available within **6–8 hours** of the event. * **Offsite activity data** is typically available within **24 hours** of the event. * **Initial attribution data** is available within **7–9 hours** of the sale. * **Final attribution data** is processed and posted within **74 hours** after the sale. * Please note that potential minor updates can occur up to **120 hours** before finalization Learn more about our Attribution Rules in the [Commerce Max Help Center](https://help.retailmedia.criteo.com/kb/guide/en/about-attribution-sZH1iCyq5L/Steps/1034909). *** ## Response Codes All Demand Side Analytics reporting endpoints — `POST /reports/performance`, `POST /reports/missed-opportunities`, `POST /reports/attributed-transactions`, and the shared `GET /reports/{reportId}/status` / `GET /reports/{reportId}/output` — share the same set of response and status codes. | Code | Meaning | | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `200` | Request succeeded — report submitted, status retrieved, or output returned. | | `400` | Validation error. Common causes: missing, or more than one, scope filter under `filters` (`accountIds[]` / `campaignIds[]` / `lineItemIds[]`); missing `metrics[]` or `dimensions[]`; a date range exceeding 100 days; or a `startDate` older than 3 years. | | `404` | The `reportId` used in `GET /reports/{reportId}/status` or `GET /reports/{reportId}/output` doesn't exist, or doesn't belong to the caller's account. | | `410` | The report is expired (past its `expiresAt`) or failed to generate and is no longer retrievable. Submit a new report request — report output isn't retained indefinitely. | For authentication, permission, and rate-limit errors (`401`, `403`, `429`, `500`) common to all Retail Media API endpoints, see [API Error Codes](/retail-media/docs/api-error-codes). *** ## What changed in this version **This version introduces a major redesign of the Demand Side Analytics reporting API.** If you have an integration built against a previous version, it will **not** work unchanged: the endpoints, the request shape, and the `reportType` field have all changed. See the [migration guide](/retail-media/docs/dsp-analytics-migration-guide) before upgrading. Previous versions exposed three aggregation-level endpoints — `POST /reports/campaigns`, `POST /reports/line-items`, and `POST /reports/accounts` — together with a `reportType` field that selected a preset report shape (`summary`, `keyword`, `pageType`, `capout`, `attributedTransactions`, and so on). That model has been replaced by a smaller, explicit, and more predictable set of endpoints. | Purpose | New endpoint | | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | | Flexible performance reporting, at any account / campaign / line-item granularity | [`POST /reports/performance`](/retail-media/docs/performance-report) | | Budget cap-out and missed-delivery diagnostics (formerly `reportType: capout`) | [`POST /reports/missed-opportunities`](/retail-media/docs/missed-opportunities-report) | | Transaction-level attribution log (formerly `reportType: attributedTransactions`) | [`POST /reports/attributed-transactions`](/retail-media/docs/attributed-transactions-report) | **What is different from the previous model:** * **One performance endpoint instead of three.** `/reports/campaigns`, `/reports/line-items`, and `/reports/accounts` are all replaced by `POST /reports/performance`. You choose the scope by which ID array you pass under `filters`, and the output granularity by the dimensions you select. * **`reportType` is gone.** You now always specify `metrics` and `dimensions` explicitly. The preset report types (`keyword`, `pageType`, `productCategory`, `product`, `servedCategory`, `environment`, …) are reproduced simply by adding the corresponding dimension to your request. * **Scope moved into a `filters` object.** Instead of top-level `accountId` / `campaignId` / `lineItemId`, provide exactly one of `filters.accountIds[]`, `filters.campaignIds[]`, or `filters.lineItemIds[]`. * **`startDate`, `endDate`, `filters`, `metrics`, and `dimensions` are all required** on the new endpoints. * **Two purpose-built use cases are split into their own endpoints.** `capout` and `attributedTransactions` are no longer `reportType` values — they are dedicated endpoints, each with a few field/metric renames documented on its own page. For the full old → new endpoint mapping, every `reportType` value, before/after request examples, and the legacy support timeline, see [Migrating from the Legacy Reporting API](/retail-media/docs/dsp-analytics-migration-guide). # Migrating from the Legacy Reporting API Source: https://developers.criteo.com/retail-media/docs/dsp-analytics-migration-guide How to move from the legacy /reports/campaigns, /reports/line-items, and /reports/accounts endpoints (with reportType) to the unified 2026.07 DSP Analytics endpoints. ## Who should read this Your integration calls `POST /reports/campaigns`, `POST /reports/line-items`, or `POST /reports/accounts` — with or without a `reportType` — on a pre-2026.07 version of the Retail Media API. This guide maps every legacy call to its 2026.07 equivalent, with before/after request examples. If you're integrating against DSP Analytics for the first time, skip this page and start with the [Overview](/retail-media/docs/demand-side-analytics-overview). ## Is this urgent? Legacy endpoints keep working unchanged on **v2026.01 and earlier**. Per the [versioning policy](/retail-media/docs/versioning-policy), each stable version is supported for 12 months after release, after which it's deprecated and later sunset (the API signals this with `Deprecation` and `Sunset` response headers before the endpoint starts returning `410 Gone`). You don't need to migrate the moment you read this — but any new build, or any plan to move onto 2026.07, should target the endpoints below. *** ## Endpoint mapping | Legacy call | 2026.07 endpoint | | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | `POST /reports/campaigns` (any `reportType`, or flexible with `metrics`/`dimensions`) | [`POST /reports/performance`](/retail-media/docs/performance-report), scoped by `filters.campaignIds[]` | | `POST /reports/line-items` (any `reportType`, or flexible) | [`POST /reports/performance`](/retail-media/docs/performance-report), scoped by `filters.lineItemIds[]` | | `POST /reports/accounts` (any `reportType`, or flexible) | [`POST /reports/performance`](/retail-media/docs/performance-report), scoped by `filters.accountIds[]` | | `reportType: capout` on any of the above | [`POST /reports/missed-opportunities`](/retail-media/docs/missed-opportunities-report) | | `reportType: attributedTransactions` on any of the above | [`POST /reports/attributed-transactions`](/retail-media/docs/attributed-transactions-report) | Three separate endpoints, each with its own field quirks and a `reportType` enum, become three purpose-built endpoints with one consistent request shape. *** ## What's different in every request Regardless of which legacy endpoint or `reportType` you're moving from, the same four changes apply: 1. **Scope moves into a `filters` object.** The legacy endpoints took a top-level `id` / `ids` (or `accountIds` on the accounts endpoint). The new endpoints take exactly one of `filters.accountIds[]`, `filters.campaignIds[]`, or `filters.lineItemIds[]` — never a bare top-level ID field, and never more than one array. 2. **`reportType` is gone.** There's no preset-shape enum anymore. You always specify `metrics[]` and `dimensions[]` explicitly — including for what used to be the `summary` / default shape. 3. **`startDate`, `endDate`, `filters`, `metrics`, and `dimensions` are all required.** The legacy endpoints allowed some of these to be inferred from `reportType`; the new endpoints don't infer anything. 4. **`timezone` is lowercase.** The legacy campaign and line-item endpoints used `timeZone` (capital Z); the account endpoint already used lowercase `timezone`. All 2026.07 endpoints use lowercase `timezone` consistently — if you're coming from `/reports/campaigns` or `/reports/line-items`, this field name changes even though the value format doesn't. There's no longer an account-specific date-range restriction either: every 2026.07 DSP endpoint allows a **100-day** span between `startDate` and `endDate`, whether you scope by account, campaign, or line item. (The legacy `/reports/accounts` endpoint capped account-level requests at 31 days — that cap doesn't carry over.) *** ## Before / after ### Campaign or line-item flexible report ```json Before — POST /reports/campaigns theme={null} { "data": { "type": "RetailMediaReportRequest", "attributes": { "id": "8343086999167541140", "metrics": ["impressions", "clicks", "spend"], "dimensions": ["date"], "startDate": "2026-05-01", "endDate": "2026-05-07", "timeZone": "America/New_York" } } } ``` ```json After — POST /reports/performance theme={null} { "data": { "type": "AsyncPerformanceReport", "attributes": { "filters": { "campaignIds": ["8343086999167541140"] }, "metrics": ["impressions", "clicks", "spend"], "dimensions": ["date"], "startDate": "2026-05-01", "endDate": "2026-05-07", "timezone": "America/New_York" } } } ``` Swap `filters.lineItemIds[]` for `filters.campaignIds[]` if you were calling `/reports/line-items`. ### Account-level report ```json Before — POST /reports/accounts theme={null} { "data": { "attributes": { "accountIds": ["505471171905413120"], "startDate": "2026-05-01", "endDate": "2026-05-28", "dimensions": ["date", "accountId"], "metrics": ["impressions"], "timezone": "UTC" } } } ``` ```json After — POST /reports/performance theme={null} { "data": { "type": "AsyncPerformanceReport", "attributes": { "filters": { "accountIds": ["505471171905413120"] }, "startDate": "2026-05-01", "endDate": "2026-05-28", "dimensions": ["date", "accountId"], "metrics": ["impressions"], "timezone": "UTC" } } } ``` ### `reportType: capout` ```json Before — POST /reports/line-items theme={null} { "data": { "attributes": { "id": "987654", "reportType": "capout", "startDate": "2026-05-01", "endDate": "2026-05-07" } } } ``` ```json After — POST /reports/missed-opportunities theme={null} { "data": { "type": "AsyncMissedOpportunitiesReport", "attributes": { "filters": { "lineItemIds": ["987654"] }, "startDate": "2026-05-01", "endDate": "2026-05-07", "dimensions": ["date", "lineItemId", "lineItemName"], "metrics": ["missedTraffic", "missedSpend", "capoutHour"] } } } ``` Metric names change too — see [Missed Opportunities Report: migrating from `reportType: capout`](/retail-media/docs/missed-opportunities-report#migrating-from-reporttype-capout) for the full `capoutMissed*` → `missed*` rename table. ### `reportType: attributedTransactions` ```json Before — POST /reports/campaigns theme={null} { "data": { "attributes": { "id": "123456", "reportType": "attributedTransactions", "startDate": "2026-05-01", "endDate": "2026-05-07" } } } ``` ```json After — POST /reports/attributed-transactions theme={null} { "data": { "type": "AsyncAttributedTransactionsReport", "attributes": { "filters": { "campaignIds": ["123456"] }, "startDate": "2026-05-01", "endDate": "2026-05-07", "dimensions": ["advertisedDate", "advertisedProductName", "purchasedProductName", "advertisedToPurchasedProductRelationship"], "metrics": ["attributedSales", "attributedUnits"] } } } ``` Field names change too — see [Attributed Transactions Report: migrating from `reportType: attributedTransactions`](/retail-media/docs/attributed-transactions-report#migrating-from-reporttype-attributedtransactions) for the full `adv*` → `advertised*` rename table. *** ## Mapping every `reportType` value | Old `reportType` (or legacy dimension) | New equivalent | | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | `summary` | `POST /reports/performance` with `metrics`: `impressions`, `clicks`, `spend`, `roas`, `ctr`, `attributedSales`, `attributedUnits` | | `flexible` (no `reportType`, explicit `metrics`/`dimensions`) | `POST /reports/performance` — same behavior, only the endpoint path and request shape change | | `keyword` | Add `keyword` to `dimensions` on `/reports/performance` | | `pageType` | Add `pageType` to `dimensions` | | `productCategory` | Add `productCategory` to `dimensions` | | `product` | Add `productId` and `productName` to `dimensions` | | `servedCategory` | Add `servedCategory` to `dimensions` | | `environment` | Add `environment` to `dimensions` | | `capout` | [`POST /reports/missed-opportunities`](/retail-media/docs/missed-opportunities-report) | | `attributedTransactions` | [`POST /reports/attributed-transactions`](/retail-media/docs/attributed-transactions-report) | *** ## Common migration errors | Symptom | Cause | | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `400 Bad Request` on a request that used to work | Almost always a missing or extra scope filter — `filters` must contain **exactly one** of `accountIds[]` / `campaignIds[]` / `lineItemIds[]`. Passing a bare top-level `id` (the old shape) is silently invalid, not ignored. | | `400 Bad Request` mentioning `metrics` or `dimensions` | These are now required on every request. A call that relied on `reportType` to imply the output columns needs explicit `metrics[]` / `dimensions[]`. | | Data looks right but `timezone` seems ignored | Check the field name — `timeZone` (capital Z) is not recognized on the new endpoints; use `timezone`. | | Row-level fields renamed or missing on an attributed-transactions or capout migration | See the endpoint-specific rename tables linked above — several fields were renamed (`adv*` → `advertised*`) or moved between `metrics` and `dimensions` (`daypartingScheduled`). | *** ## What's next * [Overview](/retail-media/docs/demand-side-analytics-overview) * [Performance Report](/retail-media/docs/performance-report) * [Missed Opportunities Report](/retail-media/docs/missed-opportunities-report) * [Attributed Transactions Report](/retail-media/docs/attributed-transactions-report) * [Versioning Policy](/retail-media/docs/versioning-policy) # Fill Rate Report Source: https://developers.criteo.com/retail-media/docs/fill-rate-report ## Introduction The fill rate report measures the placement impressions that were successfully filled in comparison to the total number of delivered placements. Retailers can leverage this data to analyze areas in demand and their supply that are impacting the ability to maximize yield. *** ## Endpoints The report generation uses an asynchronous endpoint that is used to receive the report creation request (using a POST request); then, using the report `id` generated, it's possible to check the report status and download the output results using the following GET endpoint requests.

Verb

Endpoint

Description

POST

/reports/fillrate

Request a fill rate report creation

POST

/reports/unfilled-placements

Request an unfilled reasons report

GET

/reports/\{reportId}/status

Get status of a specific report

GET

/reports/\{reportId}/output

Download output of a specific report

*** ## Report Request Attributes

Attribute

Data Type

Description

supplyAccountIds \*

list\\

Supply Account IDs to pull results for

Accepted values: array of strings/int64

Writable? N / Nullable? N

dimensions \*

list\\

An array of strings used to define which dimensions to see in the report

Accepted values: refer to Metrics and Dimensions for the complete list of supported dimensions

Writable? N / Nullable? N

metrics \*

list\\

An array of strings used to define which metrics to see in the report

Accepted values: refer to Metrics and Dimensions for the complete list of supported metrics

Writable? N / Nullable? N

startDate \*

date

Start date of the report (inclusive)

Accepted values: yyyy-mm-dd with max interval of 100 days with endDate

Writable? N / Nullable? N

endDate \*

date

End date of the report (inclusive)

Accepted values: yyyy-mm-dd with max interval of 100 days with startDate

Writable? N / Nullable? N

timezone

string

Time zone to consider in the metrics calculation, startDate and endDate

Accepted values: IANA (TZ database) time zones (example: America/New\_York , Europe/Paris , Asia/Tokyo , UTC )

Default: UTC

Writable? N / Nullable? Y

format

enum

The format type the report should return results

Accepted values: json , json-compact , json-newline , csv

Default: json

Writable? N / Nullable? N

adServerType

enum

The ad server responsible for rending the ad on the retailer site.

Accepted values: all , gam , criteo

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Create a Fill Rate Report request This endpoint receives requests to create Fill Rate Reports and returns a report `id` (to be used in the next steps) in case the request was successfully created ; otherwise, will expose errors details about the request issues ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/fillrate ``` **Sample Request** ```bash expandable theme={null} curl -X 'POST' \ 'https://api.criteo.com/{version}/retail-media/reports/fillrate' \ -H 'accept: text/plain' \ -H 'Content-Type: application/json-patch+json' \ -H 'Authorization: Bearer Add_token' \ -d '{ "data": { "type": "string", "attributes": { "supplyAccountIds": [ "8639134211138xxxx" ], "dimensions": [ "date", "retailerId", "retailerName", "placementId", "placementName", "pageTypeName", "environment", "servedCategory", "retailerCategoryId", "retailerCategoryName", "adServerType" ], "metrics": [ "pageViews", "availablePlacements", "unfilledPlacements", "fillRate", "placementImpressions", "productImpressions", "impressions", "placementClicks", "productClicks", "clicks", "placementImpressionsCTR", "productImpressionsCTR", "cpm", "cpc", "placementImpressionsRevenue", "productClicksRevenue", "revenue", "workingMedia", "netRevenue", "nonDeliverablePlacements", "deliverablePlacements", "placementsWithCandidates", "coveredPlacements", "coverageRate" ], "adServerType": "all", "format": "csv", "startDate": "2025-09-08", "endDate": "2025-09-09", "timezone": "America/New_York" } } }' ``` **Sample Response**: Report request successfully created (response status 🟢 `200`) ```json theme={null} { "data": { "attributes": { "status": "pending", "rowCount": 0, "fileSizeBytes": 0, "md5CheckSum": null, "createdAt": "2025-09-15T19:00:29.056Z", "expiresAt": null, "message": null, "id": "48dec08e-5f65-41cd-9d77-85f87cxxxxx" }, "id": "48dec08e-5f65-41cd-9d77-85f87xxxxxxx", "type": "StatusResponse" }, "warnings": [], "errors": [] } ``` *** ## Retrieve Unfilled Reasons ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/unfilled-placements ``` **Sample Request** **List of Unfilled Reasons** Check the full list of supported unfilled reasons [here](/retail-media/docs/metrics-and-dimensions-ssp#fill-rate-unfilled-reasons) ```bash expandable theme={null} curl -X 'POST' \ 'https://api.criteo.com/{version}/retail-media/reports/unfilled-placements' \ -H 'accept: text/plain' \ -H 'Content-Type: application/json-patch+json' \ -H 'Authorization: Bearer Add Token' \ -d '{ "data": { "type": "string", "attributes": { "supplyAccountIds": [ "8639134211138xxxx" ], "dimensions": [ "adServerType", "date" ], "metrics": [ "totalUnfilledPlacements", "unfilledNotEnoughDemand", "nonDeliverableUnmappedCategories", "nonDeliverablePagesWithUnknownProducts", "nonDeliverableBlockedOptOut", "nonDeliverableBlockedPageCategory", "nonDeliverableInsufficientOrganicResults", "nonDeliverableTestPlacement", "uncoveredSearchTermWithoutCategory", "uncoveredNoDemandBrandedKeywordConquestingEnabled", "uncoveredNoDemandBrandedKeywordConquestingDisabled", "uncoveredNoDemandUnbrandedInventory", "uncoveredFilteredOutDemand", "uncoveredBrokenPlacement", "uncoveredNotPainted", "availablePlacements", "fillRate", "placementImpressions", "productImpressions", "placementClicks", "productClicks", "clicks", "placementImpressionsCTR", "productImpressionsCTR", "cpm", "cpc", "placementImpressionsRevenue", "productClicksRevenue", "revenue", "nonDeliverablePlacements", "placementsWithCandidates", "coveredPlacements", "coverageRate" ], "format": "csv", "startDate": "2025-09-08", "endDate": "2025-09-09", "timezone": "America/New_York" } } }' ``` **Sample Response** ```json theme={null} { "data": { "attributes": { "status": "pending", "rowCount": 0, "fileSizeBytes": 0, "md5CheckSum": null, "createdAt": "2025-09-15T19:45:55.758Z", "expiresAt": null, "message": null, "id": "4dcd1f71-77f0-4bf2-b225-3e7a0dxxxxx" }, "id": "4dcd1f71-77f0-4bf2-b225-3e7a0ddxxxxxx", "type": "StatusResponse" }, "warnings": [], "errors": [] } ``` *** ## Get status of specific report This endpoint retrieves the status of a specific report creation.\ Status can be `pending`, `success`, `failure`, or `expired`. ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/{reportId}/status ``` **Sample Request** ```bash theme={null} curl -L 'https://api.criteo.com/{version}/retail-media/reports/5f148e12-fba3-432e-b0d5-fe316xxxxx/status' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json theme={null} { "data": { "id": "5f148e12-fba3-432e-b0d5-fe316xxxxxx", "type": "StatusResponse", "attributes": { "id": "5f148e12-fba3-432e-b0d5-fe3164axxxxx", "status": "success", "message": "rows_count=33490", "rowCount": 33490, "fileSizeBytes": 6669897, "createdAt": "2025-02-14T14:59:20.000Z", "expiresAt": "2025-02-21T15:00:00.000Z", "md5CheckSum": "801993bc0fe04e2b3fcf767a1c867a04" } }, "warnings": [], "errors": [] } ``` *** ## Download output of specific report Once the report creation is completed (`"status": "success"` in response above), the report output will be available to download in this endpoint. ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/{reportId}/output ``` **Sample Request** ```bash theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/reports/2e733b8c-9983-4237-aab9-17a4xxxxxx/output" \ -H "Authorization: Bearer " ``` **Sample Responses** Fill Rate and Coverage Rate ```json expandable theme={null} [ { "date": "2025-09-08", "retailerId": 180, "retailerName": "RetailerExample", "placementId": 21930, "placementName": "viewCategory_M-Butterfly2", "pageTypeName": "category", "environment": "mobile", "servedCategory": "tires & auto > auto & truck accessories > solar power systems", "retailerCategoryId": 695922, "retailerCategoryName": "solar power systems", "adServerType": "Criteo", "pageViews": null, "availablePlacements": 6, "unfilledPlacements": 6, "fillRate": null, "placementImpressions": null, "productImpressions": null, "impressions": null, "placementClicks": null, "productClicks": null, "clicks": null, "placementImpressionsCTR": null, "productImpressionsCTR": null, "cpm": null, "cpc": null, "placementImpressionsRevenue": 0, "productClicksRevenue": 0, "revenue": null, "workingMedia": null, "netRevenue": null, "nonDeliverablePlacements": 6, "deliverablePlacements": 0, "placementsWithCandidates": 0, "coveredPlacements": 0, "coverageRate": null }, { "date": "2025-09-08", "retailerId": 180, "retailerName": "RetailerExample", "placementId": 21930, "placementName": "viewCategory_M-Butterfly2", "pageTypeName": "category", "environment": "mobile", "servedCategory": "toys > electronics for kids", "retailerCategoryId": 673065, "retailerCategoryName": "electronics for kids", "adServerType": "Criteo", "pageViews": null, "availablePlacements": 179, "unfilledPlacements": 179, "fillRate": null, "placementImpressions": null, "productImpressions": null, "impressions": null, "placementClicks": null, "productClicks": null, "clicks": null, "placementImpressionsCTR": null, "productImpressionsCTR": null, "cpm": null, "cpc": null, "placementImpressionsRevenue": 0, "productClicksRevenue": 0, "revenue": null, "workingMedia": null, "netRevenue": null, "nonDeliverablePlacements": 136, "deliverablePlacements": 43, "placementsWithCandidates": 179, "coveredPlacements": 0, "coverageRate": 0 } ] ``` **Unfilled Placements** ```json expandable theme={null} [ { "adServerType": "Criteo", "date": "2025-09-30", "totalUnfilledPlacements": 55388, "unfilledUserOptOut": 0, "unfilledNotEnoughDemand": 0, "unfilledTotalAuctionSettings": 0, "unfilledTotalAuctionConsiderations": 0, "unfilledAdvertiserAuctionSettings": 0, "unfilledRetailerAuctionSettings": 0, "unfilledCriteoAuctionSettings": 0, "unfilledReturnedButNotPainted": 0, "nonDeliverableUnmappedCategories": 0, "nonDeliverablePagesWithUnknownProducts": 8, "nonDeliverableBlockedOptOut": 0, "nonDeliverableBlockedPageCategory": 0, "nonDeliverableInactivePlacement": null, "nonDeliverableInsufficientOrganicResults": 0, "nonDeliverableInvalidTraffic": null, "nonDeliverableTestPlacement": 0, "uncoveredUnusedFormats": null, "uncoveredSearchTermWithoutCategory": 5954, "uncoveredNoDemandBrandedKeywordConquestingEnabled": 0, "uncoveredNoDemandBrandedKeywordConquestingDisabled": 760, "uncoveredNoDemandUnbrandedInventory": 48666, "uncoveredNoDemandOptOut": 0, "uncoveredFilteredOutDemand": 0, "uncoveredBrokenPlacement": 0, "uncoveredNotPainted": null, "availablePlacements": 55388, "fillRate": null, "placementImpressions": null, "productImpressions": null, "placementClicks": null, "productClicks": null, "clicks": null, "placementImpressionsCTR": null, "productImpressionsCTR": null, "cpm": null, "cpc": null, "placementImpressionsRevenue": 0, "productClicksRevenue": 0, "revenue": null, "nonDeliverablePlacements": 8, "deliverablePlacements": 55380, "placementsWithCandidates": 0, "coveredPlacements": 0, "coverageRate": 0 } ] ``` *** ## Responses

Response

Description

🟢 200

Call executed with success

🔴 400

Common Validation Errors:

  • Deserialization error : one or more input parameters is not supported; see details for more info.
  • Please select an interval under 100 days : using a date range with more than 100 days apart between startDate and endDate .
  • Time zone xyz is not valid : using a time zone value that is not listed in the list TZ database time zones.

🔴 403

  • You are not authorized to access some of the requested resources. : API user does not have the authorization to access some of the requested resources. Review the supply account IDs used in the request and, for an authorization request, follow the authorization request steps.
***
## What's next * [Metrics & Dimensions (Fill Rate Report)](/retail-media/docs/metrics-dimensions-fill-rate-report) # Is Criteo Retail Media API for you? Source: https://developers.criteo.com/retail-media/docs/is-criteo-api-for-you **Brand** | You have preferred tools and the development resources to build with our APIs **Agencies** | You offer complementary tools to brands who prefer your managed services **Partner** | You offer complementary tools to brands or agencies to enrich their retail media campaigns **Retailers** | Reach out to your Criteo representative to discuss your needs **Marketplaces** | You operate a platform with users who are sellers # Keyword Review Source: https://developers.criteo.com/retail-media/docs/keyword-review ## Introduction The keyword approval process is designed for advertisers and retailers to determine what keywords are prospects to be used for targeting on retailer inventory. When an advertiser proposes a set of keywords for review, these keywords are then forwarded to the retailer reviewer, who evaluates them based on predefined criteria such as relevance, accuracy, and compliance with guidelines. The reviewer may use tools and resources to verify the appropriateness of each keyword. If the keywords meet the standards, they are approved and added to the database. This iterative process ensures that only high-quality, relevant keywords are approved and utilized. *** ## Endpoints

Verb

Endpoint

Description

GET

/accounts/\{accountId}/keywords/in-review-report

Retrieve a Keywords Approval report to the specific supply account, with a count of keywords in review state at line-item

GET

/line-items/\{lineItemId}/keywords

Retrieve a set of all keywords in review state for the specific line-item

POST

/line-items/\{lineItemId}/keywords/review

Review keyword(s) for the specific line-item

*** ## Keywords Approval Report Attributes

Attribute

Data Type

Description

id / lineItemId

string

Line Item ID, respective to the amount of keywords in review

Accepted values: string of int64

Writeable? N / Nullable? N

lineItemName

string

Line Item name, respective to the amount of keywords in review

Accepted values: up to 255-chars string

Writeable? Y / Nullable? N

campaignId

string

Campaign ID, respective to the amount of keywords in review

Accepted values: string of int64

Writeable? N / Nullable? N

campaignName

string

Campaign name, respective to the amount of keywords in review

Accepted values: up to 255-chars string

Writeable? Y / Nullable? N

accountId

string

Account ID, respective to the amount of keywords in review

Accepted values: string of int64

Writeable? N / Nullable? N

accountName

string

Account name, respective to the amount of keywords in review

Accepted values: up to 255-chars string

Writeable? Y / Nullable? N

retailerId

string

Retailer ID, respective to the amount of keywords in review

Accepted values: string of int64

Writeable? N / Nullable? N

retailerName

string

Retailer name, respective to the amount of keywords in review

Accepted values: up to 255-chars string

Writeable? Y / Nullable? N

countKeywords

integer

Amount of keywords in review for the respective line-item

Accepted values: countKeywords ≥ 1

Writeable? N / Nullable? N

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Keywords Review Attributes

Attribute

Data Type

Description

id

string

Line Item ID, respective to the amount of keywords in review

Accepted values: string of int64

Writeable? N / Nullable? N

reviewState

enum

Status of the Keyword Review (only applicable for PositiveExactMatch keywords)

Accepted values:

  • InReview \- keyword has been submitted manually, and the review is still pending
  • Approved \- keyword was approved manually
  • Rejected \- keyword was rejected manually
  • AutoApproved \- keyword was approved automatically
  • AutoRejected \- keyword was rejected automatically
  • Recommended \- keyword was recommended by our keyword model

Default: InReview

Writeable? N / Nullable? N

matchType

enum

The matching algorithm to be used when comparing this keyword with shopper search phrases

Accepted values:

  • PositiveExactMatch \- normalized keyword is an exact match for the normalized search phrase bid
  • NegativeExactMatch \- normalized keyword is an exact match for the normalized search phrase to not bid
  • NegativeBroadMatch \- normalized keyword is a substring of the normalized search phrase to not bid

Writeable? N / Nullable? N

bid

decimal

The bid override for the positive keyword. The keyword will use the default line item bid if the value is null . The currency of the bid is the default currency for the retailer.

Accepted values: retailer's minBid bid ≤ retailer's maxBid

Default: null

Writeable? Y / Nullable? Y

inputKeywords

object

Keywords supplied by the user matching this normalized keyword phrase binned by match type (see examples below)

Parameters:

  • positiveExact \- collection of supplied positive exact phrases
  • negativeExact \- collection of supplied negative exact phrases
  • negativeBroad \- collection of supplied negative broad phrases

Writeable? Y / Nullable? Y

createdAt

timestamp

Timestamp the keyword was created in the line-item (or recommended to line-item)

Accepted values: yyyy-mm-ddThh:mm:ss (in ISO-8601 )

Writeable? N / Nullable? N

updatedAt

timestamp

Last timestamp the keyword was updated in the line-item (or recommended to line-item)

Accepted values: yyyy-mm-ddThh:mm:ss (in ISO-8601 )

Writeable? N / Nullable? N

*** ## Keywords Review Body Request

Attribute

Data Type

Description

keywords \*

list \

List of object pairs made of phrase and reviewState to approve/reject keywords

Parameters:

  • phrase \- keyword to review
  • reviewState \- approval result

Writeable? N / Nullable? N

phrase \*

enum

Normalized keyword for approval review

Accepted values: string keywords returned from previous endpoint (in "reviewState": "InReview"

Writeable? N / Nullable? N

reviewState \*

enum

Approval result of the Keyword Review

Accepted values:

  • Approved \- keyword was approved manually
  • Rejected \- keyword was rejected manually

Writeable? N / Nullable? N

*** ## Get Keywords Approval report This endpoint retrieves a Keywords Approval report for the provided supply account ID (not applicable for demand accounts). Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `500`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/keywords/in-review-report ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/accounts/368471940340928512/keywords/in-review-report?offset=0&limit=25" \ -H "Accept: application/json" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/accounts/368471940340928512/keywords/in-review-report?offset=0&limit=25" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/368471940340928512/keywords/in-review-report?offset=0&limit=25'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/368471940340928512/keywords/in-review-report?offset=0&limit=25") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` **Sample Response** ```json expandable theme={null} { "meta": { "count": 71, "offset": 0, "limit": 25 }, "data": [ { "id": "4840685188706902009", "type": "LineItemKeywordReviewReport", "attributes": { "lineItemId": "4840685188706902009", "lineItemName": "LI Retailer ABC Category A", "retailerId": "401887", "retailerName": "Retailer ABC", "campaignId": "124755545923269376", "campaignName": "Campaign AAA", "accountId": "97393138059194368", "accountName": "Test Account", "countKeywords": 2 } }, { "id": "6854840188706902009", "type": "LineItemKeywordReviewReport", "attributes": { "lineItemId": "124773003405488128", "lineItemName": "LI Retailer ABC Category B", "retailerId": "401887", "retailerName": "Retailer ABC", "campaignId": "124755545923269376", "campaignName": "Campaign AAA", "accountId": "97393138059194368", "accountName": "Test Account", "countKeywords": 4 } }, // ... { "id": "358669652976373760", "type": "LineItemKeywordReviewReport", "attributes": { "lineItemId": "9979917896105882144", "lineItemName": "LineItem ABC Producs Jan 2025", "retailerId": "401887", "retailerName": "Retailer ABC", "campaignId": "106358893501214720", "campaignName": "Sponsored Products Jan 2025", "accountId": "97393138059194368", "accountName": "Test Account", "countKeywords": 5 } } ], "warnings": [], "errors": [] } ``` *** ## Get Keywords to review This endpoint retrieves the list of all Keywords review state for the provided Line-Item ID. This endpoint evolved from previous versions to allow Supply Accounts considered as eligible reviewers to review keywords from line-items of other accounts not included in their consent access (applicable for Private Market networks). ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/keywords ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "124848016959148032", "type": "RetailMediaKeywordsModel", "attributes": { "keywords": { "top": { "reviewState": "InReview", "matchType": "PositiveExactMatch", "bid": 2.00, "inputKeywords": { "positiveExact": [ "top", "tops" ] }, "createdAt": "2024-05-17T02:12:52.1208996", "updatedAt": "2024-05-17T02:12:52.8112947" }, "t-shirt": { "reviewState": "InReview", "matchType": "PositiveExactMatch", "bid": 1.00, "inputKeywords": { "positiveExact": [ "t-shirts", "tshirt", "t shirt" ] }, "createdAt": "2024-07-25T05:13:47.766958", "updatedAt": "2024-07-25T05:13:48.2112064" }, "top woman": { "reviewState": "InReview", "matchType": "PositiveExactMatch", "bid": null, "inputKeywords": { "positiveExact": [ "tops for women", "women's top" ] }, "createdAt": "2024-07-29T06:45:17.5861897", "updatedAt": "2024-07-29T06:45:17.8158725" } } } } } ``` *** ## Review Keywords for a Line-item This endpoint allows retailers users to review (approve/reject) one or multiple keywords for the respective Line-Item ID. The response will return the full list of Keywords Reviews (including still `InReview`, `Approved` and `Rejected`). Once keywords are reviewed through this endpoint, the Keywords Approval Report (available in `/accounts/{accountId}/keywords/in-review-report`) will reflect the updated amount of keywords left for review. ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/keywords/review ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/review" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "data": { "attributes": { "keywords": [ { "phrase": "top", "reviewState": "rejected" }, { "phrase": "t-shirt", "reviewState": "approved" } ] } } }' ``` ```python Python expandable theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/review" payload = json.dumps({ "data": { "attributes": { "keywords": [ { "phrase": "vegetable", "reviewState": "approved" }, { "phrase": "tomato", "reviewState": "rejected" } ] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"attributes\":{\"keywords\":[{\"phrase\":\"vegetable\",\"reviewState\":\"approved\"},{\"phrase\":\"tomato\",\"reviewState\":\"rejected\"}]}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/review") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/balances'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"attributes":{"keywords":[{"phrase":"vegetable","reviewState":"approved"},{"phrase":"tomato","reviewState":"rejected"}]}}}'); try{ $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "type": "RetailMediaKeywordsReviewResult", "attributes": { "keywords": [ { "phrase": "top", "reviewState": "Rejected" }, { "phrase": "t-shirt", "reviewState": "Approved" }, { "phrase": "top woman", "reviewState": "InReview" } ] } }, "warnings": [], "errors": [] } ```
## **Responses**

Response

Title

Detail

Troubleshooting

🟢 200

Call executed with success

🟢 201

Entity request created with success

🔴 400

Keyword Error

One or more keywords given are not found on this line item

Double-check the value of the keyword informed in the Review request; it should contain only existing keywords with "reviewState": "InReview" retrieved from Get Keywords endpoint

🔴 400

Model validation error

Error converting value "xyz" to type 'Criteo.RetailMedia. \ '

Value "xyz" provided is not a valid value for that respective parameter. Check the error details for more information

🔴 403

Forbidden

The account ID provided is not suitable for those endpoints (only supply accounts), the account is not included in the consent from the API app or the API app doesn't have Manage access to the Campaign domain/scope.

Review the Types of Permissions in Authorization Requests

***
## What's next * [Bid Multipliers](/retail-media/docs/bid-multipliers) * [Budget Overrides](/retail-media/docs/budget-overrides) * [Minimum Bid](/retail-media/docs/minimum-bid) # Keywords Source: https://developers.criteo.com/retail-media/docs/keywords ## Introduction The `keywords` endpoints allows you to control your Onsite Sponsored Products line item by providing visibility to users on **what keyword(s) are applied to line items**. This allows to determine which keyword(s) to target positively or negatively. The endpoint can also provide **keyword bidding capabilities** to optimize line items based on relevant keywords. Visit the [**Onsite Sponsored Products**](/retail-media/docs/onsite-sponsored-products) page for a complete summary of Criteo's keyword service. The `search` endpoint evaluates each query against product eligibility rules configured for the current page or context. * Queries may reference products that are not eligible to be displayed on the page. These products will be excluded from the search results. * Queries may also match products that are eligible to be displayed. These products can be returned in the response. As a result, the response may not include all products relevant to the query—only those that meet the page’s eligibility criteria. *** ## Endpoints

Verb

Endpoint

Description

GET

/line-items/\{lineItemId}/keywords

Retrieve a set of positive and negative keywords for a line item

GET

/line-items/\{lineItemId}/keywords/recommended

Retrieve a collection of recommended keywords for a line item

POST

/line-items/\{lineItemId}/keywords/add-remove

Add or remove keywords from a line item

POST

/line-items/\{lineItemId}/keywords/set-bid

Set a bid override at keyword level

*** ## Keyword Attributes

Attribute

Data Type

Description

id \*

string

Line Item ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

keywords \*

object

Keywords structure, indexed by normalized keyword phrases each of them containing structure of:

  • matchType
  • bid
  • inputKeywords
  • reviewState
  • createdAt
  • updatedAt

matchType \*

enum

Matching algorithm type to be used when comparing this keyword with shopper search phrases.

Accepted values:

  • PositiveExactMatch : normalized keyword is an exact match for the normalized search phrase bid
  • NegativeExactMatch : normalized keyword is an exact match for the normalized search phrase do not bid
  • NegativeBroadMatch : normalized keyword is a substring of the normalized search phrase do not bid

Default: PositiveExactMatch

Writeable? N / Nullable? N

reviewState

enum

Status of Keyword review, only applicable for PositiveExactMatch match type keywords.

Keywords not reviewed by the automatic keyword service will be reviewed and approved by the retailer.

Accepted values:

  • InReview : keyword has been submitted manually, and the review is still pending
  • Approved : keyword was approved manually
  • AutoApproved : keyword was approved automatically
  • Rejected : keyword was rejected manually
  • AutoRejected : keyword was rejected automatically
  • Recommended : keyword was recommended by our keyword model

Default: InReview

Writeable? N / Nullable? N

bid

decimal

The bid override for the positive keyword. The keyword will use the default line item bid if the value is null . The currency of the bid is the default currency for the retailer. The bid can be applied to both manual keywords and recommended keywords.

Accepted values: retailer's minBid bid ≤ line-item's maxBid , available in the endpoints detailed in Catalog Endpoints and Onsite Display Line Items , respectively

Default: null

Writeable? Y / Nullable? Y

isDeleted

boolean

Control flag to add or remove the keyword from the line-item

Accepted values: true / false

Writeable? N / Nullable? N

inputKeywords \*

object

Keywords structure associated with line-item containing normalized keyword phrases and organized by match type.

Parameters:

  • positiveExact : list of supplied positive exact phrases
  • negativeExact : list of supplied negative exact phrases
  • negativeBroad : list of supplied negative broad phrases

phrase

string

Raw text of the keyword to be added or removed

Accepted values: up to 255-chars string

Writeable? Y / Nullable? N

createdAt

timestamp

Timestamp when keyword was configured in the line-item (or recommended to line-item)

Accepted values: yyyy-mm-ddThh:mm:ss (in ISO-8601 )

Writeable? N / Nullable? N

updatedAt

timestamp

Timestamp when keyword was last modified in the line-item (or recommended to line-item)

Accepted values: yyyy-mm-ddThh:mm:ss (in ISO-8601 )

Writeable? N / Nullable? N

*\*Required* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Get Keywords by Line Item ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/keywords ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords" \ -H "Authorization: Bearer " \ -H "Accept: application/json" ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") headers = { 'Authorization': 'Bearer ', 'Accept': 'application/json' } conn.request("GET", "/{version}/retail-media/line-items/358669652976373760/keywords", headers=headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords") .method("GET", null) .addHeader("Authorization", "Bearer ") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Authorization' => 'Bearer ', 'Accept' => 'application/json' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "358669652976373760", "type": "RetailMediaKeywordsModel", "attributes": { "keywords": { "vegetable": { "matchType": "NegativeBroadMatch", "bid": null, "inputKeywords": { "negativeBroad": [ "vegetable" ], "negativeExact": [], "positiveExact": [] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "tomato": { "matchType": "NegativeExactMatch", "bid": null, "inputKeywords": { "negativeBroad": [], "negativeExact": [ "tomatoes" ], "positiveExact": [] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "strawberry": { "matchType": "NegativeExactMatch", "bid": null, "inputKeywords": { "negativeBroad": [], "negativeExact": [ "strawberry" ], "positiveExact": [] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "broccoli": { "matchType": "NegativeExactMatch", "bid": null, "inputKeywords": { "negativeBroad": [], "negativeExact": [ "broccoli" ], "positiveExact": [] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "banana": { "matchType": "NegativeExactMatch", "bid": null, "inputKeywords": { "negativeBroad": [], "negativeExact": [ "banana" ], "positiveExact": [] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "pasta": { "reviewState": "Approved", "matchType": "PositiveExactMatch", "bid": null, "inputKeywords": { "negativeBroad": [], "negativeExact": [], "positiveExact": [ "pasta" ] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "milk": { "reviewState": "Approved", "matchType": "PositiveExactMatch", "bid": 0.50, "inputKeywords": { "negativeBroad": [], "negativeExact": [], "positiveExact": [ "milk" ] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "juice": { "reviewState": "Approved", "matchType": "PositiveExactMatch", "bid": null, "inputKeywords": { "negativeBroad": [], "negativeExact": [], "positiveExact": [ "juice" ] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "egg": { "reviewState": "Approved", "matchType": "PositiveExactMatch", "bid": 0.50, "inputKeywords": { "negativeBroad": [], "negativeExact": [], "positiveExact": [ "eggs" ] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" }, "fruit": { "matchType": "NegativeBroadMatch", "bid": null, "inputKeywords": { "negativeBroad": [ "fruits" ], "negativeExact": [], "positiveExact": [] }, "createdAt": "2025-01-01T00:00:00", "updatedAt": "2025-01-01T00:00:00" } } } }, /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` *** ## Get Recommended Keywords by Line Item This endpoint retrieves a collection of recommended keywords for a line item, created automatically by our keyword models. **Only the top 100 keywords will be returned** Automatic recommended keywords can change day to day, as are determined based on click volumes by users on Retailer's environment. Although significant changes are not expected, it is possible that the long tail of the top 100 keywords change slightly ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/keywords/recommended ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/recommended" \ -H "Authorization: Bearer " \ -H "Accept: application/json" ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") headers = { 'Authorization': 'Bearer ', 'Accept': 'application/json' } conn.request("GET", "/{version}/retail-media/line-items/358669652976373760/keywords/recommended", headers=headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/recommended") .method("GET", null) .addHeader("Authorization", "Bearer ") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/recommended'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Authorization' => 'Bearer ', 'Accept' => 'application/json' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "data": { "type": "RecommendedKeywords", "attributes": { "keywords": { "bar sound": { "reviewState": "AutoApproved", "matchType": "PositiveExactMatch", "bid": 1.0, "inputKeywords": { "positiveExact": [ "bar sound", "sound bar", "sound-bar", "sound bars", "sounds bar" ] }, "createdAt": "2025-01-01T07:00:00", "updatedAt": "2025-01-01T08:00:00" }, "dolby soundbar": { "reviewState": "Recommended", "matchType": "PositiveExactMatch", "bid": null, "inputKeywords": { "positiveExact": [ "dolby soundbars", "soundbar dolby" ] }, "createdAt": "2025-01-01T07:00:00", "updatedAt": "2025-01-01T08:00:00" }, "atmos": { "matchType": "NegativeBroad", "inputKeywords": { "negativeBroad": [ "atmos" ] }, "createdAt": "2025-01-01T07:00:00", "updatedAt": "2025-01-01T08:00:00" } }, "recommended": [ "atmos", "dolby soundbars", "sound bar", "sound bars", "soundbar dolby" ] } }, /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` *** ## Add or remove Keyword from Line Item ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/keywords/add-remove ``` **Negative Targeting v1** The negative keyword targeting in this API will eventually replace the [Negative Keyword Targeting](/retail-media/docs/negative-keywords-open-auction-only) endpoints. You may continue using those endpoints without disrupting your services. We recommend reviewing and testing the new Keyword endpoints to prepare for a future migration to these new endpoints. **Sample Request** ```bash cURL theme={null} curl -L -X POST "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/add-remove" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "data": { "id": "358669652976373760", "type": "RetailMediaKeywordAddRemove", "attributes": { "keywords": [ { "phrase": "cookies and bread", "matchType": "PositiveExactMatch", "isDeleted": "false" }, { "phrase": "raspberry", "matchType": "NegativeExactMatch", "isDeleted": "false" }, { "phrase": "potatoes", "matchType": "NegativeExactMatch", "isDeleted": "true" } ] } } }' ``` ```python Python expandable theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": { "id": "358669652976373760", "type": "RetailMediaKeywordAddRemove", "attributes": { "keywords": [ { "phrase": "cookies and bread", "matchType": "PositiveExactMatch", "isDeleted": "false" }, { "phrase": "raspberry", "matchType": "NegativeExactMatch", "isDeleted": "false" }, { "phrase": "potatoes", "matchType": "NegativeExactMatch", "isDeleted": "true" } ] } } }) headers = { 'Authorization': 'Bearer ', 'Content-Type': 'application/json', 'Accept': 'application/json' } conn.request("POST", "/{version}/retail-media/line-items/358669652976373760/keywords/add-remove", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java expandable theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, """ { "data": { "id": "358669652976373760", "type": "RetailMediaKeywordAddRemove", "attributes": { "keywords": [ { "phrase": "cookies and bread", "matchType": "PositiveExactMatch", "isDeleted": "false" }, { "phrase": "raspberry", "matchType": "NegativeExactMatch", "isDeleted": "false" }, { "phrase": "potatoes", "matchType": "NegativeExactMatch", "isDeleted": "true" } ] } } } """); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/add-remove") .method("POST", body) .addHeader("Authorization", "Bearer ") .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/add-remove'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', 'Accept' => 'application/json' )); $request->setBody(json_encode(array( "data" => array( "id" => "358669652976373760", "type" => "RetailMediaKeywordAddRemove", "attributes" => array( "keywords" => array( array( "phrase" => "cookies and bread", "matchType" => "PositiveExactMatch", "isDeleted" => "false" ), array( "phrase" => "raspberry", "matchType" => "NegativeExactMatch", "isDeleted" => "false" ), array( "phrase" => "potatoes", "matchType" => "NegativeExactMatch", "isDeleted" => "true" ) ) ) ) ), JSON_PRETTY_PRINT)); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response**\ *200 successful status will return an empty object array* ```json theme={null} {} ``` *** ## Set bid on Keyword Bids can be set on a keyword at any time, even when the keywords are still in the`InReview` state ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/keywords/set-bid ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST "https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/set-bid" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "data": { "type": "RetailMediaKeywordsSetBid", "id": "358669652976373760", "attributes": { "keywords": [ {"phrase": "eggs", "bid": "0.50"}, {"phrase": "milk", "bid": "0.50"} ] } } }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": { "id": "358669652976373760", "type": "RetailMediaKeywordsSetBid", "attributes": { "keywords": [ {"phrase": "eggs", "bid": "0.50"}, {"phrase": "milk", "bid": "0.50"} ] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'text/plain', 'Authorization': 'Bearer ' } conn.request("POST", "/{version}/retail-media/line-items/358669652976373760/keywords/set-bid", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, """ { "data": { "id": "358669652976373760", "type": "RetailMediaKeywordsSetBid", "attributes": { "keywords": [ {"phrase": "eggs", "bid": "0.50"}, {"phrase": "milk", "bid": "0.50"} ] } } } """); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/set-bid") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); `` ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/358669652976373760/keywords/set-bid'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'text/plain', 'Authorization' => 'Bearer ' )); $request->setBody(json_encode(array( "data" => array( "id" => "358669652976373760", "type" => "RetailMediaKeywordsSetBid", "attributes" => array( "keywords" => array( array("phrase" => "eggs", "bid" => "0.50"), array("phrase" => "milk", "bid" => "0.50") ) ) ) ), JSON_PRETTY_PRINT)); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** 200 successful status will return an empty object array. ```json theme={null} {} ``` *** ## Responses

Response

Description

🔵 200 OK

Call completed with success

🔵 201 OK

  • The call to add/remove the keyword from the line item was executed successfully
  • The call to set keyword bid to the line item was executed successfully

🔴 400 * Bad Request

Setting a bid for a positive keyword that doesn't exist on the line item.

Error Message

"On line item \{lineItemId} normalized keyword "\{keyword}"/en\_US not found"

Setting a keyword bid above the line-item maxBid value will result in a 400 bad request error message. In this example, the maxBid value is at least 0.40.

Error Message

"Invalid bid value, bid greater than maximum of 1.00000000, found for keyword: "

Setting a keyword bid below the retailer minBid value will result in a 400 bad request error message. In this example, the minBid value is at least 0.40.

Error Message

"Invalid bid value, bid less than minimum of 0.4000, found for keyword: "

***

## What's next * [Keyword Review](/retail-media/docs/keyword-review) # Line Items Source: https://developers.criteo.com/retail-media/docs/line-items ## Overview Each campaign consists of one or more line items. You can only run ads after creating a campaign and at least one line item. A line item allows you to select the products and the retailer where you'd like to advertise. Each line item can include multiple featured products but is restricted to a single retailer. To advertise across multiple retailers, you must create separate line items for each. Several settings are available to help you manage your budget and optimize ad delivery effectively. With the Criteo API, you can: * Manage your retail media line items * Configure line items, including budgets, flight dates, bids (for Onsite Sponsored Products), and targeting options (for Preferred Deals) * Retrieve products from your product catalog to advertise ### Line Item Settings 789d2f5 l3 line items * A line item promotes products for ads on a specific retailer. * Line items include settings such as start and end dates, optional budget controls, and associated retailers where ads are served. * Campaigns can manage budgets at both the line item and campaign level. * Several [reports](/retail-media/docs/demand-side-analytics-get-started) are available to measure line item performance. * Campaigns are limited to 10,000 non-archived line items. * Line items are automatically archived 90 days after their end date. ### Promoted Products 57f7b20 l4 products * A promoted product defines the product to be advertised on a line item. * Use your account [catalog](/retail-media/docs/catalogs) to identify eligible products for promotion. * Each product can have a specific bid amount if desired. * Line items can include up to 500 promoted products. *** ## Getting started 1. **Select products** from your account catalog to promote. 2. **Create a campaign** to define the marketing objective. 3. **Create a line item** within the campaign. 4. **Add products** to the line item to specify which products to promote. 5. **Assign the campaign** to an account balance for budget management. 6. **Activate your line item** to begin running ads! **Access to Preferred Deals capabilities** Preferred Deals are currently in beta and available only to our Retailer partners. To access Preferred Deals documentation, please contact your Criteo Account Manager. ***
## What's next * [Line Items Endpoints](/retail-media/docs/line-items-endpoints) * [Promoted Products](/retail-media/docs/promoted-products) * [Recommended Keywords](/retail-media/docs/recommended-keywords) * [Recommended Categories](/retail-media/docs/recommended-categories) * [Category Search](/retail-media/docs/categories) # Line Items Endpoints Source: https://developers.criteo.com/retail-media/docs/line-items-endpoints **Getting Started** 1. A line item holds promoted products to advertise on a single retailer. 2. Line items include basic settings such as start and end dates, optional budget controls, and the associated retailer where ads are served. 3. Budgets can also be managed at the campaign level. 4. Several [reports](/retail-media/docs/demand-side-analytics-get-started) are available to track line item performance. 5. Campaigns are limited to 10,000 non-archived line items. 6. Line items are automatically archived 90 days after their end date. *** ## Endpoints

Method

Endpoint

Description

GET

/accounts/\{accountId}/line-items

Retrieve all line items associated with a specific account.

GET

/line-items/\{lineItemId}

Retrieve details of a specific line item.

*** ## Line Item Attributes

Attribute

Data Type

Description

id

string

Line item ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

name

string

Line item name, must be unique within a campaign

Accepted values: up to 255-chars string

Writeable? Y / Nullable? N

campaignId

string

Campaign ID, in which the respective line item belongs

Accepted values: string of int64

Writeable? N / Nullable? N

type

enum

Campaign type

Accepted values: auction , preferred

Writeable? Y / Nullable? N

targetRetailerId

string

Retailer ID, in which the respective line item serves ad on

Accepted values: string of int64

Writeable? N / Nullable? N

startDate

date

Start date of the line item, in the Account timezone; used to schedule its activation and start serving ads.

To understand the conditions that will cause a status to change, check out Campaign & Line Item Status

Accepted values: yyyy-mm-dd

Writeable? Y / Nullable? N

endDate

date

End date of the line item, in the Account timezone; serves ads indefinitely if omitted or set to null .

A timestamp can be included as well if the line item is desired to end at a certain time of day

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601 )

Default: if null or absent, balance will be available indefinitely

Writeable? Y / Nullable? Y

budget

decimal

Line item lifetime spend cap, uncapped if omitted or set to null

Accepted values: budget ≥ 0.0

Default: 0.0

Writeable? Y / Nullable? Y

budgetSpent

decimal

Budget amount the line item has already spent

Accepted values: budgetSpent ≥ 0.0

Default: 0.0

Writeable? N / Nullable? N

budgetRemaining

decimal

Budget amount the line item has remaining until cap is hit; null if budget is uncapped

Accepted values: 0 ≤ budgetRemaining budget

Default: 0.0

Writeable? N / Nullable? Y

status

enum

Line item status; can only be updated by a user to active or paused ; all other values are applied automatically depending on financials, flight dates, or missing attributes required for line item to serve.

Accepted values: active , paused , scheduled , ended , budgetHit , noFunds , draft , archived

Writeable? Y / Nullable? N

createdAt

timestamp

Timestamp of line item creation, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601)

Writeable? N / Nullable? N

updatedAt

timestamp

Timestamp of last line item update, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601)

Default: same as createdAt

Writeable? N / Nullable? N

*** ## Get all Line Items This endpoint lists all line items in the specified campaign. Results are paginated using `pageIndex` and `pageSize` query parameters; if omitted, defaults to `0` and `25`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/line-items ``` **Sample Request** ```bash cURL theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/accounts/123456/line-items?pageIndex=0&pageSize=25" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/accounts/4/line-items?pageIndex=0&pageSize=25" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/accounts/4/line-items?pageIndex=0&pageSize=25") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/accounts/4/line-items?pageIndex=0&pageSize=25'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "data": [ { "type": "RetailMediaLineItem", "id": "9979917896105882144", "attributes": { "campaignId": "8343086999167541140", "name": "Line Item 123", "targetRetailerId": "3239117063738827231", "startDate": "2020-04-06", "endDate": null, "budget": null, "budgetSpent": 2383.87, "budgetRemaining": null, "status": "active", "createdAt": "2020-04-06T17:29:11+00:00", "updatedAt": "2020-04-06T17:29:11+00:00" } }, // ... { "type": "RetailMediaLineItem", "id": "6854840188706902009", "attributes": { "campaignId": "8343086999167541140", "name": "Line Item 789", "targetRetailerId": "18159942378514859684", "startDate": "2020-04-08", "endDate": null, "budget": 8000.00, "budgetSpent": 1921.23, "budgetRemaining": 6078.77, "status": "paused", "createdAt": "2020-04-06T23:42:47+00:00", "updatedAt": "2020-06-03T03:01:52+00:00" } } ], "metadata": { "totalItemsAcrossAllPages": 105, "currentPageSize": 25, "currentPageIndex": 0, "totalPages": 5, "nextPage": "https://api.criteo.com/{version}/retail-media/accounts/123456/line-items?pageIndex=1&pageSize=25", "previousPage": null } } ``` *** ## Get a specific Line Item This endpoint retrieves details for a specified line item by its ID ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId} ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json theme={null} { "data": { "type": "RetailMediaLineItem", "id": "2465695028166499188", "attributes": { "campaignId": "8343086999167541140", "name": "My New Line Item", "targetRetailerId": "18159942378514859684", "startDate": "2020-04-06", "endDate": null, "budget": null, "budgetSpent": 0.00, "budgetRemaining": null, "status": "draft", "createdAt": "2020-04-06T06:11:23+00:00", "updatedAt": "2020-04-06T06:11:23+00:00" } } ``` *** ## Responses

Response

Description

🟢

200

Call completed successfully. The specified line item details are returned.

🔴

403

API user is not authorized to make requests for the account ID. To request authorization, follow the

authorization request

steps.

🔴

404

Line item ID not found. Ensure the

lineItemId

is correct and exists.

***
## What's next * [Promoted Products](/retail-media/docs/promoted-products) * [Recommended Categories](/retail-media/docs/recommended-categories) * [Recommended Keywords](/retail-media/docs/recommended-keywords) * [Category Search](/retail-media/docs/categories) # Metrics and Dimensions (SSP) Source: https://developers.criteo.com/retail-media/docs/metrics-and-dimensions-ssp ## Introduction In this page you will find all the metrics and dimensions that are currently support with the [Revenue Report](/retail-media/docs/revenue-report-ssp). Please note that many of the metrics and dimensions listed here are currently supported only through the API. *** ## Dimensions

Dimensions

Description

date

The date of when reported activity took place occurred

hour

The hour of the day when rendered ad received an event

parentAccount

The associated account that is connected to the supply or demand account

accountId

The computed and unique identifier of the supply or demand account

accountName

The supply or demand account name

accountTypeName

The account type of the reported activity. Options will include:

  • Demand \- for revenue generated from an indirect sold or private market demand account.
  • Supply \- revenue was generated from direct sold campaigns

advertiserType

The advertiser account type where the ad activity originated from. Options includes:

  • retailer \- ad activity sold directly in the supply account
  • brand \- ad activity sold to a demand brand account in the Criteo network or through private market
  • seller \- ad activity sold to a demand seller account in the Criteo network or through private market

campaignId

The computed unique campaign identifier of the demand or supply account that generated the activity

campaignName

The campaign name of the demand or supply account that generated the activity

campaignTypeName

The campaign type available. Available options are Open Auction or Preferred Deals

campaignStartDate

The start date set for the campaign

campaignEndDate

The end date set for campaign

lineItemId

The computed unique identifier of a line-item

lineItemName

The line-item name provided by the advertiser

lineItemStartDate

The start date set for the line-item

lineItemEndDate

The end date set for the line-item

lineItemStatus

The status of the line-item associated with the selected dimension, such as the date or hour indicating of when the event took place.

retailerId

The retailer ID that is associated with the report activities . This will be the same id provided in the API call

retailerName

The retailer name that is associated to the report activity.

brandId

The brand ID provided by the retailer brand ID associated with the advertised SKU

brandName

The retailer brand name associated with the advertised SKU

placementId

The id of the placement where the ad creative was displayed.

placementName

The name of the placement where the ad creative was displayed.

pageTypeName

The page type where the ad was rendered

environment

The environment where the ad was rendered on. Options will include web, mobile and app

soldBy

The source of where activities originated from. Options will include Direct Sold , Indirect Sold or Private Market

buyType

The campaign buying strategy. Options will include auction , preferredDeals , or sponsorship

salesChannel

Sales channel the attributed purchase was made through.

Available options are:

online * for sales attributed to an ad that was served and purchased online or in-app

offline * for sales to an ad that was served online but purchase in store

attributionSettings

The lookback click and view attribution window of the requested report. The attribution window is based on the parameters selected in the report API request. The attributedSettings field will be based on the lookback windows provided in the API call.

Post-Click (C) lookback window

none, 7, 14, 30 days

Post-view (V) lookback window

none, 1, 7, 14, 30 days

activityType

The type of ad engagement the sale was attributed to. Available options will include imp for impressions or click for clicks

keyword

Keyword or phrase used to land on the search page where an ad creative rendered.

skuRelation

Attribution rule used to match the impression or click to a sale. Available options are: Same SKU , Same Parent SKU , Same Category , Same Brand or Same Seller

advProductId

Advertised product ID; this references the same product ID of the retailer Catalogs

advProductName

Advertised product name

advProductGtin

Advertised product GTIN

advProductMpn

Advertised product MPN

pageCategory

The retailer defined category of the page where ads are rendered

retailerCategoryId

The retailer category provides the type of product the SKU belongs to. This fields provides the id of that product type

retailerCategoryName

The name of that product type

taxonomyBreadcrumb

The category breadcrumb of the product using retailer product taxonomies (L1, L2 L3 etc.). This is for analysis where SKUs are present in the displays

taxonomy1Id

taxonomy2Id

taxonomy3Id

taxonomy4Id

taxonomy5Id

taxonomy6Id

taxonomy7Id

The ID SKU's taxonomy. The revenue report provides the option to select level 1 through level 7.

ℹ️ Note : SKUs will normally have at least the primary sku taxonomy (L1). All following levels are considered additional taxonomies. If a SKU does not have an additional taxonomy level, the report will default to unknown

taxonomy1Name

taxonomy2Name

taxonomy3Name

taxonomy4Name

taxonomy5Name

taxonomy6Name

taxonomy7Name

The name SKU's taxonomy. If a SKU does not have an additional taxonomy level, the report will default to unknown

targetedKeywordType

The conquesting ad strategy used with the keywords. Output values of this dimension includes:

Conquesting – Search terms the line item uses to target competitors' branded keywords.

Branded – Search terms the line item uses to target its own branded keywords.

Generic – Search terms that are neutral or non-branded, targeted by the line item.

Unknown – Search term and SKU pairs that don’t have a defined conquesting type. These are typically keywords used before a conquesting strategy was implemented.

*** ### Metrics

Dimensions

Description

numberOfCampaigns

the total count of campaigns associated with the selected report dimension.

numberOfLineItems

The total count of line-items associated with the selected report dimension.

numberOfSkus

The total count of skus associated with the selected report dimension.

skuPrice

The total price of each SKU unit.

  • *Note*\*: It is recommended to utilize metrics such as advProductId , advProductGtin , and advProductMpn to access individual SKU prices. However, when considering other dimensions at the line-item, campaign, or account level, the sum of all SKU prices will be calculated.

pageViews

The count of unique ad calls on a retailer network. Use this metric when referencing to dimensions that relates to itself to receive a more comprehensive data. Using dimensions such as pageTypeName , placementId or placementName will provide you data to understand the performance of this metric.

impressions

An impression represents each time an ad renders on a page, regardless of clicks or views.

An impression for a Sponsored Product ad is when the sponsored SKU renders on the page (the product being the ad).

An impression for a Commerce Display ad is when the entire banner (creative + product) renders on the page.

An impression for a Display banner ad is when the creative banner renders on the page.

productClicks

Total count of the click events that occur when a user clicks a product in a placement

placementClicks

Total count of the click events that occur when a user clicks a placement

clicks

The total count of all click events

  • *Formula*\*: placementClicks * productClicks

sales

The total attributed revenue from product sales

units

The total attributed product units sold

assistedSales

Sales revenue attributed to a click or impression of all the ads that appeared on a page within the chosen attribution window (specified at the campaign level) but were not determined to be the attributedSales (the last ad before the customer purchased).

assistedUnits

The number of events that occurred that helped generated a sale. Assisted units are excluded from attributedUnits . This means its not counted in the attributed units calculation

openAuctionRevenue (*deprecated*)

The total amount of sponsored products revenue generated on the set date, not including sponsorships.

preferredDealsRevenue (*deprecated*)

The total amount of onsite display revenue generated on the set date, not including sponsorships.

sponsoredProductRevenue

The total amount of sponsored products revenue generated on the set date, not including sponsorships.

onsiteDisplayRevenue

The total amount of onsite display revenue generated on the set date, not including sponsorships.

revenue

The total revenue generated on the set date. The revenue metric take the total revenue generated across preferred deals or auction campaigns for that period and is computed the same way as the openAuctionRevenue and preferredDealsRevenue .

transactions

The total amount of attributed orders/transactions

ctr

The percentage of shoppers who clicked an ad rendered on a page.

Product and Product Category Report Types

  • *Formula*\*: clicks / productImpressions

All other report types

  • *Formula*\*: clicks / placementImpressions
  • *Note*\*: there are two types of impressions that can be measured to know the success of your ads: placementImpressions and productImpressions . Preferred deals have placement impressions, while open auction uses product impressions. For more info: Product & Placement Impression Help Center article

cr

The number of conversion generated by the visitors to the retailer site.

  • *Formula*\*: number of conversions / clicks \* 100

cpc

Average cost-per-click calculated by dividing openAuctionRevenue / clicks or preferredDealsRevenue / clicks

cpm

Average cost per mille calculated by diving preferredDealsRevenue / impressions * 1000

roas

Return-on-ad-spend (ROAS), calculated by dividing sales / openAuctionRevenue or sales / preferredDealsRevenue

workingMedia

The total spend paid by the brand

netRevenue

The total revenue from brand spend for the retailer

uniqueVisitors

The number of distinct shoppers exposed to an ad within the reporting period. Each shopper is counted once using the retailer cookie ID.

uniqueVisitors is an estimate, minor 1% discrepancies can occur.

Criteo uses retailer cookie IDs to identify users across sessions on the same device. Each ID can last up to a year, provided the user does not clear their cookies.

frequency

An average representing how often an impression has been shown to the same user

The `uniqueVisitors` metric may show discrepancies compared to UI values when querying long time ranges. Due to API limitations, reports can only be retrieved for a **maximum of 100 days per request**. To analyze longer periods, multiple requests must be performed and aggregated client-side. While this approach works for additive metrics (e.g. impressions), it may lead to **double counting** for user-based metrics such as `uniqueVisitors` or `reach`, since the same user can appear in multiple reporting windows. As a result, summing `uniqueVisitors` across multiple requests may produce higher values than those displayed in the UI, where user deduplication is applied across the full time range. *** ### Video Metrics

Key-Values

Data Type

Description

videoViews

string

The number of times at least 50% of the video ad appeared for at least 2 seconds (MRC standard).

videoStarts

string

The number of times one of your video ads started playing.

videosPlayedTo25

string

The number of times one of your videos played to at least 25% of its duration.

videosPlayedTo50

string

The number of times one of your videos played to at least 50% of its duration.

videosPlayedTo75

string

The number of times one of your videos played to at least 75% of its duration.

videosPlayedTo100

string

The number of times one of your videos played to 100% of its duration.

videoPlayingRate

string

The average played percentage of a started video.

Formula: Sum of Quartiles x 0.25 / (4 x Video starts)

videoCompletionRate

string

The percentage of started videos that played for their entire duration.

Formula: Number of videos that played to completion / Total number of videos started \* 100

videoStartingRate

string

The percentage of videos printed that started playing.

Formula: Video Starts / Placement Impressions

videoPlayingRate

string

The average played percentage of a started video.

Formula: Sum of Quartiles x 0.25 / (4 x Video starts)

videoMuted

string

The number of times users clicked the “mute” button on your video.

videoUnmuted

string

The number of times users clicked the “unmute” button on your video.

videoResumed

string

The number of times users activated the resume control after the creative had been stopped and paused.

videoPaused

string

The number of times users activated the pause control on the video.

videoViewability

string

The percentage of video ads that were considered viewable. At least 50% of the ad’s pixels must be visible on the screen for at least two continuous seconds (MRC standard). Requires OMID support.

Formula: Viewable Impressions / Placement Impressions

***
# Metrics & Dimensions (Fill Rate Report) Source: https://developers.criteo.com/retail-media/docs/metrics-dimensions-fill-rate-report ## Introduction In this page, you will find all the metrics and dimensions that are currently supported in the reports for Supply Side accounts: * [Revenue Report](/retail-media/docs/revenue-report-ssp): provides attributed performance data from campaigns. * [Fill Rate Report](/retail-media/docs/fill-rate-report): provides summary of placement opportunities and impression filled and covered in retailer(s) inventory. Please note that some of the metrics and dimensions listed here are currently supported only through the API. *** # Fill Rate Report ## Dimensions

Dimensions

Description

date

The date of when reported activity took place occurred

retailerId

The retailer ID that is associated with the report activities. This will be the same id provided in the API call

retailerName

The retailer name that is associated to the report activity.

environment

The environment where the ad was rendered on. Options will include web, mobile and app

pageTypeName

The page type where the ad was rendered

placementId

The id of the placement where the ad creative was displayed.

placementName

The name of the placement where the ad creative was displayed.

adServerType

The ad server where the ad was rendered on.

Value: Criteo and GAM

retailerCategoryId

The retailer category provides the type of product the SKU belongs to. This field provides the ID of that product type.

retailerCategoryName

The name of that product type

servedCategory

The category breadcrumb of the retailer page where ads are rendered

Example: "*beauty and grooming > fragrances > deodorants > sprays > jive sprays > jive moon dream 9 piece body spray - for men & women*"

*** ## Metrics

Dimensions

Description

availablePlacements

The number of available placements that were available to fill, including non-deliverable and deliverable placements.

clicks

The total count of all click events

Formula : placementClicks * productClicks

coverageRate

The number of covered placements divided by the number of deliverable placements

coveredPlacements

A placement with candidates where Criteo has provided SKUs or line-items in the ad response

cpc

Average cost-per-click

Formula : openAuctionRevenue / clicks or preferredDealsRevenue / clicks

cpm

Average cost per *mille*, calculated by:

Formula : preferredDealsRevenue / impressions * 1000

deliverablePlacements

Available placement that the retailer allowed Criteo to run an auction for

fillRate

The number of times a deliverable placement on a page was populated with an ad (even if the impression was not viewable). Calculated by dividing the placement impressions by deliverable placements.

Formula : placementImpressions / deliverablePlacements

impressions

An impression represents each time an ad renders on a page, regardless of clicks or views.

An impression for a Sponsored Product ad is when the sponsored SKU renders on the page (the product being the ad).

An impression for a Commerce Display ad is when the entire banner (creative + product) renders on the page.

An impression for a display banner ad is when the creative banner renders on the page.

netRevenue

The total revenue from brand spend for the retailer

nonDeliverablePlacements

A non-deliverable placement is a placement against which Criteo is not allowed by the retailer to run an auction.

pageViews

The count of unique ad calls on a retailer network. Use this metric when referencing to dimensions that relates to itself to receive a more comprehensive data. Using dimensions such as pageTypeName , placementId or placementName will provide you data to understand the performance of this metric.

placementClicks

Total count of the click events that occur when a user clicks a placement

placementImpressions

The number of placement impressions.

placementImpressionsCTR

The percentage of shoppers who clicked an ad placement rendered on a page

Formula : ( placementClicks * productClicks ) / placementImpressions

placementImpressionsRevenue

The total revenue generated by placement impressions of CPM ads

placementsWithCandidates

A placement with candidates is a placement for which Criteo is allowed by the retailer to run an auction and has sufficient information and demand to run it.

productClicks

Total count of the click events that occur when a user clicks a product in a placement

productClicksRevenue

The total revenue generated by product clicks of CPC ads

productImpressions

The number of filled product impressions

productImpressionsCTR

The number of clicks divided by the number of product impressions

Formula : productClicks / productImpressions

revenue

The total revenue generated on the set date. The revenue metric takes the total revenue generated across preferred deals or auction campaigns for that period and is computed the same way as the openAuctionRevenue and preferredDealsRevenue

unfilledPlacements

The number of unfilled placements

workingMedia

The total spend paid by the brand

*** ### Fill Rate Unfilled Reasons

Reason

Definition

Uncovered

totalUnfilledPlacements

The number of available ad placements that did not serve any impressions.

unfilledNotEnoughDemand

There is not enough line items eligible to the placement for run of site placements.

uncoveredBrokenPlacement

Ads returned to the retailer, but on placements that the retailer rarely paints. If a placement has a painted rate of less than 1% over the last 7 days, it can be considered as broken.

uncoveredFilteredOutDemand

Filtering reasons are the set of reasons for which line items can and will be excluded from pre-auctions, which decreases the number of ad opportunities overall. Filtering reasons may be of technical, supply, or demand nature (out of stock, dayparting,

audience targeting, capping…)

uncoveredNoDemandBrandedKeywordConquestingDisabled

Available opportunities without candidate campaigns, that happen on branded keywords on retailers that disabled conquesting (on that particular placement). No demand on branded keyword conquesting disabled

uncoveredNoDemandBrandedKeywordConquestingEnabled

Available opportunities without candidate campaigns, that happen on branded keywords on retailers that enabled conquesting (on that particular placement)

uncoveredNoDemandUnbrandedInventory

Ad placements available on general (non-branded) inventory, but no campaigns are set up to use them

uncoveredNotPainted

Ads returned to the retailer but not displayed (on placements that aren't broken).

uncoveredSearchTermWithoutCategory

Ad placements on keywords that the keyword model cannot

categorize.

Undeliverable

nondeliverableBlockedOptOut

Ad placements for opt-out users that are not delivering because you have not enabled ads for these users

nonDeliverableBlockedPageCategory

Ad placements on pages where you have blocked Criteo from running auctions (e.g., some categories on which you do not want any ads to be served)

nonDeliverableInsufficientOrganicResults

Ad placements where the page does not have enough organic results to display ads. For example, if an ad is meant to appear on line 5 but fewer than 5 lines of products exist.

nonDeliverableTestPlacement

These are ad placements that are still in testing and not fully enabled.

nonDeliverableUnmappedCategories

Ad placements on category and merchandising pages that aren't deliverable because their category keys are missing from the retailer’s product feed.

nonDeliverablePagesWithUnknownProducts

Product pages where items can't be identified in the retailer's product feed.

***
## What's next * [Fill Rate Report](/retail-media/docs/fill-rate-report) # Minimum Bid Source: https://developers.criteo.com/retail-media/docs/minimum-bid ## Introduction 1. An [Onsite Sponsored Products](/retail-media/docs/onsite-sponsored-products) line item holds promoted products to advertise on a single retailer. 2. Line items have bid settings, start & end dates, and optional budgeting & pacing controls. 3. Target & maximum bid settings must respect minimum bid (`minBid`), that can be set at product SKU level, to start delivering ads 4. Products SKU IDs are available through [Catalog](/retail-media/docs/catalogs) endpoints. *** ## Endpoints

Verb

Endpoint

Description

POST

/retailers/\{retailerId}/cpc-min-bids

Search for min bid CPC defined by collection of SKU IDs

*** ## Minimum Bid Attributes

Attribute

Data Type

Description

retailerId \*

string

Retailer ID where the line item will serve ads on

Accepted values: int64

Writeable? N / Nullable? N

skuIds \*

list \

List of SKU IDs in which the minimum bid is requested (usually, the SKUs promoted by the line item).

Values are available through Catalog endpoints

Accepted values: at least, an empty list \[]

Writeable? N / Nullable? N

skuId

string

SKU ID respective to the minBid in the response

Accepted values: SKU IDs from catalog

Writeable? N / Nullable? N

overallMinBid

decimal

Overall minimum bid resulted from the list of SKUs requested, that the line item should respect to, effectively, deliver ads

Acceptable values: at least 0.01

Writeable? N / Nullable? N

minBid

decimal

Minimum bid for the respective SKU

Acceptable values: at least 0.01

Writeable? N / Nullable? N

*\*Required* *** ## Retrieve Minimum Bid from SKU IDs **Sample Request** ```bash cURL theme={null} curl -L -X POST "https://api.criteo.com/{version}/retail-media/retailers/12345/cpc-min-bids" \ -H 'Accept: application/json' \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "data": { "type": "", "attributes": { "skuIds": [ "a1b2c3", "d4e5f6", "g7h8i9" ] } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/retailers/12345/cpc-min-bids" payload = json.dumps({ "data": { "type": "", "attributes": { "skuIds": [ "a1b2c3", "d4e5f6", "g7h8i9" ] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"type\":\"\",\"attributes\":{\"skuIds\":[\"a1b2c3\",\"d4e5f6\",\"g7h8i9\"]}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/retailers/12345/cpc-min-bids") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/retailers/12345/cpc-min-bids'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"type":"","attributes":{"skuIds": ["a1b2c3","d4e5f6","g7h8i9"]}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "data": [ { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 10.00, "pageType": "Home", "creativeId": "758332652442947584" } }, { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 2.50, "pageType": "Search", "creativeId": "758332652442947584" } }, { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 2.50, "pageType": "ProductDetail", "creativeId": "758332652442947584" } }, // ... { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 2.50, "pageType": "Confirmation", "creativeId": "758332652442947584" } }, { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 10.00, "pageType": "Home", "creativeId": "735093382380679168" } }, { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 2.50, "pageType": "Search", "creativeId": "735093382380679168" } }, { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 2.50, "pageType": "ProductDetail", "creativeId": "735093382380679168" } }, { "type": "DisplayAuctionMinBidResult", "attributes": { "minBid": 2.50, "pageType": "Confirmation", "creativeId": "735093382380679168" } } ], "warnings": [], "errors": [] } ``` *** ## Responses

Response

Description

🟢 200

Call executed with success

🔴 400

json-serialization-error

Required attribute missing or with unexpected format in request's body

🔴 404

Not Found

Retailer ID informed in request's path was not found

***
## What's next * [Demand Side Analytics (DSP)](/retail-media/docs/analytics) * [Supply Side Analytics (SSP)](/retail-media/docs/supply-side-reporting-ssp) # Missed Opportunities Report Source: https://developers.criteo.com/retail-media/docs/missed-opportunities-report POST /reports/missed-opportunities — diagnose budget cap-out and estimate missed delivery for Retail Media DSP campaigns. This endpoint enables Retail Media DSP partners to diagnose budget cap-out and estimate missed delivery for their campaigns and line items. Cap-out occurs when a line item exhausts its daily budget before the day ends, causing it to stop participating in eligible auctions. Missed traffic is reported for any line item that did not participate in all eligible auctions during the day. The response is aggregated — one row per day per line item (or per combination of dimensions you specify). All metrics relate to delivery shortfalls; no performance metrics (impressions served, clicks, revenue) are included. For performance metrics, use [`POST /reports/performance`](/retail-media/docs/performance-report). **Primary audience:** Engineers and ops teams diagnosing delivery shortfalls. Not a campaign performance reporting surface. The endpoint supports asynchronous report generation. Submit a request, poll for status, and download the output when ready. *** ## Request ```http theme={null} POST /2026-07/retail-media/reports/missed-opportunities ``` ### Required fields `startDate`, `endDate`, `filters`, `dimensions`, and `metrics` are all required. `filters` must contain exactly one scope filter (`filters.accountIds[]`, `filters.campaignIds[]`, or `filters.lineItemIds[]`). | Field | Type | Description | | ----------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------- | | `startDate` | string | Inclusive report start date. ISO 8601 date (`YYYY-MM-DD`). | | `endDate` | string | Inclusive report end date. ISO 8601 date (`YYYY-MM-DD`). Must be ≥ `startDate`. Dates are interpreted in UTC. | | `filters` | object | Required. Must contain exactly one of the scope filters below. | | `filters.accountIds[]` | array of strings | Scope to all line items under this account. Mutually exclusive with `campaignIds` and `lineItemIds`. | | `filters.campaignIds[]` | array of strings | Scope to all line items under this campaign. Mutually exclusive with `accountIds` and `lineItemIds`. | | `filters.lineItemIds[]` | array of strings | Scope to this line item. Mutually exclusive with `accountIds` and `campaignIds`. | | `dimensions` | array of strings | Required. Output grouping fields. See [Dimensions](#dimensions) below. | | `metrics` | array of strings | Required. Output measure fields. See [Metrics](#metrics) below. | ### Optional fields | Field | Type | Default | Description | | ------------------------- | ---------------- | -------------- | ---------------------------------------------------------------- | | `format` | string | `json-compact` | Output format: `json`, `json-compact`, `json-newline`, or `csv`. | | `filters.salesChannels[]` | array of strings | — | Filter by sales channel. | | `filters.mediaTypes[]` | array of strings | — | Filter by media type. | ### Example request ```http theme={null} POST /2026-07/retail-media/reports/missed-opportunities Authorization: Bearer {token} Content-Type: application/json { "data": { "type": "AsyncMissedOpportunitiesReport", "attributes": { "startDate": "2026-05-01", "endDate": "2026-05-07", "filters": { "lineItemIds": ["301234567890123457"] }, "dimensions": ["date", "lineItemId", "lineItemName"], "metrics": ["missedTraffic", "missedSpend", "capoutHour"] } } } ``` *** ## Response A successful request returns `200 OK` with a `reportId`: ```json theme={null} { "data": { "type": "StatusResponse", "id": "4ddbf658-e588-41b7-bd21-82b0f93bec32", "attributes": { "status": "pending", "rowCount": 0, "fileSizeBytes": 0, "md5CheckSum": null, "createdAt": "2026-07-28T13:37:21.000Z", "expiresAt": null, "message": null, "id": "4ddbf658-e588-41b7-bd21-82b0f93bec32" } } } ``` Poll for status until `status` is `success` or `failure`: ```http theme={null} GET /2026-07/retail-media/reports/{reportId}/status Authorization: Bearer {token} ``` ```json theme={null} { "data": { "type": "StatusResponse", "id": "4ddbf658-e588-41b7-bd21-82b0f93bec32", "attributes": { "status": "success", "rowCount": 7, "fileSizeBytes": 937, "md5CheckSum": "a7113a91e30cc0b0de3827703280fe8f", "createdAt": "2026-07-28T13:37:21.000Z", "expiresAt": "2026-08-04T13:37:22.000Z", "message": "rows_count=7", "id": "4ddbf658-e588-41b7-bd21-82b0f93bec32" } } } ``` Download the output when status is `success`: ```http theme={null} GET /2026-07/retail-media/reports/{reportId}/output Authorization: Bearer {token} ``` ```json theme={null} { "columns": ["date", "lineItemId", "lineItemName", "missedTraffic", "missedSpend", "capoutHour"], "data": [ ["2026-05-01", "301234567890123457", "Spring Sale - Kitchen Search - Broad", 0.0, 0.0, "No cap-out"], ["2026-05-02", "301234567890123457", "Spring Sale - Kitchen Search - Broad", 0.148558, 2676.70, "20:00"], ["2026-05-03", "301234567890123457", "Spring Sale - Kitchen Search - Broad", 0.155921, 2813.52, "20:00"], ["2026-05-04", "301234567890123457", "Spring Sale - Kitchen Search - Broad", 0.099693, 1686.55, "21:00"], ["2026-05-05", "301234567890123457", "Spring Sale - Kitchen Search - Broad", 0.01672, 251.76, "23:00"], ["2026-05-06", "301234567890123457", "Spring Sale - Kitchen Search - Broad", 0.001905, 29.17, "23:00"], ["2026-05-07", "301234567890123457", "Spring Sale - Kitchen Search - Broad", 0.014384, 222.97, "23:00"] ], "rows": 7 } ``` Each row in the report output represents one day (or one combination of dimensions, if dimensions were specified). *** ## Response Codes For the full list of status and error codes for this endpoint — including `404` (report not found) and `410` (report expired) — see [Response Codes](/retail-media/docs/demand-side-analytics-overview#response-codes) in the Overview. *** ## Metrics Select metrics using the `metrics[]` array in your request. `metrics` is required. | Metric | Description | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `capoutHour` | Hour of the day when the line item exhausted its daily budget, on average, formatted as `HH:00` (e.g. `14:00` means budget was exhausted around 2pm on average). Returns the string `"No cap-out"` — not `null` or a numeric hour — for a day where the line item didn't cap out. | | `missedClicks` | Estimated clicks lost due to reduced auction participation. | | `missedImpressions` | Estimated impressions lost due to reduced auction participation. | | `missedSales` | Estimated revenue lost due to reduced auction participation, in the account's reporting currency. | | `missedSpend` | Estimated spend that would have occurred had the line item participated in all eligible auctions. | | `missedTraffic` | Percentage of the day's total eligible traffic the line item did not participate in. | | `daypartingScheduled` | Binary: whether dayparting was active at the time of the cap-out event. | | `totalSpend` | Total media spend for the line item. | | `roas` | Return on ad spend — revenue per unit of currency spent. | | `attributedSales` | Sales revenue attributed to the campaign per attribution settings. | | `impressions` | Impressions served. | | `clicks` | Clicks counted. | | `cpc` | Average cost per click. | | `cpm` | Average cost per 1,000 impressions. | | `ctr` | Click-through rate: clicks / impressions. | All "missed" estimates are modeled — they represent what the line item would have delivered had it participated in all eligible auctions. *** ## Dimensions Select grouping dimensions using the `dimensions[]` array in your request. `dimensions` is required. | Dimension | Description | | -------------- | ----------------------------------------- | | `date` | Date events occurred. | | `accountId` | Account ID. | | `accountName` | Account name. | | `campaignId` | Campaign ID. | | `campaignName` | Campaign name. | | `lineItemId` | Line item ID. | | `lineItemName` | Line item name. | | `retailerId` | Retailer ID where the line item served. | | `retailerName` | Retailer name where the line item served. | | `buyType` | Buy type of the line item. | | `bidStrategy` | Bid strategy of the line item. | *** ## Data Retention This endpoint supports a lookback window of up to **3 years** (36 months). A request with a `startDate` older than that returns `400 Bad Request` — `StartDate cannot be older than 3 years.` Separately, a single report may span at most **100 days** between `startDate` and `endDate`, regardless of whether you scope by account, campaign, or line item. *** ## Migrating from `reportType: capout` Replace your existing call on `/reports/campaigns` or `/reports/line-items` with a call to this endpoint. The underlying data is unchanged. **Endpoint change:** ``` POST /reports/campaigns → POST /reports/missed-opportunities POST /reports/line-items → POST /reports/missed-opportunities ``` **Request shape changes:** * Replace the top-level `accountId` / `campaignId` / `lineItemId` fields with a `filters` object containing `accountIds[]`, `campaignIds[]`, or `lineItemIds[]` arrays. * Add required `dimensions[]` and `metrics[]` arrays to select output columns. * `startDate` and `endDate` are now required (date-only `YYYY-MM-DD`; timestamps are rejected). * Remove `reportType: capout` — it is not accepted on this endpoint. **Metric renames:** | Old name | New name | | ------------------------- | -------------------------- | | `capoutMissedClicks` | `missedClicks` | | `capoutMissedImpressions` | `missedImpressions` | | `capoutMissedSales` | `missedSales` | | `capoutMissedSpend` | `missedSpend` | | `capoutMissedTraffic` | `missedTraffic` | | `capoutHour` | `capoutHour` *(unchanged)* | **Dimension changes:** `daypartingScheduled` has moved from a dimension to a metric in this endpoint. Add it to your `metrics[]` array instead of `dimensions[]`. # Onsite Sponsored Products Source: https://developers.criteo.com/retail-media/docs/onsite-sponsored-products ## Line Items Each campaign consists of one or several line items. With the Criteo Retail Media API, you can run an ad only after creating a campaign and, at least, one line item. 659142a lineitem1 A line item is where you will select the products and the retailer you want to advertise. Each line item can consist of multiple featured products but can only run across one retailer. You will need to create multiple line items to run across multiple retailers. Several line item settings also help you spend your budget wisely and optimize delivery. To see all of your existing line items, please refer to [Line Items](/retail-media/docs/line-items) **Things to Know** * A line item holds promoted products to advertise on any single retailer. * Line items have bid settings, start & end dates, and optional budgeting & pacing controls. * Budgets may additionally be controlled at the campaign level. * Several reports are available to measure line item performance. * Campaigns are limited to 10,000 non-archived line items. * Line items are archived automatically 90 days after their end date. *** ## Keywords Criteo API provides the capability to control search placements based on keywords that shoppers may use on a search page. Using a single API call, you can specify which keywords to target or avoid, and optimize your line item by setting bids on the most relevant keywords. ### Negative Keyword Targeting This endpoint and its capabilities apply **ONLY** to Onsite Sponsored Products Campaigns & Line Items.\ Negative keyword targeting allows you to specify keywords on which you do not want your ads to appear (applies to search inventory). Negative keyword targeting helps determine where a line item should or should not serve, based on product keywords that shoppers use in searches or purchases. Negative keywords can be specified as either **Broad Match** or **Exact Match**.

Match Type

Negative keyword

Ads won't show for

Ads may show for

Broad match

Men's shoes

Men shoes, Blue men’s shoes, Men's shoe size 9

Shoes, Boy’s shoes, Men’s basketball shoes

Exact match

Men’s shoes

Men’s shoes, Mens shoes, Mens shoe

Shoes, Blue men’s shoes, Mens shoe size 9

**Exact match** blocks ads from serving for specific keywords, while broad match blocks ads for a range of similar terms. **Broad match** is considered a subset of exact match, meaning keywords set as broad will be treated as both broad and exact matches. ### Submitted Keywords Submitted (or Positive) keyword targeting enables targeting based on a pool of search phrases that closely match what shoppers type. The API allows you to specify these phrases using the `PositiveExactMatch` match type, comparing the shopper's search term with your specified keywords for an exact match. [Submitted Keywords](https://help.retailmedia.criteo.com/kb/guide/en/submitted-keywords-pWrW3V33fn/Steps/1632115) will always be **Exact Match**.

Submitted keyword match type

Positive keyword

Ads will show for

Ads won’t show for

Exact match

Women's shoes

Women's shoes, Womens shoes, Womens shoe

Shoes, Blue women’s shoes, Womens shoe size 9

#### Keyword Normalization Involves: * Removing stop words (e.g., "a," "the," "at"). * [Stemming ](https://help.retailmedia.criteo.com/kb/guide/en/keyword-bidding-oBNia2gtXt/Steps/2150023,2150048,2150049) remaining words by trimming prefixes and suffixes ("runner" => "run"). * Sorting remaining words alphabetically. You can also prune phrases using `NegativeExactMatch` and `NegativeBroadMatch` to remove unwanted matches. * **Negative exact match**: Removes phrases that match the normalized keyword exactly. * **Negative broad match**: Removes phrases that match any part of a normalized keyword. The remaining positive phrases are sent to delivery for bid qualification on search pages, while delivery does not use negative keywords. #### Submitted Keyword Approval Workflow When you submit a positive keyword, it enters a pending state. Criteo’s validation system will automatically review and approve or reject the keyword: * If the keyword is already mapped in the automated keyword model, it is approved. * If the keyword contains a competitor's brand name, it is rejected and deactivated. * If the keyword cannot be validated automatically, a Criteo reviewer will manually assess its eligibility. KWS.png ### Keyword Bidding * Keyword bidding offers more granular control over your ad spend by allowing specific bids on keywords. * The bid must respect the minimum CPC bid of the line item. If the line item has a maximum CPC bid set, this will always be enforced, even if a keyword bid exceeds it. **Outcomes Based on Keyword Status:** * **Approved:** Keyword bids take effect immediately. * **In Review:**: Bids are not effective until the keyword is approved. * **Rejected:** Bids have no effect. **Additional Resources** To learn more about Criteo keyword services, explore these articles: * [Criteo Keyword Model](/retail-media/v2024.10/docs/positive-keyword-targeting) * [Keyword Bidding](https://help.retailmedia.criteo.com/kb/guide/en/keyword-bidding-oBNia2gtXt/Steps/2150023,2150048) * [Submitted Keyword](https://help.retailmedia.criteo.com/kb/guide/en/submitted-keywords-pWrW3V33fn/Steps/1632115) * [Negative Keyword](https://help.retailmedia.criteo.com/kb/guide/en/negative-keyword-targeting-zgMmEUbU8V/Steps/1208564) ***
## What's next * [Onsite Sponsored Products Line Items](/retail-media/docs/onsite-sponsored-products-line-items) # Onsite Sponsored Products Line Items Source: https://developers.criteo.com/retail-media/docs/onsite-sponsored-products-line-items **Get Started** Learn more about how open auction line items work with our API in [Onsite Sponsored Products](/retail-media/docs/onsite-sponsored-products). *** ## Endpoints

Method

Endpoint

Description

GET

/campaigns/\{campaignId}/auction-line-items

Get all auction line items from a specific campaign

POST

/campaigns/\{campaignId}/auction-line-items

Create a new auction line item

GET

/auction-line-items/\{lineItemId}

Get a specific auction line item

PUT

/auction-line-items/\{lineItemId}

Update a specific auction line item

**Field Definitions** * `Create` operations using the `POST` method expect every **Required** field; omitting **Optional** fields will set those fields to **Default** values. * `Update` operations using the `PUT` method expect every **Writeable** field; omitting these fields is equivalent to setting them to `null`, if possible. *** ## Line Item Attributes

Attribute

Data Type

Description

id

string

Auction line item ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

name \*

string

Line item name, must be unique within the Campaign

Accepted values: between 2 and 255-chars string

Writeable? Y / Nullable? N

campaignId \*

string

Campaign ID, in which the respective line item belongs and generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

targetRetailerId \*

string

Retailer ID where the line item will serve ads on. For retailer-budgets campaigns, must match the campaign's retailerId . Only one retailer is allowed per retailer-billed campaign.

Accepted values: string of int64

Writeable? N / Nullable? N

startDate \*

date

Start date of the line item, used to schedule its activation and start serving ads. To understand the conditions that will cause a status to change, check out Campaign & Line Item Status

ℹ️ This now supports datetime offset to define the desired time zone, in the format of ±hh:mm . If omitted in create/update operations, UTC will be considered the default time zone. Values are returned in UTC in responses; dates are normalized to account timezone internally.

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm or yyyy-mm-dd (in ISO-8601)

Writeable? Y / Nullable? N

endDate

date

End date of the line item; serves ads indefinitely if omitted or set to null . To understand the conditions that will cause a status to change, check out Campaign & Line Item Status

ℹ️ This now supports datetime offset to define the desired time zone, in the format of ±hh:mm . If omitted in create/update operations, UTC will be considered the default time zone. Values are returned in UTC in responses; dates are normalized to account timezone internally.

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm or yyyy-mm-dd (in ISO-8601 )

Default: if null or absent, line item will serve ads indefinitely

Writeable? Y / Nullable? Y

budget

decimal

Lifetime spend cap of line item (optional), uncapped if omitted or set to null

Accepted values: budget ≥ 0.0

Default: null

Writeable? Y / Nullable? Y

budgetSpent

decimal

Budget amount the line item has already spent

Accepted values: budgetSpent ≥ 0.0

Default: 0.0

Writeable? N / Nullable? N

budgetRemaining

decimal

Amount the line item has remaining until cap is hit; null if budget is uncapped

Accepted values: 0 ≤ budgetRemaining budget

Default: 0.0

Writeable? N / Nullable? Y

monthlyPacing

decimal

Amount the line item can spend per calendar month (optional), in the Account time zone. Omitting or setting to null leaves the monthly spend uncapped.

Accepted values: monthlyPacing ≥ 0.0 (or null )

Default: 0.0

Writeable? Y / Nullable? Y

dailyPacing

decimal

Amount the line item can spend per calendar day (optional), in the Account time zone. It resets each day; overwritten by calculation if isAutoDailyPacing is enabled; uncapped if omitted or set to null

Accepted values: dailyPacing ≥ 0.0 (or null )

Default: 0.0

Writeable? Y / Nullable? Y

isAutoDailyPacing

boolean

To activate, either line item endDate and budget, or monthlyPace , must be specified; overwrites dailyPacing with calculation if not set prior

Accepted values: true , false

Default: false

Writeable? Y / Nullable? N

bidStrategy

enum

Indicate whether Adaptive CPC is enabled or not automated will trigger a validation against the maxBid to ensure that it is present. manual will trigger a validation against the targetBid to ensure that a bid for the line item have been input.

Accepted values: automated , manual

Default: manual

Writeable? Y / Nullable? N

optimizationStrategy

enum

Bid algorithm optimizing for sales conversions, sales revenue or clicks

Accepted values: conversion , revenue , clicks

Default: conversion

Writeable? Y / Nullable? N

targetBid

bidStrategy decimal

If optimizing for conversion or revenue , a target average amount to bid (as each bid is modulated up/down by our optimization algorithm); else bids stay constant, if optimizing for clicks Bidding is uncapped if omitted or set to null

ℹ️ Note:

  • Must meet minBid for line item to deliver ads, which depends on selected products (available through the Catalog)
  • Input excludes platform fees

Accepted values: at least the greatest value of minBid across all products in the line item

Default: 0.3

Writeable? Y / Nullable? Y

maxBid

decimal

If optimizing for conversion or revenue , the maximum amount allowed to bid for each display (respected regardless of targetBid ). Does not apply if optimizing for clicks Bidding is uncapped if omitted or set to null

ℹ️ Note:

  • Must meet minBid for line item to deliver ads, which depends on selected products (available through the Catalog)
  • Input excludes platform fees

Accepted values: at least 0.1

⚠️ Note: As of 2026-01, maxBid is required when bidStrategy: automated. When set to null, the API returns 0 in responses, but the system treats it internally as uncapped (no bid ceiling).

Writeable? Y / Nullable? Y

status

enum

Line item status; can only be updated by a user to active or paused ; all other values are applied automatically depending on financials, flight dates, or missing attributes required for line item to serve. To understand the conditions that will cause a status to change, check out Campaign & Line Item Status

Accepted values: active , paused , scheduled , ended , budgetHit , noFunds , draft , archived

Writeable? Y / Nullable? N

flightSchedule

object

Settings allowing custom scheduling for serving ads serving, organized by a combination of legs . In case of null or empty legs , the line item status will remain unchanged along the weekdays and hours, as long as other delivery parameters are respected - see Campaign & Line Item Status

Accepted values: see below

Writeable? Y / Nullable? Y

keywordStrategy

enum

Keyword strategy used to target users according to the promoted products appended in the line item and their competitors

ℹ️ Note: "*Conquesting*" is not available for all retailers; when creating a new line item for those retailers, a validation error will return which can be avoided by omitting this attribute from the request

Accepted values:

  • genericAndBranded : enables users who submit general keywords and also keywords related to the brand(s) to target the promoted products associated with the line item (default behavior)
  • conquesting : enables users who submit keywords identified as competitor(s) from the brand(s) related to the promoted products associated with the line item (manual review required)
  • genericBrandedAndConquesting : enables users who submit keywords related to both brand(s) and competitor(s) from the promoted products of line item (manual review required)

Default: genericAndBranded

Writeable? Y / Nullable? N

createdAt

timestamp

Timestamp of line item creation, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601)

Writeable? N / Nullable? N

updatedAt

timestamp

Timestamp of last line item update, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601)

Default: same as createdAt

Writeable? N / Nullable? N

(\*) *Required for create operations* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Flight Schedule Legs Attributes

Attribute

Data Type

Description

dayOfWeek

enum

Day of the week or day type that the respective leg should be effective, i.e., the respective line item should be activated (in case all other conditions are satisfied)

Accepted values: sunday , monday , tuesday , wednesday , thursday , friday , saturday , everyday , weekdays , weekends

Writeable? Y / Nullable? N

startTime

time

Start time that the respective leg should be effective, i.e., the respective line item should be activated (in case all other conditions are satisfied)

ℹ️ This time value will be interpreted considering the time zone provided in the startDate / endDate above

Accepted values: hh:mm , with values between 00:00 and 23:59

Writeable? Y / Nullable? N

endTime

time

End time that the respective leg should be effective, i.e., the respective line item should be deactivated (in case all other conditions are satisfied)

ℹ️ This time value will be interpreted considering the time zone provided in the startDate / endDate above

Accepted values: hh:mm , with values between 00:00 and 23:59

Writeable? Y / Nullable? N

*** ## Get all Onsite Sponsored Products Line Items This endpoint lists all Onsite Sponsored Products line items in the specified campaign. This endpoint now returns `null` in the `budgetRemaining` field for line items with uncapped budgets and line items with missing budgets. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `500`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). ```http theme={null} https://api.criteo.com/{version}/retail-media/campaigns/{campaignId}/auction-line-items ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/campaigns/544937665113018368/auction-line-items?offset=0&limit=500" \ -H "Authorization: Bearer " \ -H "Accept: application/json" ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") headers = { 'Authorization': 'Bearer ', 'Accept': 'application/json' } conn.request("GET", "/{version}/retail-media/campaigns/544937665113018368/auction-line-items?offset=0&limit=500", headers=headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/campaigns/544937665113018368/auction-line-items?offset=0&limit=500") .method("GET", null) .addHeader("Authorization", "Bearer ") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/campaigns/544937665113018368/auction-line-items?offset=0&limit=500'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig([ 'follow_redirects' => TRUE ]); $request->setHeader([ 'Authorization' => 'Bearer ', 'Accept' => 'application/json' ]); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "data": [ { "id": "9979917896105882144", "type": "SponsoredProductsLineItem", "attributes": { "name": "Line Item 123 Always On", "campaignId": "544937665113018368", "targetRetailerId": "12345", "startDate": "2024-09-01T04:00:00+00:00", "endDate": null, "status": "active", "budget": 5000.00, "budgetSpent": 2354.38, "budgetRemaining": 2645.62, "maxBid": 2.50, "targetBid": null, "monthlyPacing": null, "dailyPacing": null, "isAutoDailyPacing": false, "bidStrategy": "automated", "optimizationStrategy": "conversion", "flightSchedule": null, "keywordStrategy": "genericBrandedAndConquesting", "createdAt": "2024-08-24T15:46:45.1578781+00:00", "updatedAt": "2025-08-12T08:02:36.9158515+00:00" } }, // ... { "id": "6854840188706902009", "type": "SponsoredProductsLineItem", "attributes": { "name": "Line Item 456 - Weekends Only", "campaignId": "544937665113018368", "targetRetailerId": "6789", "startDate": "2025-08-09T04:00:00+00:00", "endDate": "2026-01-01T03:59:59+00:00", "status": "draft", "budget": 12000.00, "budgetSpent": 0.00, "budgetRemaining": 12000.00, "maxBid": 5.0, "targetBid": null, "monthlyPacing": null, "dailyPacing": null, "bidStrategy": "automated", "optimizationStrategy": "conversion", "isAutoDailyPacing": false, "flightSchedule": { "legs": [ { "dayOfWeek": "Weekends", "startTime": "00:00", "endTime": "23:59" } ] }, "keywordStrategy": "genericAndBranded", "createdAt": "2025-07-24T15:46:45.7793506-04:00", "updatedAt": "2025-08-12T08:02:36.9158515-04:00" } }, ], "metadata": { "count": 35, "offset": 0, "limit": 25 }, "warnings": [], "errors": [] } ``` **Sample response with uncapped or missing budget** ```json theme={null} { "data": [ { "attributes": { "name": "Oscar Mayer Bacon - Giant Eagle", "startDate": "2026-01-01", "endDate": null, "maxBid": null, "budget": null, "monthlyPacing": 744, "dailyPacing": 24.88888889, "bidStrategy": "automated", "targetRetailerId": "1084", "status": "active", "targetBid": 0.6, "isAutoDailyPacing": true, "campaignId": "789229599621738496", "budgetSpent": 1576.8, "budgetRemaining": null, "createdAt": "2025-12-17T20:37:31+00:00", "updatedAt": "2026-03-05T11:01:11+00:00", "id": "789229817782235136" }, "id": "789229817782235136", "type": "RetailMediaAuctionLineItem" } ] } ``` *** ## Create an Onsite Sponsored Products Line Item This endpoint creates a new Onsite Sponsored Products line item in the specified campaign. **Retailer Budgets Campaigns** For retailer-budget campaigns, `targetRetailerId` must match the campaign's `retailerId`. Mismatched values will return a `RetailerMismatchWithCampaign` error. Learn more about Retailer Budgets [here](/retail-media/docs/retailer-budgets). **Note:** `bidStrategy: "automated"` requires `maxBid` to be set. ```http theme={null} https://api.criteo.com/{version}/retail-media/campaigns/{campaignId}/auction-line-items ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST '{version}/retail-media/campaigns/{campaignId}/auction-line-items' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "SponsoredProductsLineItem", "attributes": { "name": "My Retailer Budget Line Item", "targetRetailerId": "123", "startDate": "2026-06-01T00:00:00+00:00", "bidStrategy": "automated", "maxBid": 5.0, "optimizationStrategy": "conversion", "keywordStrategy": "genericAndBranded" } } }' ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "100000000000000001", "type": "SponsoredProductsLineItem", "attributes": { "name": "My Retailer Budget Line Item", "startDate": "2026-06-01T00:00:00+00:00", "endDate": null, "status": "draft", "targetBid": null, "targetRetailerId": "123", "budget": null, "campaignId": "100000000000000001", "budgetSpent": 0.0, "budgetRemaining": null, "createdAt": "2026-05-29T20:33:29+00:00", "updatedAt": "2026-05-29T20:33:29+00:00", "maxBid": 5.0, "monthlyPacing": null, "dailyPacing": null, "optimizationStrategy": "conversion", "isAutoDailyPacing": false, "flightSchedule": null, "keywordStrategy": "genericAndBranded", "bidStrategy": "automated" } }, "warnings": [], "errors": [] } ``` *** ## Get a Specific Onsite Sponsored Products Line Item This endpoint returns the specified Onsite Sponsored Products line item. * This endpoint returns `null` in the `budgetRemaining` field for line items with uncapped budgets and line items with missing budgets. * `targetRetailerId` is returned in the attributes for retailer budget line items. ```http theme={null} https://api.criteo.com/{version}/retail-media/auction-line-items/{lineItemId} ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/auction-line-items/6854840188706902009" \ -H "Authorization: Bearer " \ -H "Accept: application/json" ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") headers = { 'Authorization': 'Bearer ', 'Accept': 'application/json' } conn.request("GET", "/preview/retail-media/auction-line-items/6854840188706902009", headers=headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://api.criteo.com/preview/retail-media/auction-line-items/6854840188706902009") .method("GET", null) .addHeader("Authorization", "Bearer ") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/preview/retail-media/auction-line-items/6854840188706902009'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig([ 'follow_redirects' => TRUE ]); $request->setHeader([ 'Authorization' => 'Bearer ', 'Accept' => 'application/json' ]); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "100000000000000001", "type": "SponsoredProductsLineItem", "attributes": { "name": "My Retailer Budget Line Item", "startDate": "2026-06-01T00:00:00+00:00", "endDate": null, "status": "draft", "targetBid": null, "targetRetailerId": "123", "budget": null, "campaignId": "100000000000000001", "budgetSpent": 0.0, "budgetRemaining": null, "createdAt": "2026-05-29T20:33:29+00:00", "updatedAt": "2026-05-29T20:33:29+00:00", "maxBid": 5.0, "monthlyPacing": null, "dailyPacing": null, "optimizationStrategy": "conversion", "isAutoDailyPacing": false, "flightSchedule": null, "keywordStrategy": "genericAndBranded", "bidStrategy": "automated" } }, "warnings": [], "errors": [] } ``` *** **Sample request with uncapped or missing budget** ```json theme={null} { "data": { "attributes": { "name": "Bagel Bites - Giant Eagle", "startDate": "2026-01-01", "endDate": null, "maxBid": null, "budget": null, "monthlyPacing": 230, "dailyPacing": 5.10567297, "bidStrategy": "revenue", "targetRetailerId": "1084", "status": "active", "targetBid": 0.7, "isAutoDailyPacing": true, "campaignId": "789229599621738496", "budgetSpent": 820.72682981, "budgetRemaining": null, "createdAt": "2025-12-17T21:05:51+00:00", "updatedAt": "2026-03-05T11:01:11+00:00", "id": "789236949010575360" }, "id": "789236949010575360", "type": "RetailMediaAuctionLineItem" }, "warnings": [], "errors": [] } ``` *** ## Update a Specific Onsite Sponsored Products Line Item This endpoint updates the specified Onsite Sponsored Products line item. In this example, we are: * renaming the line item and start date, to be scheduled to deliver during Q4. * enabling auto daily pacing by setting a monthly pace simultaneously. Note that with auto daily pacing enabled, daily pacing is automatically calculated and overwrites its previous value, if any. * modifying the day scheduling to deliver ads during extended weekend evenings only, i.e., Fridays, Saturdays and Sundays from 18h until 0h (local time) Also, note the draft state of the line item because products to be promoted have not yet been added. ```http theme={null} https://api.criteo.com/{version}/retail-media/auction-line-items/{lineItemId} ``` **Sample Request** ```bash cURL expandable theme={null} curl -L -X PUT "https://api.criteo.com/{version}/retail-media/auction-line-items/6854840188706902009" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "data": { "id": "6854840188706902009", "type": "SponsoredProductsLineItem", "attributes": { "name": "Line Item 456 - Q4 Weekends Evenings", "campaignId": "544937665113018368", "targetRetailerId": "6789", "startDate": "2025-10-01T00:00:00-04:00", "endDate": "2025-12-31T23:59:59-04:00", "status": "active", "budget": 12000.00, "maxBid": 5.0, "targetBid": 1.0, "monthlyPacing": 4000.00, "isAutoDailyPacing": true, "flightSchedule": { "legs": [ { "dayOfWeek": "friday", "startTime": "18:00", "endTime": "23:59" }, { "dayOfWeek": "weekends", "startTime": "18:00", "endTime": "23:59" } ] } } } }' ``` ```python Python expandable theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": { "id": "6854840188706902009", "type": "SponsoredProductsLineItem", "attributes": { "name": "Line Item 456 - Q4 Weekends Evenings", "campaignId": "8343086999167541140", "targetRetailerId": "6789", "startDate": "2025-10-01T00:00:00-04:00", "endDate": "2025-12-31T23:59:59-04:00", "status": "active", "budget": 12000.00, "maxBid": 5.0, "targetBid": 1.0, "monthlyPacing": 4000.00, "isAutoDailyPacing": True, "flightSchedule": { "legs": [ { "dayOfWeek": "friday", "startTime": "18:00", "endTime": "23:59" }, { "dayOfWeek": "weekends", "startTime": "18:00", "endTime": "23:59" } ] } } } }) headers = { 'Authorization': 'Bearer ', 'Content-Type': 'application/json', 'Accept': 'application/json' } conn.request("PUT", "/preview/retail-media/auction-line-items/6854840188706902009", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java expandable theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, """ { "data": { "id": "6854840188706902009", "type": "SponsoredProductsLineItem", "attributes": { "name": "Line Item 456 - Q4 Weekends Evenings", "campaignId": "8343086999167541140", "targetRetailerId": "6789", "startDate": "2025-10-01T00:00:00-04:00", "endDate": "2025-12-31T23:59:59-04:00", "status": "active", "budget": 12000.00, "maxBid": 5.0, "targetBid": 1.0, "monthlyPacing": 4000.00, "isAutoDailyPacing": true, "flightSchedule": { "legs": [ { "dayOfWeek": "friday", "startTime": "18:00", "endTime": "23:59" }, { "dayOfWeek": "weekends", "startTime": "18:00", "endTime": "23:59" } ] } } } } """); Request request = new Request.Builder() .url("https://api.criteo.com/preview/retail-media/auction-line-items/6854840188706902009") .method("PUT", body) .addHeader("Authorization", "Bearer ") .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/preview/retail-media/auction-line-items/6854840188706902009'); $request->setMethod(HTTP_Request2::METHOD_PUT); $request->setConfig([ 'follow_redirects' => TRUE ]); $request->setHeader([ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', 'Accept' => 'application/json' ]); $request->setBody(json_encode([ "data" => [ "id" => "6854840188706902009", "type" => "SponsoredProductsLineItem", "attributes" => [ "name" => "Line Item 456 - Q4 Weekends Evenings", "campaignId" => "8343086999167541140", "targetRetailerId" => "6789", "startDate" => "2025-10-01T00:00:00-04:00", "endDate" => "2025-12-31T23:59:59-04:00", "status" => "active", "budget" => 12000.00, "maxBid" => 5.0, "targetBid" => 1.0, "monthlyPacing" => 4000.00, "isAutoDailyPacing" => true, "flightSchedule" => [ "legs" => [ [ "dayOfWeek" => "friday", "startTime" => "18:00", "endTime" => "23:59" ], [ "dayOfWeek" => "weekends", "startTime" => "18:00", "endTime" => "23:59" ] ] ] ] ] ], JSON_PRETTY_PRINT)); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "data": { "id": "6854840188706902009", "type": "SponsoredProductsLineItem", "attributes": { "name": "Line Item 456 - Q4 Weekends Evenings", "campaignId": "544937665113018368", "targetRetailerId": "6789", "startDate": "2025-10-01T04:00:00+00:00", "endDate": "2026-01-01T03:59:59+00:00", "status": "draft", "budget": 12000.00, "budgetSpent": 0.00, "budgetRemaining": 12000.00, "maxBid": 5.0, "targetBid": 1.00000000, "monthlyPacing": 4000.00, "dailyPacing": 200.00, "bidStrategy": "manual", "optimizationStrategy": "conversion", "isAutoDailyPacing": true, "flightSchedule": { "legs": [ { "dayOfWeek": "friday", "startTime": "18:00", "endTime": "23:59" }, { "dayOfWeek": "weekends", "startTime": "18:00", "endTime": "23:59" } ] }, "keywordStrategy": "genericAndBranded", "createdAt": "2024-09-24T15:47:03.228224+00:00", "updatedAt": "2025-08-12T09:34:07.6168328+00:00" } }, "warnings": [], "errors": [] } ``` *** ## Responses

Response

Title

Description

🔵 200

Call completed with success

🔵 201

Line item created with success

🔴 400

Invalid isAutoDailyPacing

Cannot turn on IsAutoDailyPacing and add a dailyPacing value. Only one of the two options can be used.

🔴 400

Conquesting not enabled

Conquesting is not enabled for the specified retailer. Remove the keywordStrategy property from the creation request.

🔴 400

RetailerMismatchWithCampaign * Invalid Target Retailer

targetRetailerId on the line item doesn't match the parent campaign's retailerId . The detail field names both IDs: "Line item's targetRetailerId does not match the retailer-billed campaign's retailer ID ". Ensure targetRetailerId on the line item matches the retailerId set on the parent campaign.

# Partner Billing Report Source: https://developers.criteo.com/retail-media/docs/partner-billing-report ## Introduction The Partner Billing Report (PBR) enables retailers to generate a billing report automatically through the API with custom date ranges and should contain data applicable for the specified retailer identified through the supply account. *** ## Endpoints The report generation uses an asynchronous endpoint that is used to receive the report creation request (using a POST request); then, using the `reportId` generated, it's possible to check the report status and download the output results using the following GET endpoint requests.

Verb

Endpoint

Description

POST

/billing/partner-report

Request a partner billing report creation

GET

/billing/partner-report/\{reportId}/status

Get status of a specific report

GET

/billing/partner-report/\{reportId}/output

Download output of a specific report

*** ## Report Request Attributes

Attribute

Data Type

Description

accountIds

list

Account IDs (currently supports only Supply Account IDs)

Accepted values: array of strings/int64

Writeable? N / Nullable? N

retailerIds

list

Retailer IDs

Accepted values: array of strings/int64

Writeable? N / Nullable? N

startDate \*

date

Start date of the report (inclusive)

Accepted values: yyyy-mm-dd

Writeable? N / Nullable? N

endDate \*

date

End date of the report (inclusive)

Accepted values: yyyy-mm-dd

Writeable? N / Nullable? N

format

enum

The format type the report should return results

Accepted values: json , csv

Default: json

Writeable? N / Nullable? N

*\* Required* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. **Reporting Asynchronous Workflow: Step 1/3** * First, create a request for Partner Billing Report with the desired attributes * This generates a `reportId` representing the report *** ## Create a Partner Billing Report Request This endpoint receives requests to create Partner Billing Reports and returns a report `id` (to be used in the next steps) in case the request was successfully created; otherwise, it will expose errors details about the request issues ```http theme={null} https://api.criteo.com/{version}/retail-media/billing/partner-report ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/billing/partner-report' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "PartnerBillingReportRequest", "attributes": { "accountIds": [ "4257354123567401216" ], "retailerIds": [ "1234", "5678" ], "startDate": "2025-01-01", "endDate": "2025-01-31", "format": "json" } } }' ``` ```python Python expandable theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/billing/partner-report" payload = json.dumps({ "data": { "type": "", "attributes": { "accountIds": [ "4257354123567401216" ], "retailerIds": [ "1234", "5678" ], "startDate": "2025-01-01", "endDate": "2025-01-31", "format": "json" } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"type\":\"\",\"attributes\":{\"accountIds\":[\"4257354123567401216\"],\"retailerIds\":[\"1234\",\"5678\"],\"startDate\":\"2025-01-01\",\"endDate\":\"2025-01-31\",\"format\":\"json\"}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/billing/partner-report") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/billing/partner-report'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"type":"","attributes":{"accountIds":["4257354123567401216"],"retailerIds":["1234","5678"],"startDate":"2025-01-01","endDate":"2025-01-31","format":"json"}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response**: Report request successfully created (response status 🟢 `200`) ```json theme={null} { "data": { "id": "c19ed799-6747-4815-aa09-d3e04898xxxx", "type": "PartnerBillingReportStatusV1", "attributes": { "status": "success", "errorMessage": null, "createdAt": "2025-03-27T14:43:28.3788206+00:00" } }, "warnings": [], "errors": [] } ``` **Reporting Asynchronous Workflow: Step 2/3** * Next, use the `reportId` to pull the report status endpoint until one is successfully computed **Sample Response**: Validation error when creating report request (response status 🔴 `400`) ```json theme={null} { "warnings": [], "errors": [ { "traceId": "c19ed799-6747-4815-aa09-d3e04898xxxx", "type": "validation", "code": "model-validation-error", "title": "Model validation error", "detail": "data.attributes.endDate value is invalid" } ] } ``` *** ## Get Status of Specific Report This endpoint retrieves the status of a specific report creation. Status can be `pending`, `success`, `failure`, or `expired` ```http theme={null} https://api.criteo.com/{version}/retail-media/billing/partner-report/{reportId}/status ``` **Sample Request** ```bash theme={null} curl -L -X GET 'https://api.criteo.com/{version}/retail-media/billing/partner-report/c19ed799-6747-4815-aa09-d3e04898xxxx/status' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json theme={null} { "data": { "id": "c19ed799-6747-4815-aa09-d3e04898xxxx", "type": "PartnerBillingReportStatusV1", "attributes": { "status": "pending", "errorMessage": null, "createdAt": "2025-03-27T14:43:28.3788206+00:00" } }, "warnings": [], "errors": [] } ``` **Reporting Asynchronous Workflow: Step 3/3** * Finally, download the report using the report output endpoint * Report outputs are cached for at least 1 hour before expiration *** ## Download Output of Specific Report Once the report creation is completed (`"status": "success"` in response above), the report output will be available to download in this endpoint. The metrics definition of the Partner Billing Report is available in [PBR Metrics](/retail-media/docs/pbr-metrics) ```http theme={null} https://api.criteo.com/{version}/retail-media/billing/partner-report/{reportId}/output ``` **Sample Request** ```bash theme={null} curl -L -X GET "https://api.criteo.com/{version}/retail-media/reports/2e733b8c-9983-4237-aab9-17a4xxxxxx/output" \ -H 'Accept: application/json' \ -H "Authorization: Bearer " ``` **Sample Responses** ```json expandable theme={null} [ { "AccountName": "Brand A US", "AccountExternalId": "525404033764731234", "IsUnbillable": "No", "AccountCategory": "Network Demand", "RetailerName": "My Retailer Shop", "AccountService": null, "AccountCurrencyCode": "USD", "ExternalBalanceId": "525746374845021111", "BalanceName": null, "PurchaseOrder": null, "BalanceStartDate": null, "PrivateMarketPaymentOption": null, "CampaignExternalId": null, "CampaignName": "Brand A - Campaign Jan2025", "CampaignType": "SponsoredProducts", "BuyType": "Auction", "LineItemId": 530088677885964287, "LineItemName": "Brand A - My Retailer Shop - Jan2025", "WorkingMediaSpend": 100.72000000, "CreditSpend": 0.00000000, "ValueAddSpend": 0.00000000, "Clicks": 394, "Impressions": 0, "SupplyFeeAmount": 20.14400000, "RetailerManagedFeeRate": 0.0, "RetailerManagedFeeAmount": 0.0, "RetailerAudienceDataFeeAmount": null, "CriteoRetailerDataFeeAmount": null, "UtcOffset": "-05:00", "BudgetModel": "Retailer Budget", "SalesEnablementServiceFeeAmount": 0, "SelfServiceEnablementServiceFeeAmount": 0 }, // ... { "AccountName": "Brand B US", "AccountExternalId": "137955447513525678", "IsUnbillable": "No", "AccountCategory": "Network Demand", "RetailerName": "My Retailer Shop", "AccountService": null, "AccountCurrencyCode": "USD", "ExternalBalanceId": "390893529643232222", "BalanceName": null, "PurchaseOrder": null, "BalanceStartDate": null, "PrivateMarketPaymentOption": null, "CampaignExternalId": null, "CampaignName": "Brand B - Auction 2025", "CampaignType": "SponsoredProducts", "BuyType": "Auction", "LineItemId": 592048399992061951, "LineItemName": "Brand B - My Retailer Shop - Jan2025", "WorkingMediaSpend": 1497.28125424, "CreditSpend": 0.00000000, "ValueAddSpend": 0.00000000, "Clicks": 5312, "Impressions": 0, "SupplyFeeAmount": 299.45625082, "RetailerManagedFeeRate": 0.0, "RetailerManagedFeeAmount": 0.0, "RetailerAudienceDataFeeAmount": null, "CriteoRetailerDataFeeAmount": null, "UtcOffset": "-05:00", "BudgetModel": "Criteo Budget", "SalesEnablementServiceFeeAmount": 10.5, "SelfServiceEnablementServiceFeeAmount": 11.5 } ] ``` *** ## Responses

Response

Title

Detail

Troubleshooting

🟢 200

Call executed with success

🟢 201

Report request created with success

🔴 400

Validation error

Invalid date range. Maximum allowed is 31 days.

Review the startDate and endDate provided, ensuring their maximum interval of 31 days

🔴 400

Model Validation error

data.atributes.xxx value is invalid.

Review the value of respective field provided, ensuring it was informed with a valid format

🔴 403

The scope Billing is missing

The scope Billing is required to access this endpoint and is missing from the provided token

The respective API app doesn't have access to the domain/scope Billing. Review the Types of Permissions in Authorization Requests

🔴 403

Authorization error

Resource access forbidden: all the accounts/retailers are not accessible.

Review the Account/Retailer ID(s) provided in the report request

***
## What's next * [PBR Metrics](/retail-media/docs/pbr-metrics) # PBR Metrics Source: https://developers.criteo.com/retail-media/docs/pbr-metrics ## Introduction In this page, you will find the definition and details of all metrics currently supported in the [Partner Billing Report](/retail-media/docs/partner-billing-report). *** ## Metrics

Dimensions

Data Type

Description

AccountName

string

Account name

AccountId

string

Account ID, generated by Criteo

IsUnbillable

string

Flag if report item is billable or not based on the non-billable settings

AccountCategory

string

The category the account falls under, values can be:

  • Supply - Legacy
  • Supply - Private Market
  • Network Demand
  • Private Market Demand - Brand
  • Private Market Demand - Seller

RetailerName

string

Retailer name tied to the account

AccountService

string

Managed service or self-service

⚠️ Note : if the AccountCategory is Network Demand, the value will be null .

BudgetModel

string

The value should reflect either “Retailer” or “Criteo” is doing the billing

AccountCurrencyCode

string

Account currency, in 3-chars code (in ISO-4217 )

Origin

string

Indicates the source of account creation, distinguishing whether the account was created by a third-party partner working with Criteo; if so, the partner’s name is specified, otherwise, null is expected

OriginId

integer

Origin ID, generated by Criteo

BalanceId

string

Balance ID associated with the account, generated by Criteo

BalanceName

string

Balance name

⚠️ Note : if the AccountCategory is Network Demand, the value will be null .

PurchaseOrder

string

Purchase order associated to the Balance

⚠️ Note : if the AccountCategory is Network Demand, the value will be null .

BalanceStartDate

timestamp

Start date of the Balance, in format yyyy-mm-ddThh:mm:ss.sTZD

⚠️ Note : if the AccountCategory is Network Demand, the value will be null .

PrivateMarketPaymentOption

The payment option of the Private Market demand account at the balance level

⚠️ Note : if the AccountCategory is Network Demand, the value will be null .

CampaignId

string

Campaign ID, generated by Criteo

CampaignName

string

Campaign name

CampaignType

string

Campaign type (⚠️ Campaigns eg: SponsoredProducts )

BuyType

string

Campaign buying type (e.g. Auction, Preferred Deals, Sponsorship)

LineItemId

string

Line item ID, generated by Criteo

LineItemName

string

Line item name

WorkingMediaSpend

decimal

Working media spend

CreditSpend

decimal

Credit spend is the amount of credit applied in a given month to restore a working media budget that was originally impacted by bots, technical errors, or human errors.

ValueAddSpend

decimal

Value add spend is the amount of free budget applied in a given month, typically granted to brands or agencies as an incentive to spend above a specific threshold, invest in new retailers, expand into new product categories, or test different formats and audiences.

Clicks

integer

Amount of billable clicks recorded

Impressions

integer

Amount of billable impressions recorded

SupplyFeeAmount

decimal

Retailer's SSP fee amount

RetailerManagedFeeRate

decimal

Managed service fee set at the supply account, which applies to the demand side of the supply account

RetailerManagedFeeAmount

decimal

Retailer's managed service fee amount

RetailerAudienceDataFeeAmount

decimal

Retailer's offsite audience revenue before Criteo's take rate

CriteoRetailerDataFeeAmount

decimal

Criteo's take rate from retailer offsite audience revenue

UtcOffset

string

Timezone offset of the account

SalesEnablementServiceFeeAmount

decimal

Retailer's sales enablement professional service fee amount

SelfServiceEnablementServiceFeeAmount

decimal

Retailer's self-service enablement professional service fee amount

***
# Performance Report Source: https://developers.criteo.com/retail-media/docs/performance-report POST /reports/performance — flexible campaign performance reporting for Retail Media DSP partners. This endpoint enables Retail Media DSP partners to request flexible performance reporting across any level of granularity. Provide a scope filter under `filters` to define the data returned — the output granularity is then determined by the dimensions you include in the request. The endpoint supports asynchronous report generation and provides access to the full set of performance metrics and dimensions, including video, new-to-brand, and keyword data. Submit a request, poll for status, and download the output when ready. *** ## Request ```http theme={null} POST /2026-07/retail-media/reports/performance ``` ### Required fields `filters` (with exactly one scope filter), `startDate`, `endDate`, `metrics`, and `dimensions` are all required. Requests with no scope filter (or more than one) will return `400 Bad Request`. | Field | Type | Description | | ----------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------- | | `filters` | object | Required. Must contain exactly one of the scope filters below. | | `filters.accountIds[]` | array of strings | Scope the report to all campaigns under this account. Mutually exclusive with `campaignIds` and `lineItemIds`. | | `filters.campaignIds[]` | array of strings | Scope the report to all line items under this campaign. Mutually exclusive with `accountIds` and `lineItemIds`. | | `filters.lineItemIds[]` | array of strings | Scope the report to this line item. Mutually exclusive with `accountIds` and `campaignIds`. | | `startDate` | string | Start of the reporting period. ISO 8601 date (`YYYY-MM-DD`). | | `endDate` | string | End of the reporting period. ISO 8601 date (`YYYY-MM-DD`). | | `metrics` | array of strings | One or more metric names. See [Metrics](#metrics) below. | | `dimensions` | array of strings | One or more dimension names. See [Dimensions](#dimensions) below. | ### Optional fields | Field | Type | Default | Description | | -------------------------------- | ---------------- | -------------- | ----------------------------------------------------------------------------------------------- | | `timezone` | string | `UTC` | Timezone for date bucketing. IANA format (e.g. `America/New_York`). | | `format` | string | `json-compact` | Output format: `json`, `json-compact`, `json-newline`, or `csv`. | | `clickAttributionWindow` | string | — | Attribution window for click-based conversions: `none`, `7D`, `14D`, or `30D`. | | `viewAttributionWindow` | string | — | Attribution window for view-based conversions: `none`, `1D`, `7D`, `14D`, or `30D`. | | `clickMatchLevel` | string | — | Match level for click attribution. | | `viewMatchLevel` | string | — | Match level for view attribution. | | `filters.campaignTypes[]` | array of strings | — | Filter by campaign type. Values constrain eligible campaigns and may affect metric eligibility. | | `filters.salesChannels[]` | array of strings | — | Filter by sales channel. | | `filters.mediaTypes[]` | array of strings | — | Filter by media type. | | `filters.buyTypes[]` | array of strings | — | Filter by buy type. | | `filters.budgetModels[]` | array of strings | — | Filter by budget model. | | `filters.activationPlatforms[]` | array of strings | — | Filter by activation platform. | | `filters.searchTermTypes[]` | array of strings | — | Filter by search term type. | | `filters.searchTermTargetings[]` | array of strings | — | Filter by search term targeting strategy. | | `filters.targetedKeywordTypes[]` | array of strings | — | Filter by targeted keyword type. | ### Example request ```http theme={null} POST /2026-07/retail-media/reports/performance Authorization: Bearer {token} Content-Type: application/json { "data": { "type": "AsyncPerformanceReport", "attributes": { "filters": { "campaignIds": ["301234567890123456"] }, "startDate": "2026-05-01", "endDate": "2026-05-07", "timezone": "America/New_York", "metrics": ["impressions", "clicks", "spend", "roas"], "dimensions": ["date", "campaignName", "lineItemName"] } } } ``` *** ## Response A successful request returns `200 OK` with a `reportId`. Use this ID to poll for status and retrieve the output. ```json theme={null} { "data": { "type": "StatusResponse", "id": "c378da57-960e-4ce4-a297-770f9512af56", "attributes": { "status": "pending", "rowCount": 0, "fileSizeBytes": 0, "md5CheckSum": null, "createdAt": "2026-07-28T13:37:17.000Z", "expiresAt": null, "message": null, "id": "c378da57-960e-4ce4-a297-770f9512af56" } } } ``` Once the report finishes processing, the status response is fully populated: ```json theme={null} { "data": { "type": "StatusResponse", "id": "c378da57-960e-4ce4-a297-770f9512af56", "attributes": { "status": "success", "rowCount": 7, "fileSizeBytes": 1125, "md5CheckSum": "cb448a82ac773d48672cdf30c4fae9de", "createdAt": "2026-07-28T13:37:17.000Z", "expiresAt": "2026-08-04T13:37:18.000Z", "message": "rows_count=7", "id": "c378da57-960e-4ce4-a297-770f9512af56" } } } ``` **Poll for status** until `status` is `success` or `failure`: ```http theme={null} GET /2026-07/retail-media/reports/{reportId}/status Authorization: Bearer {token} ``` **Download the output** when status is `success`: ```http theme={null} GET /2026-07/retail-media/reports/{reportId}/output Authorization: Bearer {token} ``` With no `format` specified, the output defaults to `json-compact` — a `columns`/`data` array shape rather than an array of row objects: ```json theme={null} { "columns": ["date", "campaignName", "lineItemName", "impressions", "clicks", "spend", "roas"], "data": [ ["2026-05-01", "Spring Sale - Kitchen Search", "Spring Sale - Kitchen Search - Broad", 2176050, 6461, 15506.65, 22.14], ["2026-05-02", "Spring Sale - Kitchen Search", "Spring Sale - Kitchen Search - Broad", 1902829, 6396, 15295.60, 20.36], ["2026-05-03", "Spring Sale - Kitchen Search", "Spring Sale - Kitchen Search - Broad", 2061778, 6782, 16234.17, 21.70], ["2026-05-04", "Spring Sale - Kitchen Search", "Spring Sale - Kitchen Search - Broad", 1965894, 6287, 15034.17, 24.13], ["2026-05-05", "Spring Sale - Kitchen Search", "Spring Sale - Kitchen Search - Broad", 1968091, 6261, 12959.99, 30.44], ["2026-05-06", "Spring Sale - Kitchen Search", "Spring Sale - Kitchen Search - Broad", 2075084, 6648, 14762.81, 25.46], ["2026-05-07", "Spring Sale - Kitchen Search", "Spring Sale - Kitchen Search - Broad", 2089278, 6551, 15127.54, 20.34] ], "rows": 7 } ``` *** ## Response Codes For the full list of status and error codes for this endpoint — including `404` (report not found) and `410` (report expired) — see [Response Codes](/retail-media/docs/demand-side-analytics-overview#response-codes) in the Overview. *** ## Metrics Fields marked **Retailer catalog only** are available only for retailers that provide a product catalog to Criteo. For retailers without a catalog, they are not populated. | Metric | Description | | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `impressions` | Counted once per ad creative render on a page. | | `clicks` | Counted when an ad creative is clicked. | | `spend` | Total media spend. Includes platform fees for Criteo-billed; media only for retailer-billed. | | `roas` | Return on ad spend — revenue per unit of currency spent. | | `ctr` | Click-through rate: clicks / impressions. | | `cpc` | Average cost per click. Sponsored products only. | | `cpm` | Average cost per 1,000 impressions. Onsite display only. | | `cpo` | Cost per order: spend / attributed orders. | | `attributedSales` | Sales revenue directly attributed to the campaign per your attribution settings. | | `attributedUnits` | Units sold attributed to the campaign. Excludes assisted units. | | `attributedOrders` | Orders attributed per your attribution settings. | | `assistedSales` | Revenue from ads that were not the final ad before purchase but contributed to the conversion. | | `assistedUnits` | Units sold through assisted conversions. Excluded from `attributedUnits`. | | `newToBrandAttributedSales` | Attributed sales from customers who had not purchased from this brand in the prior 12 months. **Retailer catalog only.** | | `newToBrandAttributedSalesRate` | `newToBrandAttributedSales` / `attributedSales`. **Retailer catalog only.** | | `newToBrandAttributedUnits` | Attributed units from new-to-brand customers. **Retailer catalog only.** | | `newToBrandAttributedUnitsRate` | `newToBrandAttributedUnits` / `attributedUnits`. **Retailer catalog only.** | | `frequency` | Average number of times the same user saw an impression in the reporting period. | | `uniqueVisitors` | Distinct shoppers exposed to an ad in the reporting period. | | `winRate` | Bids won divided by bids participated. Based on a 25% sample. Sponsored products only. | | `sampledBidsWon` | Bids won across auctions. Based on a 25% sample. | | `sampledBidsParticipated` | Bids participated in auctions. Based on a 25% sample. | | `videosStarted` | Count of videos that started playing. | | `videoStartingRate` | Percentage of printed videos that started playing. | | `videoViews` | Videos meeting the MRC viewability standard (50% visible for 2+ continuous seconds). | | `videoViewability` | Percentage of video ads considered viewable per MRC standards. | | `videoCompletionRate` | Percentage of started videos that played to completion. | | `videosPlayedTo25` | Videos that played at least 25% of their duration. | | `videosPlayedTo50` | Videos that played at least 50% of their duration. | | `videosPlayedTo75` | Videos that played at least 75% of their duration. | | `videosPlayedTo100` | Videos that played to 100% of their duration. | | `videoPlayingRate` | Average played percentage of a started video. | | `videoMuted` | Count of video mute button clicks. | | `videoUnmuted` | Count of video unmute button clicks. | | `videoPaused` | Count of video pause activations. | | `videoResumed` | Count of video resume activations. | | `videoImpressions` | Count of video ad impressions. | | `videoAvgInteractionRate` | Average interaction rate across video engagements. | | `videoCPC` | Average cost per video click. | | `videoCPCV` | Cost per completed video view. | The `winRate` metric is meaningful only for Sponsored Products campaigns. For accounts that also run other campaign types, include `campaignType` in your `dimensions` (or filter to Sponsored Products) so `winRate` can be attributed to the right campaigns. *** ## Dimensions Fields marked **Retailer catalog only** are available only for retailers that provide a product catalog to Criteo. For retailers without a catalog, they are not populated. | Dimension | Description | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `date` | Date events occurred (`YYYY-MM-DD`). | | `hour` | Hour events occurred (0–23). | | `accountId` | Account ID. | | `accountName` | Account name. | | `campaignId` | Campaign ID. | | `campaignName` | Campaign name. | | `campaignType` | Campaign type. | | `lineItemId` | Line item ID. | | `lineItemName` | Line item name. | | `retailerId` | Retailer ID where the line item served. | | `retailerName` | Retailer name where the line item served. | | `brandId` | Brand ID of the advertised product. **Retailer catalog only.** | | `brandName` | Brand name of the advertised product. **Retailer catalog only.** | | `productCategory` | Category of the advertised product. Standardized categories. **Retailer catalog only.** | | `productId` | Advertised product ID. References the Catalogs product ID. | | `productName` | Name of the advertised product. | | `salesChannel` | Purchase channel: `online` or `offline`. | | `mediaType` | Media type of the line item. | | `buyType` | Buy type of the line item. | | `budgetModel` | Budget model of the line item. | | `activationPlatform` | Activation platform of the line item. | | `environment` | Type of environment: `web`, `mobile`, `app`. | | `pageType` | Type of retailer page where the ad rendered: `home`, `search`, `category`, `productDetail`, `merchandising`, `deals`, `checkout`, `confirmation`. | | `pageCategory` | Retailer-defined category of the page where ads rendered. **Retailer catalog only.** | | `servedCategory` | Category of the page where the ad was served. Retailer-specific taxonomy. **Retailer catalog only.** | | `keyword` | Keyword or phrase used on the search page where the ad rendered. | | `searchTerm` | Keyword or phrase searched by the shopper on the retailer site. | | `searchTermType` | Match type: `Entered`, `Searched`, or `Null`. | | `searchTermTargeting` | Targeting strategy: `Manual` or `Automatic`. | | `creativeId` | Creative ID. Onsite display only. | | `creativeName` | Creative name. Onsite display only. | | `creativeType` | Creative type: Commerce Display, Commerce Video, Standard Display, Standard Video. Onsite display only. | | `creativeTemplateId` | Creative template ID. Onsite display only. | | `creativeTemplateName` | Ad format: Flagship, Showcase, SponsoredProducts, Butterfly, BundleBoost, IAB, DisplayPanel, DigitalShelfTalker, CommerceVideoSpotlight, Custom. | | `targetedKeywordType` | Conquesting strategy: `Conquesting`, `Branded`, `Generic`, or `Unknown`. | *** ## Data Retention This endpoint supports a lookback window of up to **3 years** (36 months). A request with a `startDate` older than that returns `400 Bad Request` — `StartDate cannot be older than 3 years.` Separately, a single report may span at most **100 days** between `startDate` and `endDate`, regardless of whether you scope by account, campaign, or line item. *** ## Migrating from legacy endpoints The full legacy → new mapping (all endpoints and every `reportType` value) is documented in the [Analytics Overview — Migrating from the legacy reporting API](/retail-media/docs/demand-side-analytics-overview#migrating-from-the-legacy-reporting-api). # Promoted Products Source: https://developers.criteo.com/retail-media/docs/promoted-products ## Introduction * A promoted product specifies the product that will be advertised on a line item. * Identify eligible products to promote by accessing your account [catalog](/retail-media/docs/catalogs). * Each product can optionally be configured with a specific bid amount, allowing you to control how much you are willing to pay per click. * The suggested limit is 1500 SKUs. This is a soft limit: exceeding it won’t result in errors, but performance runs the risk of degradation at higher volumes. *** ## Endpoints

Method

Endpoint

Description

GET

/line-items/\{lineItemId}/products

Retrieve all products associated with a specific line item.

POST

/line-items/\{lineItemId}/products/append

Add products to a specific line item or update their bid override.

POST

/line-items/\{lineItemId}/products/delete

Remove products from a specific line item.

POST

/line-items/\{lineItemId}/products/pause

Pause products on a specific line item, preventing them from being advertised.

POST

/line-items/\{lineItemId}/products/unpause

Reactivate paused products on a specific line item, allowing them to be advertised again.

*** ## Promoted Products Attributes

Attribute

Data Type

Description

id \*

string

Product ID, unique identifier at the Retailer catalog and obtained from the account Catalog

Accepted values: up to 500 -chars string

Writeable? N / Nullable? N

lineItemId \*

string

Line Item ID, in which the product is to be promoted; required in the endpoints' path to define in which line item to perform the action

Accepted values: string or int64

Writeable? N / Nullable? N

bidOverride

decimal

Bid value for the specific product; overrides targetBid specified on the Line Item and must satisfy minBid from Catalog (input excludes platform fees). The value 0.0 will remove a bidOverride and the product bid will default to the line item's targetBid .

Accepted values: bidOverride minBid , 0.0

Writeable? N / Nullable? Y

status

enum

Status of Promoted Product; can only be updated to active or paused using the endpoints below.

For more details about each state, check out Campaign, Line Item & Products Status

Returned values: active , paused , scheduled , ended , budgetHit , noFunds , draft , archived

Writeable? Y / Nullable? N

*\*Required* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Get All Products on Specific Line Item This endpoint lists all products on the specified line item. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `500`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). An additional query parameter `fields` is supported to receive a comma-separated list of optional attributes to include in the response, to optimize response time and payload length. ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products ``` **Sample Request** ```bash cURL theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products?offset=0&limit=10&fields=bidOverride,status" \ -H "Authorization: Bearer " ``` ```python Python theme={null} import requests url = "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products?offset=0&limit=10&fields=bidOverride" payload={} headers = { 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products?offset=0&limit=10&fields=bidOverride") .method("GET", body) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products?offset=0&limit=10&fields=bidOverride'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** 🔵 HTTP code `200`: ```json theme={null} { "meta": { "offset": 0, "limit": 10, "count": 10, "responseCount": 10 }, "data": [ { "id": "06d3049c3e1642ec92479dbeca1fc39f", "type": "RetailMediaPromotedProduct", "attributes": { "bidOverride": 0.70, "status": "active" } }, // ... { "id": "926097", "type": "RetailMediaPromotedProduct", "attributes": { "bidOverride": 0.30, "status": "active" } } ] } ``` *** ## Add Products to specific Line Item, or Update Bid Override This endpoint adds one or more products to promote on the specified line item. If the product already exists, only its bid override will be updated. ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/append ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products/append' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "id": "492731", "type": "RetailMediaPromotedProduct", "attributes": { "id": "492731", "status": "paused", "bidOverride": "0.0" } } ] }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products/append" payload = json.dumps({ "data": [ { "id": "492731", "type": "RetailMediaPromotedProduct", "attributes": { "id": "492731", "status": "paused", "bidOverride": "0.0" } } ] }) headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(""" { "data": [ { "id": "492731", "type": "RetailMediaPromotedProduct", "attributes": { "id": "492731", "status": "paused", "bidOverride": "0.0" } } ] } """, mediaType); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products/append") .post(body) .addHeader("Accept", "application/json") .addHeader("Content-Type", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP expandable theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products/append'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Accept' => 'application/json', 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' )); $body = <<<JSON { "data": [ { "id": "492731", "type": "RetailMediaPromotedProduct", "attributes": { "id": "492731", "status": "paused", "bidOverride": "0.0" } } ] } JSON; $request->setBody($body); try{ $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .; $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** 🔵 HTTP code `204` (no body content) *** ## Remove Products from a specific Line Item This endpoint removes one or more products from the specified line item. The resulting state of the line item is returned as a single page. Line items can be created without any promoted products, but once any products are added, at least one product must remain. ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/delete ``` **Sample Request** ```bash cURL theme={null} curl -X POST "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products/delete" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "data": [ { "id": "sku1", "type": "RetailMediaPromotedProduct" } ] }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/delete" payload = json.dumps({ "data": [ { "id": "be5a3dbc8eaf46608d58ce68107a5854", "type": "RetailMediaDeleteProduct", "attributes": { "bidOverride": "0.30" } } ] }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"data\": [\n {\n \"id\": \"be5a3dbc8eaf46608d58ce68107a5854\",\n \"type\": \"RetailMediaDeleteProduct\",\n \"attributes\": {\n \"bidOverride\": \"0.30\"\n }\n }\n ]\n}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/delete") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/delete'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{\n "data": [\n {\n "id": "be5a3dbc8eaf46608d58ce68107a5854",\n "type": "RetailMediaDeleteProduct",\n "attributes": {\n "bidOverride": "0.30"\n }\n }\n ]\n}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** 🔵 HTTP code `204` (no body content) *** ## Pause Products on a Specific Line Item This endpoint allows reactivating one or multiple paused products on a line item: ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/pause ``` **Sample Request** ```bash cURL theme={null} curl -X POST 'https://api.criteo.com/{version}/retail-media/line-items/311990577399115776/products/pause' \ -H 'Content-Type: application/json' \ -H'Authorization: Bearer ' \ -d '{ "data": [ { "id": "4f5c49fce3c94542b5023e7cc1e1f5ca", "type": "RetailMediaPromotedProduct" } ] }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/pause" payload = json.dumps({ "data": [ { "id": "be5a3dbc8eaf46608d58ce68107a5854", "type": "RetailMediaPausePromoteDProduct" } ] }) headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/pause'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{\n "data": [\n {\n "id": "be5a3dbc8eaf46608d58ce68107a5854",\n "type": "RetailMediaPausePromoteDProduct"\n }\n ]\n}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"data\": [\n {\n \"id\": \"be5a3dbc8eaf46608d58ce68107a5854\",\n \"type\": \"RetailMediaPausePromoteDProduct\"\n }\n ]\n}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/pause") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` **Sample Response** 🔵 HTTP code `204` (no body content) *** ## Unpaused Products on a Specific Line Item This endpoint allows unpausing one or multiple products on a line item: ```http theme={null} https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/unpause ``` **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/line-items/311990577399115776/products/unpause' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "id": "4f5c49fce3c94542b5023e7cc1e1f5ca", "type": "RetailMediaPromotedProduct" } ] }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/unpause" payload = json.dumps({ "data": [ { "id": "be5a3dbc8eaf46608d58ce68107a5854", "type": "RetailMediaPausePromoteDProduct" } ] }) headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"data\": [\n {\n \"id\": \"be5a3dbc8eaf46608d58ce68107a5854\",\n \"type\": \"RetailMediaPausePromoteDProduct\"\n }\n ]\n}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/unpause") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/line-items/325713346766241792/products/unpause'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{\n "data": [\n {\n "id": "be5a3dbc8eaf46608d58ce68107a5854",\n "type": "RetailMediaPausePromoteDProduct"\n }\n ]\n}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** 🔵 HTTP code `204` (no body content) *** ## Responses

Response

Description

🟢 200

Call completed with success

🟢 204

Promoted product paused or unpaused with success (no body content returned)

🔴 400

Bad Request - Common validation errors:

  • Could not find the SKU ID used to append to the line item. Make sure the SKU exists in the retailer's catalog
  • Product bid override less than the product min bid
  • Invalid bid override: Cannot use bid override attribute for a product belonging to a preferred deals line item
  • Pausing/Unpausing promoted products: Only the ID is required; do not include BidOverride or Status attributes.

🔴 403

API user does not have authorization to make requests for the account ID. For authorization, follow the authorization request steps.

🔴 404

Line item ID not found

***
## What's next * [Recommended Keywords](/retail-media/docs/recommended-keywords) * [Recommended Categories](/retail-media/docs/recommended-categories) * [Category Search](/retail-media/docs/category-search) # Real-Time Performance Report Source: https://developers.criteo.com/retail-media/docs/real-time-performance-api Retrieve near real-time campaign performance data synchronously using the Retail Media Real-Time Performance API ## Introduction The Retail Media Real-Time Performance API is a synchronous reporting endpoint that exposes **near real-time campaign performance data from the Retail Media reporting platform**. This API is designed for: * Demand Side users accessing through a Commerce Yield Private Market account, * Demand Side users accessing through a Commerce Max Network account. Typical use-cases for this endpoint include, for example: * Real-time monitoring during major retail events (for example, Black Friday, Prime Day, etc.), * Live optimization dashboards for trading teams, * Alerting systems reacting to sudden performance changes (spend drops/spikes, click anomalies, etc.). This endpoint provides: * about **15 minute latency** from impression/click to availability in the API, * a maximum **7-day look back window,** * **Onsite campaign** coverage only, * A focused set of metrics: `impressions`, `clicks`, `spend`. **Metric rename from Preview**: `billableImpressions` and `billableClicks` have been renamed to `impressions` and `clicks` in the stable API. These metrics now count total volume (billable + non-billable). If you were using this endpoint in Preview, update your field mappings before migrating to stable. *** ## Endpoints Overview

Verb

Endpoint

Description

POST

/retail-media/reports/sync/real-time-performance

Retrieves real-time Retail Media performance metrics

*** ## Attributes

Attribute

Data Type

Description

startDate \*

date

Start date (YYYY-MM-DD) for the reporting window. Must be no more than 7 days in the past in the requested timezone.

endDate

date

End date (YYYY-MM-DD) for the reporting window. Optional

retailerIds

array of strings

Single retailer ID filter. Optional

accountIds

array of strings

Filter by account IDs. Max 5 IDs.

Choose one of: accountIds , campaignIds , or lineItemIds

campaignIds

array of strings

Filter by campaign IDs. Max 50 IDs.

Choose one of: accountIds , campaignIds , or lineItemIds

lineItemIds

array of strings

Filter by line item IDs. Max 50 IDs.

Choose one of: accountIds , campaignIds , or lineItemIds

dimensions \*

array of strings

Grouping dimensions. Must contain at least one value.

metrics \*

array of strings

Requested metrics. Must contain at least one value.

timezone

string

Time zone identifier. Defaults to UTC if not provided.

(\*) - *Required* At least **one of `dimensions`** and at least **one of `metrics`** must be provided. For **entity filters**: only one of `accountIds` or `campaignIds` or `lineItemIds` must be provided. This prevents unbounded queries on the full dataset. ### Supported Dimensions Values in the `dimensions` array must be selected from: * `accountId`, * `campaignId`, * `lineItemId`, * `retailerId`, * `accountName`, * `campaignName`, * `lineItemName`, * `retailerName`, * `date`, * `hour`. ### Supported Metrics Values in the `metrics` array must be selected from: * `impressions`, * `clicks`, * `spend`. `billableImpressions` and `billableClicks` are still accepted for backward compatibility with existing preview integrations, but are redundant with `impressions`/`clicks` and should not be used in new integrations. ### Behavioral Notes * **Optional end date parameter**: The endpoint accepts an optional `endDate` parameter. If omitted, it will return data from `startDate` up to the current hour in the requested timezone. * **Look back limit**: The look back window is limited to 7 days relative to "now" in the requested timezone.\ Requests with `startDate` older than this limit are rejected with a 400 Bad Request. * **Time zone handling**: All date/hour-based dimensions (date, hour) are computed in the requested timezone.\ If timezone is omitted, UTC is used. *** ## Real-Time Performance Endpoint This endpoint retrieves real-time Retail Media performance metrics. ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/sync/real-time-performance ``` *** ### **Sample Request** ```bash cURL theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/reports/sync/real-time-performance' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "startDate": "2026-03-01", "timezone": "America/New_York", "campaignIds": ["561627568743333888"], "dimensions": ["date", "hour", "campaignId", "campaignName"], "metrics": ["impressions", "clicks", "spend"] } } }' ``` ```python Python theme={null} import http.client import json conn = http.client.HTTPSConnection("api.criteo.com") payload = json.dumps({ "data": { "attributes": { "startDate": "2026-03-01", "timezone": "America/New_York", "campaignIds": ["561627568743333888"], "dimensions": ["date", "hour", "campaignId", "campaignName"], "metrics": ["impressions", "clicks", "spend"] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } conn.request("POST", "/{version}/retail-media/reports/sync/real-time-performance", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder().build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"attributes\":{\"startDate\":\"2026-03-01\",\"timezone\":\"America/New_York\",\"campaignIds\":[\"561627568743333888\"],\"dimensions\":[\"date\",\"hour\",\"campaignId\",\"campaignName\"],\"metrics\":[\"impressions\",\"clicks\",\"spend\"]}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/{version}/retail-media/reports/sync/real-time-performance") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/{version}/retail-media/reports/sync/real-time-performance'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data":{"attributes":{"startDate":"2026-03-01","timezone":"America/New_York","campaignIds":["561627568743333888"],"dimensions":["date","hour","campaignId","campaignName"],"metrics":["impressions","clicks","spend"]}}}'); $response = $request->send(); echo $response->getBody(); ?> ``` *** ### **Sample Response** ```json expandable theme={null} { "meta": { "dataCompleteThrough": { "dateTime": "2026-03-01 15:45:00", "timezone": "America/New_York" }, "columns": [ { "name": "date", "type": "Date", "role": "Dimension", "timezone": "America/New_York" }, { "name": "hour", "type": "Number", "role": "Dimension", "timezone": "America/New_York" }, { "name": "impressions", "type": "Number", "role": "Metric" } ], "rows": 50 }, "data": { "type": "ReportDataResponse", "attributes": [ ["2026-03-01", 13, 536], ["2026-03-01", 14, 563], ["2026-03-01", 15, 641] ] }, "warnings": [], "errors": [] } ``` *** ## Responses

Response

Title

Detail

Troubleshooting

🟢 200

Success

Data returned successfully

Call executed with success

🔴 400

Validation Error

Invalid request (timezone, filters, dimensions, metrics, look back, etc.)

Review request parameters

🔴 400

Missing Entity Filters

No accountIds , campaignIds , or lineItemIds provided

Provide exactly one entity filter

🔴 400

Entity Filter Limit Exceeded

Too many IDs provided

Respect max limits

🔴 400

Missing Metrics

metrics is missing or empty

Provide at least one metric

🔴 400

Missing Dimensions

dimensions is missing or empty

Provide at least one dimension

🔴 400

Look back Window Exceeded

startDate too old

Ensure ≤ 7 days

🔴 400

Invalid Timezone

Unsupported timezone

Use valid timezone

🔴 400

Deserialization Error

Invalid format or type

Fix payload format

🔴 403

Forbidden

Unauthorized access to resources

Check permissions

*** ## Error Examples ### Validation Error (Invalid Timezone) ```json theme={null} { "warnings": [], "errors": [ { "traceId": "0b396e92adef8703a22dd5a5898e05b7", "traceIdentifier": "0b396e92adef8703a22dd5a5898e05b7", "type": "validation", "code": "invalid", "instance": "/retail-media/reports/sync/real-time-performance", "title": "Time zone America/Paris is not valid. See criteo developer portal for supported time zones", "source": { "Data.Attributes.Timezone": "Data.Attributes.Timezone" } } ] } ``` ### Missing Entity Filters ```json theme={null} { "errors": [ { "type": "validation", "code": "invalid", "instance": "/retail-media/reports/sync/real-time-performance", "title": "Exactly one of accountIds, campaignIds, or lineItemIds must be provided" } ] } ``` ### Entity Filter Limit Exceeded ```json theme={null} { "errors": [ { "type": "validation", "code": "invalid", "instance": "/retail-media/reports/sync/real-time-performance", "title": "You must provide at most 50 ids in 'CampaignIds', 73 were provided." } ] } ``` ### Missing Metrics ```json theme={null} { "errors": [ { "type": "validation", "code": "invalid", "instance": "/retail-media/reports/sync/real-time-performance", "title": "At least one metric must be specified" } ] } ``` ### Missing Dimensions ```json theme={null} { "errors": [ { "type": "validation", "code": "invalid", "instance": "/retail-media/reports/sync/real-time-performance", "title": "At least one dimension must be specified" } ] } ``` ### Look back Window Exceeded ```json theme={null} { "errors": [ { "type": "validation", "code": "invalid", "instance": "/retail-media/reports/sync/real-time-performance", "title": "startDate cannot be more than 7 days in the past" } ] } ``` ### Deserialization Error ```json theme={null} { "errors": [ { "type": "validation", "code": "deserialization-error", "instance": "/retail-media/reports/sync/real-time-performance", "title": "Deserialization error" } ] } ``` ### Forbidden ```json theme={null} { "errors": [ { "type": "Authorization", "code": "forbidden", "instance": "/retail-media/reports/sync/real-time-performance", "title": "You are not authorized to access some of the requested resources.", "detail": "Please make sure you have the necessary permissions." } ] } ``` # Recommended Categories Source: https://developers.criteo.com/retail-media/docs/recommended-categories ## Introduction The Recommended Categories endpoint helps you discover the most relevant product categories for your advertising campaigns by leveraging a retailer's taxonomy structure. This endpoint analyzes your specified products and returns up to 50 recommended categories that align with where your products naturally fit within the retailer's inventory organization. Recommended categories are pulled directly from the retailer's taxonomy, with each product having a category that indicates its position within the retailer's inventory hierarchy. The endpoint uses the pages and child pages where products are already positioned to generate recommendations, ensuring that the suggestions are inherently relevant to the products associated with your line items. This data-driven approach is particularly valuable for **campaign targeting optimization**, **category expansion strategies**, and understanding how your products align with the retailer's organizational structure. By using these recommendations, you can improve campaign performance by targeting the most appropriate product categories and reaching shoppers who are browsing relevant product sections. *** ## Endpoint

Method

Endpoint

Description

POST

/retailers/\{retailerId}/recommend-categories

Gets the top 50 recommended categories for specified products

*** ## Attributes table

Attribute

Data Type

Description

retailerId \*

string

Unique identifier for the retailer. Found using the GET retailers endpoint.

Required in URL path.

Writable? N / Nullable? N

productIds \*

array

Array of product ID strings for category recommendations.

Min: 1 item, Max: 1000 items.

Required field.

Writable? Y / Nullable? N

\**Required* *** ## Get Recommended Categories This endpoint retrieves the top 50 recommended categories for specified products based on the retailer's taxonomy structure. Categories are determined by the pages and child pages where products are currently positioned within the retailer's inventory. **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/retailers/12345/recommend-categories' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "productIds": [ "PROD123", "PROD456", "PROD789" ] }, "type": "RecommendedCategoriesRequestV1" } }' ``` **Sample Response** ```json expandable theme={null} { "data": [ { "id": "520020", "type": "CategoryV1", "attributes": { "text": "Electronics|Audio|Headphones|Wireless", "name": "Wireless Headphones", "parentId": "522931" } }, { "id": "810902", "type": "CategoryV1", "attributes": { "text": "Electronics|Audio|Headphones", "name": "Headphones", "parentId": "2816897" } }, { "id": "2802692", "type": "CategoryV1", "attributes": { "text": "Electronics|Audio", "name": "Audio Equipment", "parentId": "13772216" } } ], "warnings": [ { "traceId": "7eaa128c7ef3417ddb40654d40006773", "type": "validation", "code": "not-all-skus-available", "title": "Partial result", "detail": "Sku ids 8110729593111,8110728872215 are not available." } ], "errors": [] } ``` *** ## Responses

Code

Meaning

Troubleshooting Hint

🟢 200

Success

Request processed successfully, returns up to 50 recommended categories.

🔴 400

Bad Request

Check that productIds array is provided with 1-1000 items, and retailerId is valid in URL path.

🔴 403

Forbidden

Verify authorization and retailer access permissions.

*** ### Common Error Scenarios **Missing or Empty Product IDs** ```json theme={null} { "warnings": [], "errors": [ { "traceId": "6f7fcf70d8b024627481b771c79656f6", "type": "validation", "code": "model-validation-error", "title": "Model validation error", "detail": "Required property 'skuIds' not found in JSON. Path 'data.attributes', line 7, position 5." } ] } ``` **Invalid Retailer ID** ```json theme={null} { "warnings": [], "errors": [ { "traceId": "ea6343210d0922cd1217b99448e98839", "type": "validation", "code": "model-validation-error", "title": "Model validation error", "detail": "The value ':retailerId' is not valid." } ] } ``` ***
## What's next * [Recommended Keywords](/retail-media/docs/recommended-keywords) * [Category Search](/retail-media/docs/categories) # Recommended Keywords Source: https://developers.criteo.com/retail-media/docs/recommended-keywords ## Introduction The Recommended Keywords endpoint helps to discover the most relevant keywords for your advertising campaigns by leveraging Criteo's advanced Keyword Service technology. This is the same algorithm used to generate keywords for Sponsored Products line items that serve on search pages across retail environments. When you provide `product IDs`, this endpoint analyzes your products and returns the top 100 keywords that your Sponsored Product and Onsite Display line items would serve on when shoppers search for related terms. This data-driven approach ensures your campaigns target the most effective keywords based on actual search behavior and product relevance. The Recommended Keywords are particularly valuable for **campaign optimization**, **keyword expansion strategies**, and **understanding how your products align with shopper search intent**. By using these recommendations, you can improve campaign performance and reach more qualified shoppers who are actively searching for products like yours. *** ## Endpoints

Method

Endpoint

Description

POST

/retailers/\{retailerId}/recommend-keywords

Gets the top 100 recommended keywords for specified products

*** ## Attributes table

Attribute

Data Type

Description

retailerId \*

string

Unique identifier for the retailer. Found using the GET retailers endpoint.

Required in URL path.

Writable? N / Nullable? N

productIds \*

array

Array of product ID strings for keyword recommendations.

Min: 1 item, Max: 1000 items.

Required field.

Writable? Y / Nullable? N

\**Required* *** ## Get Recommended Keywords This endpoint retrieves the top 100 recommended keywords for specified products using Criteo's Keyword Service technology. The recommendations are based on the same algorithms used for Sponsored Products line items serving on search pages. **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/retailers/12345/recommend-keywords' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "productIds": [ "PROD123", "PROD456", "PROD789" ] }, "type": "RecommendedKeywordsRequestV1" } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "RecommendedKeywordsResponseV1", "attributes": { "recommendedKeywords": [ "wireless headphones", "bluetooth earbuds", "noise cancelling headphones", "gaming headset", "wireless earbuds", "bluetooth headphones", "over ear headphones", "sports headphones", "true wireless earbuds", "active noise cancellation" ] } }, "warnings": [], "errors": [] } ``` *** ## Responses

Code

Meaning

Troubleshooting Hint

🟢 200

Success

Request processed successfully, returns up to 100 recommended keywords

🔴 400

Bad Request

Check if productIds array is provided with 1-1000 items, and retailerId is valid in URL path

🔴 403

Forbidden

Verify authorization and retailer access permissions

*** ### Common Error Scenarios **Missing or Empty Product IDs** ```json theme={null} { "errors": { "Data.Attributes.ProductIds": [ "The field ProductIds must be a string or array type with a minimum length of '1'." ] }, "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-e03b1ec1e478d6ac2b6645102df581b0-770e081f98eea942-01" } ``` **Invalid Retailer ID** ```json theme={null} { "errors": { "retailerId": [ "The value ':retailerId' is not valid." ] }, "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-2674ea556f336eb5d84536b5674db671-99e929542eda8eff-01" } ``` ***
## What's next * [Category Search](/retail-media/docs/category-search) # Retailer Budgets Source: https://developers.criteo.com/retail-media/docs/retailer-budgets ## Introduction **Commerce Max Retailer Budgets** introduces a buying model in which campaign budgets are funded by the retailer rather than the advertiser. This guide covers the API changes required for third-party buying platforms to create and manage Retailer Budgets Sponsored Products campaigns end-to-end. ### Business Context Prior to this release, the Retail Media API did not expose retailer scoping on balances, campaigns, or line items. Retailer-budgets buying requires platforms to associate balances, campaigns, and line items to the same retailer — the API now enforces these constraints explicitly. ### Prerequisites * API version `2026-01` or later is required to see retailer-billed balances. On prior versions, retailer-budgets balances are hidden by default to prevent integration surprises during rollout. * Platforms must use the supply account ID when querying balances if they wish to discover retailer-budgets balances. ### Key Concepts * **Retailer-budgets balance** — a budget object funded by the retailer, scoped to a specific `RetailerId`. Cannot be created via API; must be retrieved via `GET /balances`. * **`RetailerId`** — the identifier of the retailer that funds the balance and scopes the campaign. Must be consistent across balance → campaign → line item. * **`budgetModel`** — a new field on the retailer search response indicating which budget models (e.g., `retailerBilled`, `capped`, `uncapped`) are supported at a given retailer. **Backward compatibility for balance endpoints:** * The `poNumber` field on balance responses is **removed** in `2026-01` and replaced by two separate fields: `retailerPoNumber` and `criteoPoNumber`. This is a breaking change for consumers of `GET /balances` on prior versions who rely on `poNumber`. * All other new fields (`retailerId`, `privateMarketBillingType`) are additive. Retailer-budgets balances are hidden by default on prior API versions. *** ## Endpoints Overview All endpoints changes related to Retailer Budgets are also documented in the following pages: * [Balances Endpoint Guide](/retail-media/docs/balances-endpoints) * [Campaigns Endpoint Guide](/retail-media/docs/campaigns-endpoints) * [Auction Line Items Endpoint Guide](/retail-media/docs/onsite-sponsored-products-line-items) * [Retailer Search Endpoint Guide](/retail-media/docs/retailer-search)

Verb

Endpoint

Description

GET

/retail-media/balances/\{balanceId}

Get a single balance. Now includes retailerId , retailerPoNumber , criteoPoNumber .

GET

/retail-media/accounts/\{accountId}/balances

List balances. Now includes retailer fields. Retailer-budgets balances hidden on prior versions.

GET

/retail-media/balances/\{balanceId}/history

Get balance change history. Now includes retailerPoNumber , criteoPoNumber .

POST

/retail-media/balances/\{balanceId}/campaigns/append

Add campaigns to a balance. Validates retailer consistency.

POST

/retail-media/balances/\{balanceId}/campaigns/delete

Remove campaigns from a balance. Returns error for retailer-billed balances.

POST

/retail-media/accounts/\{accountId}/campaigns

Create a campaign. Now accepts and validates retailerId .

GET

/retail-media/campaigns

List campaigns. Now returns retailerId ; supports filtering by retailer.

GET

/retail-media/campaigns/\{campaignId}

Get a campaign. Now returns retailerId .

POST

/retail-media/campaigns/\{campaignId}/auction-line-items

Create a line item. Enforces targetRetailerId matches campaign retailer.

POST

/retail-media/accounts/\{accountId}/retailers/search

Search retailers. Now returns budgetModel in campaignAvailabilities .

*** ## Attributes ### New and Changed Fields on Balances

Attribute

Data Type

Mutable

Description

retailerId

string?

init

Retailer this balance is scoped to.

Present only on retailer-budgets balances.

*Nullable?* Y (null for non-retailer-billed)

retailerPoNumber

string?

always

Retailer purchase order number. Replaces the removed poNumber field.

*Nullable?* Y

criteoPoNumber

string?

always

Criteo purchase order number.

Replaces the removed poNumber field.

*Nullable?* Y

privateMarketBillingType

enum

init

Billing type for Private Market. Values: NotApplicable , BillByRetailer , BillByCriteo , Unknown

\~\~ poNumber \~\~

~~string~~

Removed in 2026-01 . Replaced by retailerPoNumber and criteoPoNumber .

*** ### New Field on Campaigns A new field `retailerId` has been added to the following endpoints: * `/accounts/{accountId}/campaigns` * `/campaigns/{campaignId}`

Attribute

Data Type

Description

retailerId

string

The retailer this campaign is associated with.

Required when using a retailer-budgets balance.

Writeable? Y (at create)

Nullable? Y (for non-retailer-budgets campaigns)

### New Fields on Retailer Search The new fields are added to the following endpoint: * `/accounts/{accountId}/retailers/search`

Attribute

Data Type

Description

budgetModel

string

Budget model(s) supported for the given buyType / campaignType combination at this retailer.

Values: capped , uncapped , retailerBudgets , criteoBudgets

Writeable? N

Nullable? N

### New Error Codes

Error code

Endpoint

Meaning

RetailerBilledBalanceImmutable

DELETE /balances/\{balanceId}/campaigns

Cannot remove a retailer-budgets balance from a campaign.

RetailerMismatchWithBalance

POST /accounts/\{accountId}/campaigns

Campaign RetailerId does not match the balance's RetailerId .

RetailerMismatchWithCampaign

POST /campaigns/\{campaignId}/auction-line-items

Line item targetRetailerId does not match the campaign's RetailerId .

*** # Endpoint Changes ## Get List of Balances for an Account This endpoint returns a paginated list of balances for an account. On API version `2026-01` and later, retailer-budgets balances are included and `retailerId`, `retailerPoNumber`, and `criteoPoNumber` are returned. The old `poNumber` field is removed. **Query parameters** * `offset` (int, default 0), * `limit` (int, default 25, max 500), * `limitToId` (List\) ```text theme={null} https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/balances ``` **Sample Request** ```bash cURL theme={null} curl -L -X GET 'https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/balances' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` ```python Python theme={null} import http.client conn = http.client.HTTPSConnection("api.criteo.com") headers = {'Accept': 'application/json', 'Authorization': 'Bearer <TOKEN>'} conn.request("GET", "/2026-01/retail-media/accounts/625702934721171442/balances", headers=headers) res = conn.getresponse() print(res.read().decode("utf-8")) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder().build(); Request request = new Request.Builder() .url("https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/balances") .method("GET", null) .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer <TOKEN>") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/balances'); $request->setMethod(HTTP_Request2::METHOD_GET); $request->setHeader(array('Accept' => 'application/json', 'Authorization' => 'Bearer <TOKEN>')); echo $request->send()->getBody(); ``` **Sample Response** ```json expandable theme={null} { "metadata": { "totalItemsAcrossAllPages": 135, "currentPageSize": 25, "currentPageIndex": 0, "totalPages": 6 }, "data": [ { "id": "100000000000000001", "type": "BalanceV1", "attributes": { "name": "Sample Name", "retailerPoNumber": null, "criteoPoNumber": "PO-CRITEO-123", "retailerId": null, "memo": "Sample memo", "deposited": 10.0, "spent": 10.0, "remaining": 0.0, "startDate": "2020-04-13", "endDate": null, "status": "ended", "createdAt": "2020-04-13T15:39:48+00:00", "updatedAt": "2023-06-13T13:35:53+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "notApplicable" } }, { "id": "100000000000000002", "type": "BalanceV1", "attributes": { "name": "Sample Name", "retailerPoNumber": "PO-RETAILER-123", "criteoPoNumber": "PO-CRITEO-123", "retailerId": 123, "memo": "Sample memo", "deposited": 100.0, "spent": 0.16, "remaining": 99.84, "startDate": "2026-03-24", "endDate": null, "status": "active", "createdAt": "2026-03-24T18:15:58+00:00", "updatedAt": "2026-05-20T17:17:40+00:00", "balanceType": "capped", "spendType": "onsite", "privateMarketBillingType": "notApplicable" } } ], "warnings": [], "errors": [] } ``` *** ## Add Campaigns to a Balance This endpoint adds one or more campaigns to a balance. It validates that campaigns are retailer-native when the balance is retailer-budget. ```http theme={null} https://api.criteo.com/2026-01/retail-media/balances/{balanceId}/campaigns/append ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/balances/814886589256347648/campaigns/append' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "ids": ["718038552188952576", "234105251251242423"] }, "type": "AppendCampaignsRequest" } }' ``` **Sample Response** ```json theme={null} { "data": { "attributes": { "ids": ["718038552188952576", "234105251251242423"] }, "type": "BalanceCampaignsV1" }, "warnings": [], "errors": [] } ``` **Sample Response — Error (non-retailer-native campaign)** ```json theme={null} { "errors": [ { "message": "Only retailer-sold campaigns are allowed to be mapped to a retailer-budget balance.", "status": 400 } ] } ``` *** ## Remove Campaign(s) from a Balance This endpoint removes one or more campaigns from a balance. ```http theme={null} https://api.criteo.com/2026-01/retail-media/balances/{balanceId}/campaigns/delete ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/balances/814886589256347648/campaigns/delete' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "attributes": { "ids": ["234105251251242423"] }, "type": "DeleteCampaignsRequest" } }' ``` **Sample Response** ```json theme={null} { "data": { "attributes": { "ids": ["718038552188952576"] }, "type": "BalanceCampaignsV1" }, "warnings": [], "errors": [] } ``` *** ## Create New Campaigns This endpoint creates a new campaign. For retailer-budgets campaigns, `retailerId` is required and must match the `retailerId` on the drawable balance. ```http theme={null} https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/campaigns ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/campaigns' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "Campaign", "attributes": { "name": "Retailer Budgets Campaign Q2", "startDate": "2026-07-01T00:00:00+00:00", "clickAttributionWindow": "30D", "viewAttributionWindow": "None", "retailerId": "1298", "drawableBalanceIds": ["814886589256347648"] } } }' ``` **Sample Response** ```json theme={null} { "data": { "id": "718038552188952576", "type": "Campaign", "attributes": { "name": "Retailer Budgets Campaign Q2", "accountId": "625702934721171442", "type": "auction", "status": "inactive", "retailerId": "1298", "drawableBalanceIds": ["814886589256347648"], "budget": null, "budgetSpent": 0.0, "budgetRemaining": null, "startDate": "2026-07-01T00:00:00+00:00", "endDate": null, "clickAttributionWindow": "30D", "viewAttributionWindow": "None", "createdAt": "2026-05-08T00:00:00+00:00", "updatedAt": "2026-05-08T00:00:00+00:00" } } } ``` *** ## Get Campaigns by Account ID and Campaign ID Both endpoints now return `retailerId` in the campaign attributes. The list endpoint supports filtering by `retailerId`. ```http theme={null} https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/campaigns?pageIndex=0&pageSize=25 ``` ```http theme={null} https://api.criteo.com/2026-01/retail-media/campaigns/{campaignId} ``` **Sample Request — Get a Single Campaign** ```bash theme={null} curl -L -X GET 'https://api.criteo.com/2026-01/retail-media/campaigns/718038552188952576' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json theme={null} { "data": { "id": "718038552188952576", "type": "Campaign", "attributes": { "name": "Retailer Budgets Campaign Q2", "accountId": "625702934721171442", "type": "auction", "status": "active", "retailerId": "1298", "drawableBalanceIds": ["814886589256347648"], "budget": null, "budgetSpent": 1250.00, "budgetRemaining": null, "startDate": "2026-07-01T00:00:00+00:00", "endDate": null, "clickAttributionWindow": "30D", "viewAttributionWindow": "None", "createdAt": "2026-05-08T00:00:00+00:00", "updatedAt": "2026-07-01T00:00:00+00:00" } } } ``` *** ## Create an Auction Line Item Creates an auction line item. For retailer-budgets campaigns, `targetRetailerId` is required and must match the campaign's `retailerId`. Only one retailer is allowed per retailer-billed campaign. ```http theme={null} https://api.criteo.com/2026-01/retail-media/campaigns/{campaignId}/auction-line-items ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/campaigns/718038552188952576/auction-line-items' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "SponsoredProductsLineItem", "attributes": { "name": "Retailer Budget Line Item", "targetRetailerId": "1298", "startDate": "2026-07-01", "bidStrategy": "automated", "optimizationStrategy": "conversion", "keywordStrategy": "genericAndBranded" } } }' ``` **Sample Response** ```json theme={null} { "data": { "id": "234105251251242423", "type": "SponsoredProductsLineItem", "attributes": { "name": "Retailer Budget Line Item", "campaignId": "718038552188952576", "targetRetailerId": "1298", "startDate": "2026-07-01T00:00:00+00:00", "endDate": null, "status": "inactive", "budget": null, "budgetSpent": 0.0, "budgetRemaining": null, "targetBid": 0.3, "maxBid": null, "monthlyPacing": null, "dailyPacing": null, "isAutoDailyPacing": false, "bidStrategy": "automated", "optimizationStrategy": "conversion", "keywordStrategy": "genericAndBranded", "flightSchedule": null, "createdAt": "2026-05-08T00:00:00+00:00", "updatedAt": "2026-05-08T00:00:00+00:00" } }, "warnings": [], "errors": [] } ``` **Sample Response — Error (retailer mismatch)** ```json theme={null} { "errors": [ { "message": "The line item targetRetailerId must match the campaign retailerId.", "status": 400 } ] } ``` *** ## Search Retailer for an Account This endpoint allows searching for available retailers for an account. The `campaignAvailabilities` object now includes `budgetModel`, allowing platforms to determine which budget models are supported at a given retailer before creating a campaign. ```http theme={null} https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/retailers/search ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/retailers/search' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{}' ``` **Sample Response** ```json theme={null} { "data": [ { "id": "retailer-789", "type": "Retailer", "attributes": { "name": "Example Retailer", "campaignAvailabilities": [ { "buyType": "auction", "campaignType": "sponsoredProducts", "isAvailable": true, "budgetModel": "retailerBilled", "validCombinations": [ { "pageType": "search", "pageEnvironmentType": "offsite" } ] } ] } } ] } ``` *** # Responses

Response

Title

Detail

Troubleshooting

🟢 200

Success

Request executed successfully.

🔴 400

Retailer-budget balance mapping

"Only retailer-sold campaigns are allowed to be mapped to a retailer-billed balance."

Only campaigns scoped to the same retailer as the balance can be appended via /campaigns/append .

🔴 400

RetailerMismatchWithBalance

Campaign retailerId does not match the balance retailerId .

Ensure the retailerId in campaign settings matches the retailerId on the balance you are associating.

🔴 400

RetailerMismatchWithCampaign

Line item targetRetailerId does not match the campaign retailerId .

Ensure targetRetailerId on the line item matches the retailerId set on the parent campaign.

🔴 400

Error deserializing request

A required field is missing or has an invalid value.

Review the request body against the attributes table above.

🔴 403

Unauthorized

Verify your access token and that your account has access to the retailer in question.

# Retailer Search Source: https://developers.criteo.com/retail-media/docs/retailer-search ## Introduction A retailer offers a selection of products from multiple brands.\ Retailers act as publishers, providing advertising inventory for brands to promote their products. An account can have access to one or more retailers, with this access typically managed by Criteo. A retailer typically allows multiples types of pages to be targeted. A **page** is an inventory that can be targeted by [Campaigns](/retail-media/docs/campaign) and [Line Items](/retail-media/docs/line-items) with specific configurations. *** ## Endpoints

Method

Endpoint

Description

POST

/accounts/\{accountId}/retailers/search

Search for Retailers associated with specific account

*** ## Retailer Attributes

Attribute

Data Type

Description

id

string

Retailer ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

name

string

Retailer name, arbitrary and defined during Retailer integration phase

Accepted values: up to 100-chars string

Writeable? Y / Nullable? N

campaignAvailabilities

list

Set of retail media capabilities available for the specific Retailer, separated by the different campaignType x buyType pairs. It's dependent on their current technical integration and other business conditions

Accepted values: see table below

Writeable? N / Nullable? N

*** ## Retailer Campaign Availability Attributes

Attribute

Data Type

Description

campaignType

enum

Campaign type that the following attributes are available for

Accepted values: onsiteDisplay , sponsoredProducts , offsite (case-insensitive)

Writeable? N / Nullable? N

buyType

enum

Buy type for the ad impressions of the campaign, that the following attributes are available for

Accepted values: auction , preferredDeals , sponsorship , offsite (case-insensitive)

Writeable? N / Nullable? N

budgetModelAvailabilities

array

Budget models available for this buyType x campaignType combination at this retailer. Presence of a value indicates that budget model is available; an empty array means the combination is not available.

Values: criteoBudget , retailerBudget , unknown . Learn more about Retailer Budget here.

Writeable? N / Nullable? Y

validCombinations

list

List of page type and environment where the campaign type & buy type are available to deliver ad impressions

Accepted values: list of pageType x pageEnvironmentType pairs (see below)

Writeable? N / Nullable? N

pageTypes

\

Page type available in the current integration of the associated Retailer

Accepted values: case-insensitive values of

  • home
  • search
  • category
  • productDetail
  • merchandising
  • deals
  • favorites
  • searchbar
  • categoryMenu
  • checkout
  • confirmation
  • aiAssistant

Writeable? N / Nullable? N

pageEnvironmentType

\

Environment where the page type is available in the associated Retailer integration

Accepted values: case-insensitive values of

  • web
  • mobile
  • app
  • lockout
  • mixed
  • android
  • ios

Writeable? N / Nullable? N

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Search for Retailers This endpoint searches for retailers associated with the respective account and retrieves a set of retail media capabilities, allowing the user to set up campaigns accordingly. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to `0` and `5`, respectively. See [API Response](/criteo-apis/docs/api-response#pagination). If the limit above is not respected, a dedicated error `400` with `Model validation error` will return. ```http theme={null} https://api.criteo.com/{version}/retail-media/accounts/{accountId}/retailers/search ``` **Search Attributes**

Attribute

Data Type

Description

retailerIdFilter

list

Optional list of Retailer IDs, generated internally by Criteo, to retrieve retail media capabilities from

Accepted values: list of integers, empty list or null Writeable? N / Nullable? Y

**Sample Request** ```bash cURL theme={null} curl -X POST "https://api.criteo.com/{version}/retail-media/accounts/18446744073709551616/retailers/search?offset=0&limit=5" \ -H 'Accept: application/json' \ -H "Authorization: Bearer " \ -H 'Content-Type: application/json' \ -d '{ "data": { "attributes": { "retailerIdFilter": [ 12345 ] } } }' ``` ```python Python theme={null} import requests import json url = "https://api.criteo.com/preview/retail-media/accounts/18446744073709551616/retailers/search?offset=0&limit=5" payload = json.dumps({ "data": { "attributes": { "retailerIdFilter": [ 12345 ] } } }) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer ' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\"data\":{\"attributes\":{\"retailerIdFilter\":[12345]}}}"); Request request = new Request.Builder() .url("https://api.criteo.com/preview/retail-media/accounts/18446744073709551616/retailers/search?offset=0&limit=5") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .addHeader("Authorization", "Bearer ") .build(); Response response = client.newCall(request).execute(); ``` ```php PHP theme={null} setUrl('https://api.criteo.com/preview/retail-media/accounts/18446744073709551616/retailers/search?offset=0&limit=5'); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setConfig(array( 'follow_redirects' => TRUE )); $request->setHeader(array( 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer ' )); $request->setBody('{"data": {"attributes": {"retailerIdFilter": [12345]}}}'); try { $response = $request->send(); if ($response->getStatus() == 200) { echo $response->getBody(); } else { echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' . $response->getReasonPhrase(); } } catch(HTTP_Request2_Exception $e) { echo 'Error: ' . $e->getMessage(); } ``` **Sample Response** ```json expandable theme={null} { "metadata": { "count": 1, "offset": 0, "limit": 5 }, "data": [ { "id": "299", "type": "RetailerResult", "attributes": { "name": "Retailer 1234", "campaignAvailabilities": [ { "campaignType": "onsiteDisplay", "buyType": "auction", "budgetModelAvailabilities": ["retailerBudget"], "validCombinations": [ { "pageType": "home", "pageEnvironmentType": "web" }, { "pageType": "home", "pageEnvironmentType": "ios" }, { "pageType": "search", "pageEnvironmentType": "web" }, { "pageType": "category", "pageEnvironmentType": "web" }, { "pageType": "productDetail", "pageEnvironmentType": "web" }, // ... { "pageType": "confirmation", "pageEnvironmentType": "web" } ] }, { "campaignType": "onsiteDisplay", "buyType": "preferredDeals", "budgetModelAvailabilities": ["retailerBudget"], "validCombinations": [ { "pageType": "home", "pageEnvironmentType": "web" }, // ... { "pageType": "confirmation", "pageEnvironmentType": "web" } ] }, { "campaignType": "onsiteDisplay", "buyType": "sponsorship", "budgetModelAvailabilities": [], "validCombinations": [] }, { "campaignType": "sponsoredProducts", "buyType": "auction", "budgetModelAvailabilities": ["retailerBudget"], "validCombinations": [ { "pageType": "home", "pageEnvironmentType": "web" }, // ... { "pageType": "confirmation", "pageEnvironmentType": "web" } ] }, { "campaignType": "sponsoredProducts", "buyType": "sponsorship", "budgetModelAvailabilities": ["retailerBudget"], "validCombinations": [ { "pageType": "home", "pageEnvironmentType": "web" }, // ... { "pageType": "confirmation", "pageEnvironmentType": "web" } ] }, { "campaignType": "offsite", "buyType": "offsite", "budgetModelAvailabilities": [], "validCombinations": [] } ] } } ], "warnings": [], "errors": [] } ``` *** ## Responses

Response

Description

🟢

200

Call executed with success

🔴 400

"*Model validation error: The field limit must be between 1 and 10*". This indicates that the endpoint above was invoked requesting more than 10 retailers, which is not possible. Define a limit up to 10 and use different offset values to navigate through the different result pages.

🔴 403

API user does not have the authorization to make requests to the account ID. For an authorization request, follow the authorization request steps

# Revenue Report Source: https://developers.criteo.com/retail-media/docs/revenue-report-ssp Supply Side Revenue Report (v2) ## Introduction The revenue report serves as a vital tool for supply account owners, such as retailers, enabling them to understand the origins of their retail media revenue. It offers comprehensive visibility across all advertisers, media platforms, and sales channels, encompassing direct, indirect, and private market avenues. This report delves into crucial aspects, including generated revenue, delivered impressions, clicks, average rates, and overall performance metrics. Through this API only, supply partners gain the ability to construct detailed reports by accessing several metrics and dimensions. *** ## Default Settings When a retailer wants to view their default settings (as used in the user interface), we suggest constructing their API request or data call using the same default parameters as in the UI. For Onsite Sponsored Products: * `clickAttributionWindow`: 30D * `clickMatchLevel`: `sameCategory` * `viewAttributionWindow`: 1D * `viewMatchLevel`: `sameSku` For Onsite Display: * `clickAttributionWindow`: 14D * `clickMatchLevel`: `sameCategory` * `viewAttributionWindow`: 14D * `viewMatchLevel`: `sameCategory` For more information on the report, please visit the [Criteo Help Center.](https://help.retailmedia.criteo.com/kb/guide/en/supply-side-dashboard-kAQBtSzLkH/Steps/3155149) *** ## Endpoints The report generation uses an **asynchronous endpoint** that is used to receive the report creation request (using a `POST` request). Then, using the report `id` generated, it's possible to check the report status and to download the output results using the following `GET` endpoint requests.

Verb

Endpoint

Description

POST

/reports/revenue

Request a retailer revenue report creation

GET

/reports/\{reportId}/status

Get status of a specific report

GET

/reports/\{reportId}/output

Download output of a specific report

*** ## Attributes

Attribute

Data Type

Description

id

string

Supply Account ID to pull results for

Note: for apps with access to multiple supply accounts, it is also possible to use an ids array for multiple IDs, allowing to pull results across multiple accounts. e.g.

"ids":\["supplyAccountId\_1","supplyAccountId\_2"]

Accepted values: int64

Writable? N / Nullable? N

reportType

enum

Report types are pre-packaged reports that allow the specification of the report breakdown. They enable reports to view revenue distribution by advertiser, brand, environment, page category, and page type. The metrics and dimensions in these report types are limited.

Use the metrics and dimensions arrays to build your report for additional fields.

*Note: when metrics and dimensions are used, the report type is ignored.*

Accepted values: advertiser , brand , environment , productCategory , pageType

Writable? N / Nullable? Y

revenueType

enum

The revenue type used to filter report results.

If the revenue type filter is not specified, the report will return all existing revenue data for sponsored products and preferred deals within the specified timeframe.

Accepted values: auction , preferred

Writable? N / Nullable? Y

soldBy

enum

The sales channel of indirect sold, direct sold, or private market. This is an optional filter that can be used to narrow down results.

Accepted values: directSold , indirectSold , privateMarket , authorizedBuyer

Writable? N / Nullable? Y

budgetModels

array

Filter on the budget model. Optional.

Accepted values: CriteoBudget , RetailerBudget

Writable? N / Nullable? Y

activationPlatforms

array

Filter on the activation platform. Optional.

Accepted values: CommerceMax , PrivateMarket

Writable? N / Nullable? Y

buyType

enum

The campaign buying strategy. This optional filter can be used to filter down results

Accepted values: auction , preferredDeals , sponsorship

Writable? N / Nullable? Y

format

enum

The format type the report should return results

Accepted values: json , json-compact , json-newline , csv

Writable? N / Nullable? N

campaignType

enum

The campaign type to filter results

Accepted values: all , sponsoredProducts , onSiteDisplays

Default: all

Writable? N / Nullable? N

salesChannel

enum

The sales channel where attributed sales originated

Accepted values: all , online , offline

Default: all

Writable? N / Nullable? N

advertiserTypes

list

The advertiser type where campaigns originated from

Accepted values: retailer , brand , seller

Writable? N / Nullable? N

clickAttributionWindow

enum

The post-click attribution window, defined as the maximum number of days considered between a click and a conversion for attribution; conversions are attributed to the date of conversion, not the date of click.

Accepted values: none , 7D , 14D , 30D

Default: if omitted, defaults to Campaign settings; must be specified if viewAttributionWindow is one of the accepted values

Writable? N / Nullable? Y

viewAttributionWindow

enum

The post-view attribution window, defined as the maximum number of days considered between an impression and a conversion for attribution; conversions are attributed to the date of conversion, not the date of impression.

Accepted values: none , 1D , 7D , 14D , 30D

Default: if omitted, defaults to Campaign settings; must be less than or equal to clickAttributionWindow ; must be specified if clickAttributionWindow is one of the accepted values

Writable? N / Nullable? Y

dimensions

list

An array of strings used to define which dimensions to see in the report

Accepted values: refer to Metrics and Dimensions for the complete list of supported dimensions

Writable? N / Nullable? Y

clickMatchLevel

string

The attribution configuration modal allows users to retrieve data based on the specified product match for click events.

The order of product match relationships from farthest to closest is sameBrand \< sameCategory \< sameSku . The sameBrand product match value is inclusive of sameCategory and sameSku attribution. The sameCategory value is inclusive of sameSku attribution. Only one value should be used.

*This is not a filter that excludes events. Rather, it calculates attribution using the provided SKU match level.*

Accepted values: sameSku , sameCategory , sameBrand , campaign

Default: if omitted, defaults to Campaign settings

Writable? N / Nullable? Y

viewMatchLevel

string

The attribution configuration modal allows users to retrieve data based on the specified product match for view events.

The order of product match relationships from farthest to closest is sameBrand \< sameCategory \< sameSku . The sameBrand product match value is inclusive of sameCategory and sameSku attribution. The sameCategory value is inclusive of sameSku attribution. Only one value should be used.

*This is not a filter that excludes events. Rather, it calculates attribution using the provided SKU match level.*

Accepted values: sameSku , sameCategory , sameBrand , campaign

Default: if omitted, defaults to Campaign settings

Writable? N / Nullable? Y

skuRelations

(DEPRECATED)

string

The attributed rule used to match an impression/click to a sale. The filter will narrow down results of the attributed rules set by the advertiser at the campaign level.

Accepted Values: sameSku , sameParentSku , sameCategory , sameBrand , sameSeller

Writable? N / Nullable? Y

⚠️ Note : This filter is deprecated . Please use clickMatchLevel and viewMatchLevel instead. However, the skuRelations dimension can still be used.

metrics

list

An array of strings used to define which metrics to see in the report.

Accepted values: refer to Metrics and Dimensions for the complete list of supported metrics

Writable? N / Nullable? Y

startDate

timestamp

Start date of the report (inclusive)

Accepted values: yyyy-mm-ddThh:mm:ss (in ISO-8601 )

Writable? N / Nullable? N

endDate

timestamp

End date of the report (inclusive)

Accepted values: yyyy-mm-ddThh:mm:ss (in ISO-8601 )

Writable? N / Nullable? N

timezone

string

Time zone to consider in the metrics calculation, startDate and endDate

Accepted values: IANA (TZ database) time zones (example: America/New\_York , Europe/Paris , Asia/Tokyo , UTC )

Default: UTC

Writable? N / Nullable? Y

accountIds

string

Gives the ability for the user to filter by account IDs.

*There are currently no limitations to the amount of IDs that can be added to the filter.*

campaignIds

string

Gives the ability for the user to filter by campaign IDs.

*There are currently no limitations to the amount of IDs that can be added to the filter.*

lineItemIds

string

Gives the ability for the user to filter by line item IDs.

*There are currently no limitations to the amount of IDs that can be added to the filter.*

retailerIds

string

Gives the ability for the user to filter their reporting by retailer ID(s).

**Metrics and Dimensions** For a complete list of all supported metrics and dimension, check out the [Metrics and Dimensions](/retail-media/docs/metrics-and-dimensions-ssp) When utilizing the `clickMatchLevel` and `viewMatchLevel` fields, we recommend including the `attributionSettings`, `activityType`, and `skuRelation`. This will assist in gaining a clearer understanding of the click and view events, categorized by their attribution windows and SKU relationships. *** ## Generate Revenue Report ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/revenue ``` ### Sample Request ```bash curl expandable theme={null} curl -L 'https://api.criteo.com/{version}/retail-media/reports/revenue' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "SSPRevenueReport", "attributes": { "id": "203209148566716416", "revenueType": "auction", "soldBy": "directSold", "buyType": "auction", "skuRelations": [ "sameSku" ], "format": "json", "campaignType": "sponsoredProducts", "salesChannel": "online", "clickAttributionWindow": "7D", "viewAttributionWindow": "1D", "clickMatchLevel": "sameCategory", "viewMatchLevel": "sameSKU", "dimensions": [ "date", "hour", "advertiserType", "accountName", "campaignName", "activityType", "advProductId", "advProductName", "placementName", "taxonomy1Name", "taxonomy2Name", "taxonomy3Name" ], "metrics": [ "numberOfCampaigns", "numberOfSkus", "clicks", "units", "ctr", "cr", "workingMedia", "netRevenue" ], "startDate": "2024-04-10T21:14:53.816Z", "endDate": "2024-04-10T21:14:53.816Z", "timezone": "UTC" } } } }' ``` ### Sample Response ```json JSON theme={null} { "data": { "type": "RetailMediaReportStatus", "id": "22fa642d-ab8a-463c-a2f6-fb174c2f72dd", "attributes": { "status": "pending", "rowCount": null, "fileSizeBytes": null, "md5Checksum": null, "createdAt": null, "expiresAt": null, "message": null } } } ``` *** ## Get status of specific report ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/{reportId}/status ``` ### Sample Request ```bash CURL theme={null} curl -L 'https://api.criteo.com/{version}/retail-media/reports/22fa642d-ab8a-463c-a2f6-fb174c2f72dd/status' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` ### Sample Response ```json theme={null} { "data": { "type": "RetailMediaReportStatus", "id": "22fa642d-ab8a-463c-a2f6-fb174c2f72dd", "attributes": { "status": "success", "rowCount": 2, "fileSizeBytes": 341, "md5Checksum": "f43cf2503a31a100f7b81db3c14d3fae", "createdAt": "2023-07-10T16:00:32.000Z", "expiresAt": "2023-07-17T16:00:32.000Z", "message": null } } } ``` *** ## Download Output of a Specific Report ```http theme={null} https://api.criteo.com/{version}/retail-media/reports/{reportId}/output ``` ### Sample Request ```bash theme={null} curl -X GET "https://api.criteo.com/{version}/retail-media/reports/2e733b8c-9983-4237-aab9-17a42f426xx/output" \ -H "Authorization: Bearer " ``` ### Sample Responses *Report broken down by advertiser by JSON format* ```json expandable theme={null} [ { "date": "2024-04-10", "hour": 15, "advertiserType":"seller", "accountName": "Account A", "campaignName": "CampaignABC", "placementName": "viewSearchResult", "activityType": "imp", "advProductId": "14364409", "advProductName": "360 Deluxe (PC/Mac) - 5 Devices", "taxonomy1Name": "computers & tablets", "taxonomy2Name": "software", "taxonomy3Name": "antivirus, security & utility software", "numberOfCampaigns": 1, "numberOfSkus": 1, "clicks": 0, "units": 1, "ctr": null, "cr": null, "workingMedia": 0, "netRevenue": 0 }, { "date": "2024-04-10", "hour": 11, "advertiserType":"brand", "accountName": "Account A", "campaignName": "CampaignXYZ", "placementName": "viewSearchResult", "activityType": "click", "advProductId": "15325425", "advProductName": "Mini On-Ear Bluetooth Kids Headphones - Pink", "taxonomy1Name": "audio", "taxonomy2Name": "headphones", "taxonomy3Name": "over-ear headphones", "numberOfCampaigns": 1, "numberOfSkus": 1, "clicks": 0, "units": 1, "ctr": null, "cr": null, "workingMedia": 0, "netRevenue": 0 }, { "date": "2024-04-10", "hour": 10, "advertiserType":"seller", "accountName": "Account B", "campaignName": "CampaignDEF", "placementName": "viewItem_API", "activityType": "imp", "advProductId": "17701444", "advProductName": "City Pro Electric Scooter", "taxonomy1Name": "sports, recreation & transportation", "taxonomy2Name": "electric transportation", "taxonomy3Name": "electric scooters", "numberOfCampaigns": 1, "numberOfSkus": 1, "clicks": 0, "units": 1, "ctr": null, "cr": null, "workingMedia": 0, "netRevenue": 0 } ] ``` *** ## Responses

Response

Description

🔵 200

Call executed with success

🔴 400

Common Validation Errors:

  • endDate cannot be more than 100 days from startDate * Using a date range with more than 100 days apart
  • reportType invalid * calling an unsupported report type will throw a 400 error
  • timeZone must be a valid timezone * using a time zone value that is not listed in the list tz database time zones
  • format invalid * using an unsupported file format
***
## What's next * [Metrics and Dimensions (SSP)](/retail-media/docs/metrics-and-dimensions-ssp) # Sellers Source: https://developers.criteo.com/retail-media/docs/sellers ## Introduction A seller represents an external entity that sells products in the retailers' environment (marketplace). Sellers entities are, initially, available through retailers' catalogs and can aggregate different products offered by them in the retailer marketplace. A demand account can be associated with multiple sellers (across multiple retailers) and be willing to serve ads across them. This endpoint provides a programmatic way to identify all sellers (and, consequently, retailers) associated with the respective account, so that campaigns can be set up accordingly. *** ## Endpoints

Verb

Endpoint

Description

POST

/accounts/sellers/search

Search for Sellers, associated with retailers, given an account ID

*** ## Sellers Accounts Search Attributes

Attribute

Data Type

Description

accountId \*

string

Account ID, to consider in the search for Seller accounts

Accepted values: int64

Writeable? N / Nullable? N

includeDetails

boolean

Flag indicating to include accounts' details in the response, such as name .

It may improve performance when set to false

Accepted values: true / false

Default: false

Writeable? N / Nullable? Y

sellerId

string

Seller ID, specific to the associated Retailer

Accepted values: int64

Writeable? N / Nullable? N

retailerId

integer

Retailer ID which the seller account is associated with

Accepted values: int32

Writeable? N / Nullable? N

name

string

Seller name

Accepted values: string

Writeable? N / Nullable? Y

*\* Required* *** ## Search for Sellers associated with Account This endpoint returns a list of Seller IDs (each associated with a different retailer) available for the given account ID: **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/sellers/search' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "", "attributes": { "accountIds": [ "100000002342852933" ], "includeDetails": false } } }' ``` **Sample Response** ```json theme={null} { "data": [ { "type": "SellerSearchResult", "attributes": { "accountId": "100000002342852933", "sellers": [ { "sellerId": "xxxxxxxxxxxxxxxxxxxxxxxx", "retailerId": 123, "name": null } ] } } ], "warnings": [], "errors": [] } ``` *** ## Responses

Response

Error

Message

Description

🟢 200

Call completed successfully

🔴 400

Validation Error

Error deserializing request

One of the parameters provided in the request does not match the format accepted. Check the error details and the parameters informed in the call

🔴 403

Authorization Error

Resource access forbidden: does not have permissions

API user does not have the authorization to make requests to the account ID. For an authorization request, follow the authorization request steps

***
## What's next * [Retailers](/retail-media/v2025.07/docs/retailers) # Store Inventory Source: https://developers.criteo.com/retail-media/docs/store-inventory Manage product availability and pricing at the store level using the Store Inventory API ## Introduction **Store Inventory** enables retailers to manage product availability and pricing at the store level, supporting accurate PDP/ad experiences. Inventory events (upserts and deletes) are sent in batches, enabling real-time updates for price and availability per store. This API is **event-driven** and **multi-tenant**. You can also find the Store Inventory endpoints in our API Reference for [`upsert`](/retail-media/reference/catalog/upsert-store-inventory-per-merchant-id) and [`delete`](/retail-media/reference/catalog/delete-store-inventory-per-merchant-id). *** ## URLs * For AMERICAS: [api.us.criteo.com](https://api.us.criteo.com) * For APAC: [api.as.criteo.com](https://api.as.criteo.com) * For EMEA: [api.eu.criteo.com](https://api.eu.criteo.com) *** ## Endpoints

Verb

Endpoint

Description

POST

/\{version}/retail-media/catalog/merchants/\{merchantId}/store-inventory/upsert

Insert or update store(s)

POST

/\{version}/retail-media/catalog/merchants/\{merchantId}/store-inventory/delete

Delete store(s)

*** ## Store Inventory Attributes

Attribute

Data Type

Description

merchantId \*

integer

The ID of the managing account.

Criteo: the partnerId

Accepted values: integer (int32)

Writeable? N / Nullable? N

batchId \*

string

Identifies this event. Should be unique for a given endpoint call.

Writeable? Y / Nullable? N

productId \*

string

Identifies a product

Accepted values: up to 50 chars string

Writeable? Y / Nullable? N

storeId \*

string

Identifies the store for the customer.

Accepted values: up to 64 chars string

Writeable? Y / Nullable? N

availability \*

string

Accepted values: in\_stock , out\_of\_stock , preorder , backorder

Writeable? Y / Nullable? N

price \*

string

Product's price at this store

Accepted values: up to 14 chars string

Writeable? Y / Nullable? N

salePrice

string

The sale price of the product

Accepted values: up to 14 chars string

Writeable? Y / Nullable? Y

(\*) Required **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `merchantId`, `batchId`, `productId`) and are usually required in the URL path. *** ## Upsert Store Inventory Send a batch of inventory upsert events for a merchant. **Use case**: Insert or update store-level inventory (price, availability) for one or more products. ```http theme={null} https://api.criteo.com/{version}/retail-media/catalog/merchants/{merchantId}/store-inventory/upsert ``` ### Sample Request ```json theme={null} { "data": [ { "type": "Upsert", "attributes": { "batchId": "batch1", "productId": "product1", "storeId": "store1", "availability": "in_stock", "price": "19.99", "salePrice": "10.99" } }, { "type": "Upsert", "attributes": { "batchId": "batch2", "productId": "product2", "storeId": "store2", "availability": "out_of_stock", "price": "29.99" } } ] } ``` ### Sample Response ```json theme={null} HTTP STATUS 204 (No Content) <EMPTY PAYLOAD> ``` *** ## Delete Store Inventory Send a batch of inventory delete events for a merchant. **Use case**: Remove outdated or unavailable inventory records. ```http theme={null} https://api.criteo.com/{version}/retail-media/catalog/merchants/{merchantId}/store-inventory/delete ``` ### Sample Request ```json theme={null} { "data": [ { "type": "Delete", "attributes": { "batchId": "batch1", "productId": "product1", "storeId": "store1" } }, { "type": "Delete", "attributes": { "batchId": "batch2", "productId": "product2", "storeId": "store2" } } ] } ``` ### Sample Response ```json theme={null} HTTP STATUS 204 (No Content) <EMPTY PAYLOAD> ``` *** ## Error Codes

Error code

Error text

Description

400

Bad request

Validation errors, required fields, unique batchId / productId / storeCode

400

Request too large

Payload exceeds 1000 events

401

Unauthorized

Authentication required

403

Forbidden

Not authorized

429

Too Many Requests

Rate limiting

500

Internal Error

Server error

503

Service Unavailable

Service temporarily unavailable

# Supply Side Analytics (SSP) Source: https://developers.criteo.com/retail-media/docs/supply-side-reporting-ssp ## Introduction The Criteo Retail Media Analytics API allows you to scale operations programmatically through our API and integrate Retail Media Platform (RMP) capabilities into your preferred UI or workflow tools. With the Criteo Retail Media API You will be able to download SSP revenue reports. Report attribution windows and time zones are fully customizable. *** ## Quick Start 1. Request a report 2. Poll for report status 3. Upon success, download the report output Learn more about Retailer Support in our [CMax Help Center](https://help.retailmedia.criteo.com/kb/en/retailer-support-133303) ***
## What's next * [Revenue Report](/retail-media/docs/revenue-report-ssp) * [Metrics and Dimensions (SSP)](/retail-media/docs/metrics-and-dimensions-ssp) * [Fill Rate Report](/retail-media/docs/fill-rate-report) * [Reporting Diagnostic Guide](/retail-media/docs/reporting-overview-diagnostic-guide) # Welcome to Criteo Retail Media API Source: https://developers.criteo.com/retail-media/docs/welcome-to-criteo The Criteo Retail Media API helps you unlock a range of possibilities to help you enhance your media performance from any platform. Our suite of tools empowers you to seamlessly create, launch, and monitor your campaigns, providing a comprehensive view of your performance. **New to the Criteo API?** Start with [API Resources](/criteo-apis/docs/overview) — authentication, OAuth setup, rate limits, error codes, versioning policy, and troubleshooting are documented there and apply to all Criteo APIs. ## Criteo API Version Tiers Overview Criteo API versions follow a three-stage lifecycle. Choose the tier that fits your needs — or keep reading to learn what this version offers. **You are here.** Fully supported for 12 months with no breaking changes. The right choice for all production integrations. Production-ready preview of the next stable version. Integrate early and you're already on the right version the moment it goes stable. Early access to brand-new features before they're finalized. Contracts may change — not for production use. For the full version lifecycle — deprecation windows, release schedule, fall-forward — see the [Versioning policy](/criteo-apis/docs/versioning-policy). ## Campaign Management Campaign managed endpoints are designed to meet the diverse needs of our clients and partners.\ Our dynamic Retail Media API allows you to manage and fine-tune all your campaigns with high precision. Create, update, and monitor retail media campaigns and line items through a unified API. Manage budgets, attribution models, and balances programmatically for full setup flexibility. Adjust bids, pacing, and flight dates directly via API endpoints. Query retailer catalogs, select SKUs, and manage keyword targeting at the line-item level. ## Data Insights Access comprehensive campaign performance reports featuring: Access detailed reporting by page type, keyword, product, and category. Analyze attribution performance across all active media channels. Build multi-dimensional reports by combining metrics and dimensions programmatically. # /2026-07/retail-media/account-management/accounts/{accountId}/brands/add Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccount-managementaccounts-brandsadd https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/account-management/accounts/{accountId}/brands/add Add brands to an account # /2026-07/retail-media/account-management/accounts/{accountId}/brands/remove Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccount-managementaccounts-brandsremove https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/account-management/accounts/{accountId}/brands/remove Remove brands from an account # /2026-07/retail-media/account-management/accounts/{accountId}/create-brand-account Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccount-managementaccounts-create-brand-account https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/account-management/accounts/{accountId}/create-brand-account Creates a new child Demand Brand account for the provided parent Private Market account # /2026-07/retail-media/account-management/accounts/{accountId}/create-seller-account Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccount-managementaccounts-create-seller-account https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/account-management/accounts/{accountId}/create-seller-account Creates a new child Demand Seller account for the provided parent Private Market account # /2026-07/retail-media/account-management/accounts/{accountId}/private-market-child-accounts Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccount-managementaccounts-private-market-child-accounts https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/account-management/accounts/{accountId}/private-market-child-accounts Gets Private Market child accounts that are associated with the given account # /2026-07/retail-media/account-management/accounts/{accountId}/sellers Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccount-managementaccounts-sellers https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/account-management/accounts/{accountId}/sellers Replace the sellers associated with an account # /2026-07/retail-media/accounts Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccounts https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts Gets page of account objects that the current user can access # /2026-07/retail-media/accounts/{accountId}/grant-consent Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccounts-grant-consent https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{accountId}/grant-consent Grant consent to a business application on behalf of a Private Market demand account # /2026-07/retail-media/accounts/fees/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccountsfeessearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/fees/search Get fees for provided accounts # /2026-07/retail-media/accounts/fees/update Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccountsfeesupdate https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/fees/update Set fees for provided accounts # /2026-07/retail-media/accounts/sellers/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediaaccountssellerssearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/sellers/search Get the sellers mapped to provided accounts # /2026-07/retail-media/brands/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/accounts/2026-07retail-mediabrandssearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/brands/search Search for brands given a retailer ID and search term. # /2026-07/retail-media/accounts/{account-id}/audience-segments Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaccounts-audience-segments https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json patch /2026-07/retail-media/accounts/{account-id}/audience-segments Updates the properties of all segments with a valid configuration, and returns the full segments. For those that cannot be updated, one or multiple errors are returned. # /2026-07/retail-media/accounts/{account-id}/audience-segments/{audience-segment-id}/contact-list Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaccounts-audience-segments-contact-list https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{account-id}/audience-segments/{audience-segment-id}/contact-list Returns the statistics of a contact list segment. # /2026-07/retail-media/accounts/{account-id}/audience-segments/create Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaccounts-audience-segmentscreate https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/audience-segments/create Creates all segments with a valid configuration, and returns the full segments. For those that cannot be created, one or multiple errors are returned. # /2026-07/retail-media/accounts/{account-id}/audience-segments/delete Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaccounts-audience-segmentsdelete https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/audience-segments/delete Delete the segments associated to the given IDs. # /2026-07/retail-media/accounts/{account-id}/audience-segments/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaccounts-audience-segmentssearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/audience-segments/search Returns a list of segments that match the provided filters. If present, the filters are AND'ed together when applied. # /2026-07/retail-media/accounts/{account-id}/audiences/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaccounts-audiencessearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/audiences/search Returns a list of audiences that match the provided filters. If present, the filters are AND'ed together when applied. # /2026-07/retail-media/audience-segments/{audience-segment-id}/contact-list/add-remove Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaudience-segments-contact-listadd-remove https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/audience-segments/{audience-segment-id}/contact-list/add-remove Add/remove identifiers to or from a retail-media contact list audience-segment, with external audience segment id. # /2026-07/retail-media/audience-segments/{audience-segment-id}/contact-list/clear Source: https://developers.criteo.com/retail-media/v2026.07/reference/audience/2026-07retail-mediaaudience-segments-contact-listclear https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/audience-segments/{audience-segment-id}/contact-list/clear Delete all identifiers from a retail-media contact list audience-segment, with external audience segment id. # /2026-07/retail-media/accounts/{account-id}/balances Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediaaccounts-balances https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/balances Create balance for the given account id # /2026-07/retail-media/accounts/{account-id}/balances/{balance-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediaaccounts-balances-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{account-id}/balances/{balance-id} Get a balance for the given account id and balance id # /2026-07/retail-media/accounts/{account-id}/balances/{balance-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediaaccounts-balances-2 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json patch /2026-07/retail-media/accounts/{account-id}/balances/{balance-id} Modify a balance for the given account id # /2026-07/retail-media/accounts/{accountId}/balances Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediaaccounts-balances-3 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{accountId}/balances Gets page of balance objects for the given account id. # /2026-07/retail-media/accounts/{account-id}/balances/{balance-id}/add-funds Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediaaccounts-balances-add-funds https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/balances/{balance-id}/add-funds Add funds to a balance for the given account id # /2026-07/retail-media/accounts/{account-id}/balances/{balance-id}/change-dates Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediaaccounts-balances-change-dates https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/balances/{balance-id}/change-dates Change dates of a balance for the given account id # /2026-07/retail-media/balances/{balanceId} Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediabalances https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/balances/{balanceId} Get a balance for the given balance id. # /2026-07/retail-media/balances/{balance-id}/campaigns Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediabalances-campaigns https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/balances/{balance-id}/campaigns Gets page of campaigns for the given balanceId # /2026-07/retail-media/balances/{balanceId}/history Source: https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediabalances-history https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/balances/{balanceId}/history Gets the balance's historical change data. # /2026-07/retail-media/accounts/{accountId}/brand-catalog-export Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-brand-catalog-export https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{accountId}/brand-catalog-export Create a request for a Catalog available to the indicated account. # /2026-07/retail-media/accounts/{accountId}/brands Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-brands https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{accountId}/brands Gets page of retailer objects that are associated with the given account # /2026-07/retail-media/accounts/{account-id}/campaigns Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-campaigns https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{account-id}/campaigns Gets page of campaign objects for the given account id # /2026-07/retail-media/accounts/{account-id}/campaigns Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-campaigns-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/campaigns Creates a new campaign with the specified settings # /2026-07/retail-media/accounts/{accountId}/catalogs Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-catalogs https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{accountId}/catalogs Create a request for a Catalog available to the indicated account. # /2026-07/retail-media/accounts/{accountId}/catalogs/sellers Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-catalogssellers https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{accountId}/catalogs/sellers Create a request for a Catalog available to the indicated account. # /2026-07/retail-media/accounts/{account-id}/creatives Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-creatives https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{account-id}/creatives Get account creatives # /2026-07/retail-media/accounts/{account-id}/creatives Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-creatives-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/creatives Create a creative for an account # /2026-07/retail-media/accounts/{account-id}/creatives/{creative-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-creatives-2 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{account-id}/creatives/{creative-id} Get the specified creative # /2026-07/retail-media/accounts/{account-id}/creatives/{creative-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-creatives-3 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/accounts/{account-id}/creatives/{creative-id} Update a creative # /2026-07/retail-media/accounts/{account-id}/creatives/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-creativessearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{account-id}/creatives/search Get account creatives # /2026-07/retail-media/accounts/{account-id}/keywords/in-review-report Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-keywordsin-review-report https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{account-id}/keywords/in-review-report Generate a list of reports for line items which contain one or more actionable keyword reviews # /2026-07/retail-media/accounts/{account-id}/line-items Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-line-items https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/accounts/{account-id}/line-items Gets page of line item objects for the given account id # /2026-07/retail-media/accounts/{accountId}/retailers/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-retailerssearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{accountId}/retailers/search Searches for retailers associated with the specified account and returns budget model availability for each retailer # /2026-07/retail-media/accounts/{accountId}/seller-catalog-export Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaaccounts-seller-catalog-export https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/accounts/{accountId}/seller-catalog-export Create a request for a Catalog available to the indicated account. # /2026-07/retail-media/assets Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaassets https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/assets Creates an asset # /2026-07/retail-media/auction-line-items/{lineItemId} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaauction-line-items https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/auction-line-items/{lineItemId} Gets a sponsored product line item by its id. # /2026-07/retail-media/auction-line-items/{lineItemId} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaauction-line-items-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/auction-line-items/{lineItemId} Updates a Sponsored Products Line Item given a line item id and a request. # /2026-07/retail-media/balances/{balanceId}/campaigns/append Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediabalances-campaignsappend https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/balances/{balanceId}/campaigns/append Appends one or more campaigns to the specified balance # /2026-07/retail-media/balances/{balanceId}/campaigns/delete Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediabalances-campaignsdelete https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/balances/{balanceId}/campaigns/delete Deletes one or more campaigns on the specified balance # /2026-07/retail-media/campaigns/{campaignId} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/campaigns/{campaignId} Gets the campaign for the given campaign id # /2026-07/retail-media/campaigns/{campaignId} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/campaigns/{campaignId} Updates the campaign for the given campaign id # /2026-07/retail-media/campaigns/{campaignId}/auction-line-items Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns-auction-line-items https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/campaigns/{campaignId}/auction-line-items Gets a page of sponsored product line items by campaign id. # /2026-07/retail-media/campaigns/{campaignId}/auction-line-items Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns-auction-line-items-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/campaigns/{campaignId}/auction-line-items Creates new auction line item with the specified settings # /2026-07/retail-media/campaigns/{campaignId}/campaign-budget-overrides Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns-campaign-budget-overrides https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/campaigns/{campaignId}/campaign-budget-overrides Get current campaign budget overrides by given campaign id. # /2026-07/retail-media/campaigns/{campaignId}/campaign-budget-overrides Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns-campaign-budget-overrides-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/campaigns/{campaignId}/campaign-budget-overrides Update campaign budget overrides by given campaign id and new campaign budget overrides settings. # /2026-07/retail-media/campaigns/{campaign-id}/preferred-line-items Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns-preferred-line-items https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/campaigns/{campaign-id}/preferred-line-items Gets page of preferred line item objects for the given campaign id # /2026-07/retail-media/campaigns/{campaign-id}/preferred-line-items Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacampaigns-preferred-line-items-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/campaigns/{campaign-id}/preferred-line-items Creates a new preferred line item with the specified settings # /2026-07/retail-media/catalogs/{catalogId}/output Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacatalogs-output https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/catalogs/{catalogId}/output Output the indicated catalog. Catalogs are only available for retrieval when their associated status request is at a Success status. Produces application/x-json-stream CatalogProduct json objects (first introduced in the 2021-07 version). # /2026-07/retail-media/catalogs/{catalogId}/status Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacatalogs-status https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/catalogs/{catalogId}/status Check the status of a catalog request. # /2026-07/retail-media/categories Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacategories https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/categories Endpoint to search categories by text and retailer. # /2026-07/retail-media/categories/{categoryId} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediacategories-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/categories/{categoryId} Endpoint to search for a specific category by categoryId. # /2026-07/retail-media/line-items/{id}/keywords Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-keywords https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/line-items/{id}/keywords Fetch keywords associated with the specified line item # /2026-07/retail-media/line-items/{id}/keywords/add-remove Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-keywordsadd-remove https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/line-items/{id}/keywords/add-remove Add or Remove keywords from the line item in bulk # /2026-07/retail-media/line-items/{externalLineItemId}/keywords/recommended Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-keywordsrecommended https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/line-items/{externalLineItemId}/keywords/recommended Retrieves a collection of recommended keywords for a line item # /2026-07/retail-media/reports/{reportId}/output Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareports-output https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/reports/{reportId}/output Returns the output of an async report # /2026-07/retail-media/reports/{reportId}/status Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareports-status https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/reports/{reportId}/status Returns the status of an async report # /2026-07/retail-media/reports/attributed-transactions Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportsattributed-transactions https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/attributed-transactions Creates an attributed-transactions async report. The request accepts explicit attributed-transaction dimensions, metrics, and filters.
This endpoint is subject to specific rate limits. # /2026-07/retail-media/reports/fillrate Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportsfillrate https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/fillrate Returns an asynchronous Fill Rate Report
This endpoint is subject to specific rate limits. # /2026-07/retail-media/reports/missed-opportunities Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportsmissed-opportunities https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/missed-opportunities Creates a missed-opportunities async report. The request accepts explicit missed-opportunities dimensions, metrics, and filters.
This endpoint is subject to specific rate limits. # /2026-07/retail-media/reports/performance Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportsperformance https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/performance Creates a performance DSP analytics async report. Dimensions and metrics select the output schema, and filters constrain eligible data.
This endpoint is subject to specific rate limits. # /2026-07/retail-media/reports/revenue Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportsrevenue https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/revenue Returns an asynchronous Revenue Report
This endpoint is subject to specific rate limits. # /2026-07/retail-media/reports/sync/attributed-transactions Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportssyncattributed-transactions https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/sync/attributed-transactions Returns a synchronous Attributed Transactions Report # /2026-07/retail-media/reports/sync/campaigns Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportssynccampaigns https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/sync/campaigns Returns a synchronous Campaigns Report # /2026-07/retail-media/reports/sync/line-items Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportssyncline-items https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/sync/line-items Returns a synchronous Line Items Report # /2026-07/retail-media/reports/sync/real-time-performance Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportssyncreal-time-performance https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/sync/real-time-performance Returns a synchronous Real Time Performance Report. Returns empty rows; metadata includes dataCompleteThrough (latest time from streaming table in the request timezone).
This endpoint is subject to specific rate limits. # /2026-07/retail-media/reports/unfilled-placements Source: https://developers.criteo.com/retail-media/v2026.07/reference/analytics/2026-07retail-mediareportsunfilled-placements https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/reports/unfilled-placements Returns an asynchronous Unfilled Placements Report
This endpoint is subject to specific rate limits. # /2026-07/retail-media/billing/partner-report Source: https://developers.criteo.com/retail-media/v2026.07/reference/billing/2026-07retail-mediabillingpartner-report https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/billing/partner-report Create a Partner Billing Report request. # /2026-07/retail-media/billing/partner-report/{requestId}/output Source: https://developers.criteo.com/retail-media/v2026.07/reference/billing/2026-07retail-mediabillingpartner-report-output https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/billing/partner-report/{requestId}/output Get the output of an existing Partner Billing Report. # /2026-07/retail-media/billing/partner-report/{requestId}/status Source: https://developers.criteo.com/retail-media/v2026.07/reference/billing/2026-07retail-mediabillingpartner-report-status https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/billing/partner-report/{requestId}/status Get the status of an existing Partner Billing Report. # /2026-07/retail-media/line-items/{line-item-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/line-items/{line-item-id} Gets the line item for the given line item id # /2026-07/retail-media/line-items/{line-item-id}/bid-multipliers Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-bid-multipliers https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/line-items/{line-item-id}/bid-multipliers Fetch all bid multipliers for a given line item # /2026-07/retail-media/line-items/{line-item-id}/bid-multipliers Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-bid-multipliers-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/line-items/{line-item-id}/bid-multipliers Updates the bid multipliers for a given line item # /2026-07/retail-media/line-items/{line-item-id}/keywords/review Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-keywordsreview https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/line-items/{line-item-id}/keywords/review Update the status of keyword reviews under a line item # /2026-07/retail-media/line-items/{id}/keywords/set-bid Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-keywordsset-bid https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/line-items/{id}/keywords/set-bid Set bid overrides for associated keywords to the given line item in bulk # /2026-07/retail-media/line-items/{lineItemId}/line-item-budget-overrides Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-line-item-budget-overrides https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/line-items/{lineItemId}/line-item-budget-overrides Gets a collection of monthly and daily budget overrides for the provided line item. # /2026-07/retail-media/line-items/{lineItemId}/line-item-budget-overrides Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-line-item-budget-overrides-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/line-items/{lineItemId}/line-item-budget-overrides Update line item budget overrides by given external line item id and new line item budget overrides settings. # /2026-07/retail-media/line-items/{line-item-id}/products Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-products https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/line-items/{line-item-id}/products Retrieve a page of promoted products for a line item # /2026-07/retail-media/line-items/{line-item-id}/products/append Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-productsappend https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/line-items/{line-item-id}/products/append Append a collection of promoted products to a line item # /2026-07/retail-media/line-items/{line-item-id}/products/delete Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-productsdelete https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/line-items/{line-item-id}/products/delete Remove a collection of promoted products from a line item # /2026-07/retail-media/line-items/{line-item-id}/products/pause Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-productspause https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/line-items/{line-item-id}/products/pause Pause a collection of promoted products associated with a line item # /2026-07/retail-media/line-items/{line-item-id}/products/unpause Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-medialine-items-productsunpause https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/line-items/{line-item-id}/products/unpause Un-pause a collection of promoted products associated with a line item # /2026-07/retail-media/preferred-line-items/{line-item-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/preferred-line-items/{line-item-id} Gets the preferred line item for the given line item id # /2026-07/retail-media/preferred-line-items/{line-item-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/preferred-line-items/{line-item-id} Updates the preferred line item for the given line item id # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingadd-to-basket https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket This endpoint gets the add to basket target on the specified line item. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingadd-to-basket-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket This endpoint sets the scope of the add to basket target on the specified line item. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket/append Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingadd-to-basketappend https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket/append This endpoint appends one or more add to basket ids to targeting on the specified line item. The resulting state of the add to basket target is returned. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket/delete Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingadd-to-basketdelete https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/add-to-basket/delete This endpoint removes one or more add to basket ids from targeting on the specified line item. The resulting state of the add to basket target is returned. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingaudiences https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences This endpoint gets the audience target on the specified line item. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingaudiences-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences This endpoint sets the scope of the audience target on the specified line item. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences/append Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingaudiencesappend https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences/append This endpoint appends one or more audiences ids to targeting on the specified line item. The resulting state of the audience target is returned. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences/delete Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingaudiencesdelete https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/audiences/delete This endpoint removes one or more audiences ids from targeting on the specified line item. The resulting state of the audience target is returned. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingstores https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores This endpoint gets the store target on the specified line item. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingstores-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json put /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores This endpoint sets the scope of the store target on the specified line item. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores/append Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingstoresappend https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores/append This endpoint appends one or more store ids to targeting on the specified line item. The resulting state of the store target is returned. # /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores/delete Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediapreferred-line-items-targetingstoresdelete https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/preferred-line-items/{line-item-id}/targeting/stores/delete This endpoint removes one or more store ids from targeting on the specified line item. The resulting state of the store target is returned. # /2026-07/retail-media/retailers/{retailerId}/categories/search Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaretailers-categoriessearch https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/retailers/{retailerId}/categories/search Search a retailer categories by given text substring and category ids. # /2026-07/retail-media/retailers/{retailerId}/cpc-min-bids Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaretailers-cpc-min-bids https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/retailers/{retailerId}/cpc-min-bids Get overall and individual minimum bid amount for given retailer id and sku id list. # /2026-07/retail-media/retailers/{retailerId}/pages Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaretailers-pages https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/retailers/{retailerId}/pages Get the page types available for the given retailer # /2026-07/retail-media/retailers/{retailerId}/recommend-categories Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaretailers-recommend-categories https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/retailers/{retailerId}/recommend-categories Endpoint to get recommended categories by given retailer id and sku id list. # /2026-07/retail-media/retailers/{retailerId}/recommend-keywords Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaretailers-recommend-keywords https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/retailers/{retailerId}/recommend-keywords Recommend keywords by given retailer id and sku ids. # /2026-07/retail-media/retailers/{retailer-id}/templates Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaretailers-templates https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/retailers/{retailer-id}/templates Get retailer creative templates # /2026-07/retail-media/retailers/{retailer-id}/templates/{template-id} Source: https://developers.criteo.com/retail-media/v2026.07/reference/campaign/2026-07retail-mediaretailers-templates-1 https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/retailers/{retailer-id}/templates/{template-id} Gets the template for the specified retailer id and template id # /2026-07/retail-media/catalog/merchants/{merchantId}/store-inventory/delete Source: https://developers.criteo.com/retail-media/v2026.07/reference/catalog/2026-07retail-mediacatalogmerchants-store-inventorydelete https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/catalog/merchants/{merchantId}/store-inventory/delete Used to publish a batch of store inventories to delete. The batch is processed asynchronously. # /2026-07/retail-media/catalog/merchants/{merchantId}/store-inventory/upsert Source: https://developers.criteo.com/retail-media/v2026.07/reference/catalog/2026-07retail-mediacatalogmerchants-store-inventoryupsert https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json post /2026-07/retail-media/catalog/merchants/{merchantId}/store-inventory/upsert Used to publish a batch of store inventories to upsert. The batch is processed asynchronously. # /2026-07/retail-media/me Source: https://developers.criteo.com/retail-media/v2026.07/reference/gateway/2026-07retail-mediame https://api.criteo.com/2026-07/retailmedia/open-api-specifications.json get /2026-07/retail-media/me Get information about the currently logged application # Ad Set Source: https://developers.criteo.com/marketing-solutions/docs/ad-set Criteo's **Campaign API** allows you to retrieve information about the current configuration of your advertising Ad Sets. This API allows you to **create** adSets, **search** for Ad Sets based on filters, **start and stop** Ad Sets, and **update** your Ad Sets' names, start and end dates, bid amounts, frequency capping, and other targeting controls. ## **Ad Set Example** The following is an example of the JSON data structure of an Ad Set. Additional details about the individual attributes of Ad Sets can be found below. ```json Example Ad Set expandable theme={null} { "data": { "type": "ReadAdSet", "id": "123467", "attributes": { "name": "Campaign A", "advertiserId": "12345", "objective": "conversions", "destinationEnvironment": "app", "mediaType": "Display", "datasetId": "6789", "campaignId": "1485", "schedule": { "startDate": "2018-07-04T00:00:00Z", "endDate": "2018-07-26T00:00:00Z", "activationStatus": "on", "deliveryStatus": "live" }, "bidding": { "bidAmount": 0.9, "costController": "MaxCPC", }, "targeting": { "frequencyCapping": { "frequency": "hourly", "maximumImpressions": 3 }, "geoLocation": { "countries": {"values": ["FR"], "operand": "in"}, "subdivisions": {"values": ["FR-01", "FR-38"], "operand": "notIn"}, "zipCodes": null }, "deliveryLimitations": { "devices": ["mobile", "tablet"], "operatingSystems": ["ios"], "environments": [] } }, "budget": { "budgetStrategy": "capped", "budgetRenewal": "daily", "budgetDeliverySmoothing": "accelerated", "budgetDeliveryWeek": "undefined", "budgetAmount": {"value": 123.45} }, "attributionConfiguration": { "attributionMethod": "criteoAttribution", "lookbackWindow": null } } }, "warnings": [], "errors": [] } ``` ## **Ad Set Attributes** **`name`**\ The Ad Set name, set by the advertiser. **`destinationEnvironment`**\ Read-only. The environment that an ad click will lead a user to. **`objective`**\ The intended optimization for the Ad Set. Can be `customAction`, `clicks`, `conversions`, `displays`, `appPromotion`, `revenue`, `storeConversions`, `value`, `reach`, `visits` or `videoViews` (only when mediaType is set to Video) **`mediaType`**\ The type of media the ad set will deliver on. Can be `Display` or `Video` **`datasetId`**\ Data Set Id associated with the specified advertiser ID. See [Datasets](/marketing-solutions/v2026-preview/docs/datasets) for how to find datasets associated to advertisers. **`campaignId`**\ Id of the marketing campaign associated to the ad set. See [Search for Campaigns](/marketing-solutions/docs/campaign#searching-campaigns) for how to search for campaigns. ### Ad Set Schedule **`schedule.startDate`**\ ISO 8601 format. It must always be earlier than the `schedule.endDate`. It's a mandatory parameter of the Schedule object. This condition applies only if an `endDate` is defined. **`schedule.endDate`**\ ISO 8601 format. `null` by default. (`null` is a valid value.) **`schedule.activationStatus`**\ Can be `on` or `off`. `off` by default. Set by the advertiser, this represents the intent to deliver ads. See [Start and Stop Ad Sets](/marketing-solutions/docs/ad-set#start-an-ad-set) for how to change this value. **`schedule.deliveryStatus`**\ Can be `draft`, `inactive`, `live`, `notLive`, `pausing`, `paused`, `scheduled`, `ended`, `notDelivering`, or `archived`. The initial value for a newly created Ad Set is `draft`. This is a **computed value** and is read-only. **`activationStatus` vs `deliveryStatus`** `deliveryStatus` is a computed value. It is affected by factors other than the value of `activationStatus`, such as budget consumption, start date, and end date. ### Ad Set Bidding **`bidding.bidAmount`**\ Decimal value target relating to the `objective` specified. May be `null` for strategies that do not require a target value. **`bidding.costController`**\ How spend is controlled and optimized. Can be `COS` (Cost of Sale), `MaxCPC` (Cost per Click), `CPI` (Cost per Install), `CPM` (Cost per Mille), `CPO` (Cost per Order), `CPSV` (Cost per Site Visit), `CPV` (Cost per View), `targetCPM` or `dailyBudget`. ### Ad Set Targeting **`targeting.frequencyCapping.maximumImpressions`**\ Integer value. The maximum impressions allowed for the specified `frequencyCapping.frequency`. **`targeting.frequencyCapping.frequency`**\ The period by which the maximum impression limit is calculated. Can be `hourly`, `daily`, or `lifetime`. `advanced` is available for special Criteo-configured setups, but cannot be selected or set manually. **`targeting.geoLocation.countries`**\ Contains an array of `values`, two letter country codes, [ISO-3166 format](https://www.iso.org/iso-3166-country-codes.html). Also specifies an `operand` which can be `in` or `notIn` depending on the desired behavior for the `values`. **`targeting.geoLocation.subdivisions`**\ Contains an array of `values`, geographical subdivisions following [ISO-3166 format](https://www.iso.org/iso-3166-country-codes.html). Also specifies an `operand` which can be `in` or `notIn` depending on the desired behavior for the `values`. **`targeting.geoLocation.zipCodes`**\ Contains an array of `values`, zip codes. Also specifies an `operand` which can be `in` or `notIn` depending on the desired behavior for the `values`. **Geolocation Targeting** Geolocation settings do not support an empty array for their `values`. If a geolocation setting like `geoLocation.countries` is `null`, then the filter is inactive. Otherwise, the filter is active and must have a non-empty list for `values`. **`targeting.deliveryLimitations.devices`**\ List of device types that the Ad Set should target. Can contain `desktop`, `tablet`, `mobile` and `other`. **`targeting.deliveryLimitations.operatingSystems`**\ List of operating systems that the Ad Set should target. Can contain `android`, `ios`, and `other`. **`targeting.deliveryLimitations.environments`**\ List of display environments that the Ad Set should target. Can contain `inApp` and `web`. ### Ad Set Budget **`budget.budgetStrategy`**\ Whether the Ad Set budget is capped or not. Can be `capped` or `uncapped`. This field can be updated via the `PATCH` endpoint. **`budget.budgetRenewal`**\ The cadence of budget renewal. Can be `daily`, `weekly`, `monthly`, `lifetime`, or `undefined`. The value `undefined` is only allowed when `budgetStrategy` is `uncapped`. Capped budgets must use `daily`, `weekly`, `monthly`, or `lifetime`. This field can be updated via the `PATCH` endpoint. **`budget.budgetDeliverySmoothing`**\ Pacing strategy for spending the budget within a renewal period. Only applicable when `budgetStrategy` is `capped`. `accelerated`: spend pacing is based on delivery efficiency rather than the full budget period. `standard`: spread spending evenly over the renewal period. When `budgetStrategy` is `uncapped`, this field is not set (`null` in read responses, omitted in create/patch requests). This field can be updated via the `PATCH` endpoint. **`budget.budgetDeliveryWeek`**\ The seven day period used for weekly budget delivery. Can be `mondayToSunday`, `tuesdayToMonday`, `wednesdayToTuesday`, `thursdayToWednesday`, `fridayToThursday`, `saturdayToFriday`, or `sundayToSaturday`. This field is only applicable when `budgetStrategy` is `capped`, `budgetRenewal` is `weekly`, and `budgetDeliverySmoothing` is `standard`. For non-weekly budgets, this value should be `undefined`. This field can be updated via the `PATCH` endpoint. **`budget.budgetAmount`**\ A decimal value showing the remaining budget value for Ad Sets with `Capped` budget strategies. For uncapped budgets, the value will be `null`. ### Ad Set Attribution Configuration **`attributionConfiguration.attributionMethod`** The attribution method that defines how sales will be attributed to the marketing campaign. Can be `CriteoAttribution`, `GoogleAnalyticsLastClick`, `GoogleAnalyticsDataDriven`, `LastClick`, `PostClick`. **`attributionConfiguration.lookbackWindow`** The lookback window specifies the time frame during which purchases are attributed to an ad interaction. Can be `30M (Same Session)`, `24H`, `7D`, `30D`. It is filled when the `PostClick` or `LastClick` attribution method is selected, or else it should not be filled, and would return an error. ## **Searching Ad Sets** ### Retrieving Ad Sets by Filtering Ad Sets can be retrieved by specifying filters to apply to the set of all Ad Sets in your portfolio. Current available filters are `adSetIds` (which allows you to specify a list of Ad Set IDs to retrieve), `campaignIds` (which allows you retrieve Ad Sets belonging to a list of Campaigns) and `advertiserIds` (which allows you retrieve Ad Sets belonging to a list of Advertisers). For example, to retrieve two existing Ad Sets in your portfolio, filter by `adSetIds`: ```http theme={null} /marketing-solutions/ad-sets/search ``` ```json JSON Payload theme={null} { "filters": { "adSetIds": ["12345", "67890"] } } ``` The API will return an array of Ad Sets that match the provided filters: ```json Sample Response theme={null} { "data": [ { "type": "ReadAdSet", "id": "12345", "attributes": { ... } }, "type": "ReadAdSet", "id": "67890", "attributes": { ... } } ], "errors": [] } ``` The response above is truncated for clarity. Note: the *type* field is the type of entity e.g. ReadAdSet and the *id* field is the unique id of the Adset ### Retrieving All Ad Sets When no filters are specified in the JSON payload, all Ad Sets in your portfolio will be returned, as in the example below: ```http theme={null} /marketing-solutions/ad-sets/search ``` ```json JSON Payload theme={null} { "filters": {} } ``` ### Retrieving One Specific Ad Set You can also fetch the details for a single Ad Set using a GET request: ```http theme={null} /marketing-solutions/ad-sets/{adSetId} ``` The response `data` will be a single object containing the Ad Set details. ```json Sample Response theme={null} { "data": { "type": "ReadAdSet", "id": "12345", "attributes": { ... } }, "errors": [] } ``` ## **Create an Ad Set** A new ad set can be created for a specific advertiser by making a POST call to the ad set endpoint. The request body should specify the type (`Adset`) and the ad set attributes. The following attributes are required to create a new Ad Set: `name`, `campaignId`,`objective`, `datasetId`, `targeting`, `budget`, `schedule`, `bidding` For example, the following call would create a new Ad Set targeting lookalike audiences: ```http theme={null} /marketing-solutions/ad-sets ``` ```json Sample Request Body expandable theme={null} { "data": { "type": "AdSet", "attributes": { "name": "API created Ad Set", "datasetId": "56789", "objective": "conversions", "campaignId": "12789", "mediaType": "Display", "schedule": { "startDate": "2018-07-04T00:00:00Z", "endDate": "2018-07-26T00:00:00Z" }, "bidding": { "bidamount": 0.9, "costcontroller": "MaxCPC" }, "targeting": { "frequencyCapping": { "frequency": "daily", "maximumImpressions": 3 }, "geoLocation": { "countries": { "values": [ "FR" ], "operand": "In" }, "subdivisions": { "values": [ "FR-01", "FR-38" ], "operand": "NotIn" }, "zipCodes": { "values": [], "operand": "NotIn" } }, "deliveryLimitations": { "devices": [ "Mobile", "Tablet" ], "operatingSystems": [ "iOS" ], "environments": [] } }, "budget": { "budgetStrategy": "Capped", "budgetRenewal": "Daily", "budgetDeliverySmoothing": "Accelerated", "budgetDeliveryWeek": "Undefined", "budgetAmount": 123.5 }, "attributionConfiguration": { "attributionMethod": "PostClick", "lookbackWindow": "24H" } } } } ``` The API will return an array of the ID and attributes of the new ad set. The ad set attributes include the name, data set ID, campaign ID, advertiser ID, destination environment, activation status, delivery status, bid strategy and cost controller. If attributionConfiguration is not filled, then a default value of attributionMethod: CriteoAttribution, will be set. ```json theme={null} { "data": { "type": "AdSet", "id": "987634", "attributes": { "name": "API created Ad Set", "objective": "conversions", "datasetId": "56789", "campaignId": "12789", "advertiserId": "456", "destinationEnvironment": "web", "schedule": { "activationStatus": "off", "deliveryStatus": "draft" }, "bidding": { "costController": "MaxCPC" } } }, "errors": [ ], /* omitted if no errors */ "warnings": [ ] /* omitted if no warnings*/ } ``` #### Ad Set General Info At the creation, additional attributes are required: **`trackingCode`**\ Required. Click URL parameters. Query string syntax without "?" (eg. *utm\_source=criteo\&utm\_medium=display\&utm\_campaign=mycampaign*) **Ad Set Audiences** Newly created Ad Sets will not be linked to any audience. To create an audience, refer to the [Create an Audience](/marketing-solutions/docs/audience#create-audiences) guide. You can link existing audiences following the steps in the [Update Ad Set Audience](/marketing-solutions/docs/ad-set#update-adset-audience) guide. ## **Update Ad Sets** The fields of one or more Ad Sets can be updated by making a `PATCH` call to the Ad Sets endpoint. The payload should be an array of partial or whole Ad Sets, each specifying the fields to be modified. For example, the following call would update the `name`, `startDate`, `endDate`, `bidAmount` and frequency capping settings of an existing Ad Set: The bid amount value supports a maximum of 4 decimal digits. If more digits are provided, the amount will be rounded. ```http theme={null} /marketing-solutions/ad-sets ``` ```json Sample Request Body theme={null} { "data": [ { "type": "PatchAdSet", "id": "12345", "attributes": { "name": "Updated Ad Set Name", "scheduling": { "startDate": { "value": "2021-01-19T10:18:28.632Z" }, "endDate": { "value": "2021-01-20T10:18:28.632Z" } }, "bidding": { "bidAmount": { "value": 0.9 } }, "frequencyCapping": { "frequency": "hourly", "maximumImpressions": 12 }, "attributionConfiguration": { "attributionMethod": "LastClick", "lookbackWindow": "30D" } } } ] } ``` The API will return an array of Ad Sets that have been updated successfully in the response `data`. These will contain only two parameters, `type` and `id`. ```json Sample Response theme={null} { "data": [ { "type": "AdSetId", "id": "12345" } ], "errors": [], "warnings": [] } ``` **Ad Set Patch Limit** Note that there is a limit of 50 ad sets per single request. If you are updating more than 50 ad sets, please split them into chunks of 50 and make multiple requests. ### Update AdSet Audience Use this endpoint if you want to link an Audience to an AdSet. Both need to exist beforehand. **Link and Audience, not an Audience Segment** Audiences are made out of Audience Segments, and only Audiences can be linked to AdSets. If you have created an Audience Segment and would like to link it to an existing AdSet, first include it within an Audience, and later use that Audience with this endpoint. ```http theme={null} /marketing-solutions/ad-sets/{ad-set-id}/audience ``` ```json Sample Request Body theme={null} { "data": { "id": "1001", "type": "AdSetAudience", "attributes": { "audienceId": "9876" } } } ``` ```json Response body - Success theme={null} { "data": { "id": "1001", "type": "AdSetAudience", "attributes": { "audienceId": "9876" } } } ``` ```json Response Body - Failure theme={null} { "errors": [ { "type": "validation", "code": "audience-not-found", "instance": "/ad-sets/1001/audience", ... } ], "warnings": [ /* omitted if no warnings */ ... ] } ``` ### Start an Ad Set One or more Ad Sets can be set to start delivery by making a `POST` call to the Start Ad Sets endpoint shown below. The payload should be an array of Ad Sets, specifying their `type` and `id`: ```http theme={null} /marketing-solutions/ad-sets/start ``` ```json Sample Request Body theme={null} { "data": [ { "type": "AdSetId", "id": "12345" }, { "type": "AdSetId", "id": "67890" } ] } ``` The API will return an array of Ad Sets representing those Ad Sets which were started successfully: ```json Sample Response theme={null} { "data": [ { "type": "AdSetId", "id": "12345" }, { "type": "AdSetId", "id": "67890" } ], "errors": [], "warnings": [] } ``` ### Stop an Ad Set Similarly, one or more Ad Sets can be set to stop delivery by making a `POST` call to the Stop Ad Sets endpoint shown below. The payload should be an array of Ad Sets, specifying their `type` and `id`: ```http theme={null} /marketing-solutions/ad-sets/stop ``` ```json Sample Request Body theme={null} { "data": [ { "type": "AdSetId", "id": "12345" } ] } ``` The API will return an array of Ad Sets representing those Ad Sets which were stopped successfully: ```json Sample Response theme={null} { "data": [ { "type": "AdSetId", "id": "12345" } ], "errors": [], "warnings": [] } ``` ## **Partial Success / Partial Failure** Each Ad Set update is processed individually and can succeed or fail without impacting other updates in the same payload. As a result, those Ad Set updates processed successfully will be returned in the `data` array of the response, while Ad Sets updates that have failed will return as an entry in the `errors` array of the response. **HTTP Response Codes** As a result of this individual processing, the API may respond with a `200` HTTP response code, but the result of its processing may have one or more failures. For instance, for this payload which intends to update two Ad Sets: ```http theme={null} /marketing-solutions/ad-sets ``` ```json Sample Request Body theme={null} { "data": [ { "type": "PatchAdSet", "id": "12345", "attributes": { "bidding": { "bidAmount": { "value": 0.9 } } } }, { "type": "PatchAdSet", "id": "67890", "attributes": { "bidding": { "bidAmount": { "value": -2 } } } } ] } ``` The response might look like: ```json Sample Response theme={null} { "data": [ { "type": "AdSetId", "id": "12345" } ], "errors": [ { "traceIdentifier": "56ed4096-f96a-4944-8881-05468efe0ec9", "type": "validation", "code": "campaign--ad-set-update-check--invalid-bid-amount", "instance": "@data/1", "title": "Invalid bid amount", "detail": "The bid amount value is invalid: either it's an adaptative cost controller and it must be null, or it's not the valid interval of values." } ], "warnings": [] } ``` **Error `instance`** The `instance` field for validation errors will specify the index of the related update, beginning with index 0. For the example above, `@data/1` refers to the second requested update in the request's `data` array. A full list of error codes can be found in the next section. ## **Validation Errors and Warnings** In addition to [general API errors](/criteo-apis/docs/api-error-types) , you may encounter validation errors when updating an Ad Set or attempting to start and stop delivery. Below is a list of error codes for Ad Set validation and a more detailed description of their meaning. **Ad Set Retrieval Validation Warnings:** **`cannot-expose-specific-adsets`**\ The configuration of the Ad Set prevents the retrieval via this API endpoint. **Ad Set Creation Validation Errors:**\ **`campaign--ad-set-creation-check--invalid-data`**\ The Ad Set has invalid configuration or is missing required information. **`campaign--ad-set-creation-check--invalid-geolocation`**\ The geolocation is invalid. **`campaign--ad-set-creation-check--invalid-os-env-configuration`**\ The configurations of Operating Systems and Environment are invalid. **`campaign--ad-set-creation-check--start-date-not-valid`**\ The start date must be before the end date. **`campaign--ad-set-creation-check--end-date-not-valid`**\ The end date must be after the start date. **`campaign--ad-set-creation-check--invalid-bid-amount`**\ The bid amount value is invalid: either it's an adaptive cost controller and it must be null, or it's not the valid interval of values. **`campaign--ad-set-creation-check--frequency-cappings-not-valid`**\ The frequency capping configuration is not valid. **`campaign--ad-set-creation-check--invalid-dataset-id`**\ The data set ID is invalid or not associated to your account. See [Datasets](/marketing-solutions/v2026-preview/docs/datasets) for how to find ad sets associated to your account. **`campaign--ad-set-creation-check--invalid-audience-configuration`**\ The Ad Set has invalid audience or audience with missing parameters. See [Create an Ad Set](/marketing-solutions/docs/ad-set#create-an-ad-set) for how to configure Ad Set Audience. **`campaign--ad-set-creation-check--no-audience-config`**\ The Ad Set has no audience configured. See [Create an Ad Set](/marketing-solutions/docs/ad-set#create-an-ad-set) for how to configure Ad Set Audience. **`campaign--ad-set-creation-check--multiple-audience-configs`**\ The Ad Set has multiple audiences configured. Only one audience can be configured per Ad Set. See [Create an Ad Set](/marketing-solutions/docs/ad-set#create-an-ad-set) for how to configure Ad Set Audience. **`campaign--ad-set-creation-check--invalid-audience-id`**\ The Ad set has invalid audience ID(s). To create this Ad Set, get in touch with our support team for assistance. **`campaign--ad-set-creation-check--invalid-spend-strategy`**\ The Ad Set is configured with an invalid spend strategy. To create this Ad Set, get in touch with our support team for assistance. **`campaign--ad-set-creation-check--invalid-bidding-configuration`**\ The bidding configuration is not valid with the selected MediaType. **`campaign--ad-set-creation-check--invalid-attribution-configuration`** The Ad Set has an invalid attribution configuration set up. * Attribution Method should not be null or unknown * Lookback window should not be unknown, and it should only be defined for Attribution Methods: `PostClick` and `LastClick` * When Google Analytics is not configured, it is not possible to select as attribution method: `GoogleAnalyticsLastClick`, `GoogleAnalyticsDataDriven` * If defined, the lookback window for an Optimum Ad Set must be `30D` **Ad Set Update Validation Errors:**\ **`campaign--ad-set-update-check--ad-set-invalid-geolocation`**\ The geolocation is invalid. **`campaign--ad-set-update-check--ad-set-is-archived`**\ This Ad Set is archived and thus can't be started. **`campaign--ad-set-update-check--ad-set-invalid-os-env-configuration`**\ The configurations of Operating Systems and Environment are invalid. **`campaign--ad-set-update-check--ad-set-not-activable`**\ This Ad Set is currently activated. Your change would impact negatively its eligibility to be active, so it has been prevented. **`campaign--ad-set-update-check--name-is-null`**\ An Ad Set cannot have an empty name. **`campaign--ad-set-update-check--start-date-is-null`**\ It's impossible to set an empty start date (though some old Ad Sets could have a null start date). **`campaign--ad-set-update-check--start-date-not-valid`**\ The start date must be before the end date. **`campaign--ad-set-update-check--end-date-not-valid`**\ The end date must be after the start date. **`campaign--ad-set-update-check--invalid-bid-amount`**\ The bid amount value is invalid: either it's an adaptive cost controller and it must be null, or it's not the valid interval of values. **`campaign--ad-set-update-check--frequency-cappings-not-valid`**\ The frequency capping configuration is not valid. **`campaign--ad-set-update-check--too-many-entities`**\ There are too many ad sets to be updated. A maximum of 50 ad sets can be updated per single request **Ad Set Start and Stop Validation Errors:**\ **`campaign--ad-set-start-check--cannot-activate-archived-ad-set`**\ This Ad Set is archived and thus can't be started. **`campaign--ad-set-start-check--active-ad-sets-limit-reached`**\ This Ad Set cannot be started because you reached the limit on the number of simultaneoulsy activated Ad Sets. **`campaign--ad-set-start-check--ad-set-with-custom-settings`**\ This Ad Set has some advanced settings and can't be launched directly through the platform. To launch this Ad Set, get in touch with our support team. **`campaign--ad-set-start-check--data-set-is-in-creative-ab-test`**\ This Ad Set is configured with a creative A/B test and can't be launched directly through the platform. To launch this Ad Set, get in touch with our support team. **`campaign--ad-set-start-check--ad-set-is-in-ab-test`**\ This Ad Set is configured with an A/B test and can't be launched directly through the platform. To launch this Ad Set, get in touch with our support team. **`campaign--ad-set-start-check--ad-set-with-revenue-optimizer`**\ This Ad Set is configured with Optimize Revenue. It needs to be switched to Optimize conversions for at least 2 weeks. To edit and launch this Ad Set, get in touch with our support team. **`campaign--ad-set-start-check--payment-billing-status-declined`**\ We noticed incorrect information in your billing details or payment information. Please get in touch with our support team to update your details. **`campaign--ad-set-start-check--payment-billing-status-no-details`**\ There's no payment & billing information attached to this account. Go to payments & billing to add your information. **`campaign--ad-set-start-check--ad-set-requiring-data-sharing`**\ Your Ad Set can't be launched because data sharing isn't activated on your account. Please contact your Criteo representative to activate this feature. **`campaign--ad-set-start-check--payment-billing-status-no-payment-method`**\ There's no payment method attached to this account. Go to payments & billing to add your payment details. **`campaign--ad-set-start-check--advertiser-financial-statuses-missing-payment-method`** To add a payment method, go to Billing and Payments. **`campaign--ad-set-start-check--advertiser-account-delivery-paused`** Check your Billing and Payments details and, if needed, please contact your Criteo representative for support. **`campaign--ad-set-start-check--advertiser-financial-statuses-incomplete`** To provide your missing billing information, please contact your Criteo representative. **`campaign--ad-set-start-check--terms-and-conditions-not-accepted`**\ You need to accept our Terms & Conditions to launch this Ad Set. To do so, get in touch with our support team. **`campaign--ad-set-start-check--ad-set-has-no-remaining-budget`**\ This Ad Set won't run until you add budget to it. Go to Budgets to increase your budget. **`campaign--ad-set-start-check--no-inventory-placements-for-ad-set`**\ This Ad Set needs at least one ad placement to get started. Go to Creatives to edit your ad placements. **`campaign--ad-set-start-check--not-enough-transaction-tag-hits`**\ We advise you to check your transaction tags in Events Tracking before launching your Ad Set. **`campaign--ad-set-start-check--no-active-catalog-feed`**\ As you're not using the auto-import feature, we need to resync your catalog to build dynamic ads. Go to Product catalog to start syncing. **`campaign--ad-set-start-check--no-design-set-found-for-banner-types`**\ This Ad Set needs at least one ad to get started. Go to Creatives to add one. **`campaign--ad-set-start-check--cannot-activate-ad-set-without-revenue`**\ You didn't specify any cost controller (bid or target KPI) amount for this Ad Set. Add a value for your bid or your target. If the error persists, get in touch with our support team. **`campaign--ad-set-start-check--context-zero-no-geoloc-filter`**\ Extensive targeting is enabled on your Ad Set. Reaching too many people could lead to bad performance results. Go to your Ad Set settings to narrow your targeting, by restricting the geolocation to 1 or 2 countries for example. If the error persists, get in touch with our support team. **`campaign--ad-set-start-check--context-zero-wrong-configuration`**\ The audience of your Ad Set is too broad. Check its configuration or get in touch with your account strategist for assistance. **`campaign--ad-set-start-check--desktop-device-not-supported-for-app-install`**\ Your Ad Set is missing some required information. Please get in touch with our support team. **`campaign--ad-set-start-check--data-set-logo-required-for-app-install`**\ Your Ad Set is missing some required information. Please get in touch with our support team. **`campaign--ad-set-start-check--parallel-click-tracking-incorrectly-set-up`**\ Parallel click tracking is not configured correctly. **`campaign--ad-set-start-check--ad-set-has-missing-attribution-url`**\ Your Ad Set is missing an attribution URL. **`campaign--ad-set-start-check--crp-ad-set-should-not-have-smoothing-budget`**\ Your CRP Ad Set should not employ budget smoothing. **`campaign--ad-set-start-check--misconfigured-ad-set`**\ This Ad Set has invalid configuration or missing parameters. To launch this Ad Set, get in touch with our support team for assistance. **`campaign--ad-set-start-check--ad-set-requiring-an-audience`**\ This Ad Set is not linked to an audience. Check the section [Update Ad Set Audience](/marketing-solutions/docs/ad-set#update-adset-audience). **`campaign--ad-set-update-check--invalid-attribution-configuration `** This Ad Set has an invalid attribution configuration set up: * Attribution Method should not be null or unknown * Lookback window should not be unknown, and it should only be defined for Attribution Methods: `PostClick` and `LastClick` * When Google Analytics is not configured, it is not possible to select as attribution method: `GoogleAnalyticsLastClick`, `GoogleAnalyticsDataDriven` * If defined, the lookback window for an Optimum Ad Set must be `30D` ## What's next * [Display Multipliers](/marketing-solutions/docs/display-multipliers) * [Category Bids](/marketing-solutions/docs/category-bids) # Ads Source: https://developers.criteo.com/marketing-solutions/docs/ads ## **Search Ads** ### Retrieving Ads for a Specific Advertiser Ads created through Criteo's API will be returned for the designated advertiser ID. Only ads created through API and Commerce Growth are returned. ```http theme={null} /advertisers/{advertiserId}/ads ```  The API will return an array of the IDs, name, description (if specified), creative ID, ad set ID, start date and end date (if specified) for the specified advertiser ID. Please note that the advertiser ID is required in the request URL. The offset and limit are optionals. **`offset`**\ 0 based index of the first ad to return in the response. The default is 0. **`limit`**\ The number of ads to be returned. The default is 50. ```json Example Response Body theme={null} { "data": [ { "id": "15", "type": "Ad", "attributes": { "name": "My first ad", "description": "Description of my first ad", "creativeId": "18", "adSetId": "345", "startDate": "2021-09-08T08:47:30.000Z", "endDate": "2021-10-08T08:47:30.000Z" } }, { "id": "16", "type": "Ad", "attributes": { "name": "My second ad", "description": "", "creativeId": "19", "adSetId": "346", "startDate": "2021-04-29T11:05:00.000Z", "endDate": null } } ], "warnings": [], "errors": [] } ``` ### Retrieving a Specific Ad Ad created through Criteo's API will be returned for the designated ad ID. ```http theme={null} /ads/{adId} ```  The API will return an array of the ID, name, description (if specified), creative ID, ad set ID, start date and end date (if specified) for the specified ad ID. Please note that the ad ID is required in the request URL. ```json JSON theme={null} { "data": { "id": "15", "type": "Ad", "attributes": { "name": "My first ad", "description": "Description of my first ad", "creativeId": "18", "adSetId": "345", "startDate": "2021-09-08T08:47:30.000Z", "endDate": "2021-10-08T08:47:30.000Z" } }, "warnings": [], "errors": [] } ``` *** ## **Creating A New Ad** A new ad can be created for a specific advertiser and from an existing creative by making a POST call to the ads endpoint. The request body should specify the name, description (optional), creative id, adset id, start date and end date (optional) of the new ad. ```http theme={null} /advertisers/{advertiserId}/ads ``` ```json Example POST Body theme={null} { "data": { "type": "AdWriteRequest", "attributes": { "name": "My new ad", "description": "Description of my new ad", "creativeId": "20", "adSetId": "347", "startDate": "2021-09-08T08:47:30.000Z", "endDate": "2021-10-08T08:47:30.000Z" } } } ``` The API will return an array of the ID, name, description (if specified), creative id, adset id, start date and end date (if specified) of the new ad. Please note that the advertiser ID is required in the request URL. **Ad id null at creation** Ad Id will be set as null in the response. The ad id will be provided after ad deployment and can be retrieved using the "Get Existing Ads" endpoints. ```json Example Response Body theme={null} { "data": { "id": null, "type": "Ad", "attributes": { "name": "My new ad", "description": "Description of my new ad", "creativeId": "20", "adSetId": "347", "startDate": "2021-09-08T08:47:30.000Z", "endDate": "2021-10-08T08:47:30.000Z" } }, "warnings": [], "errors": [] } ``` *** ## **Deleting an ad** An ad can be deleted by specifying the ad ID in the URL path of a DELETE call to the ads' endpoint. ```http theme={null} /ads/{adId} ``` The API will return an array with the ad ID that was deleted. ```json Example Response Body theme={null} { "errors": [], "warnings": [] } ``` *** ## **Validation Errors** **`user-request-forbidden-advertiser `**\ The user doesn't have the permission to access the specified advertiser. **`user-request-forbidden-creative`**\ The user doesn't have the permission to access the specified creative. **`user-request-forbidden-ad`**\ The user doesn't have the permission to access the specified ad. **`invalid-action-with-managed-creative`**\ The action cannot be performed on a managed service creative.  **`invalid-action-with-managed-ad`**\ The action cannot be performed on a managed service ad. **`invalid-creative-action-with-status `**\ The action cannot be performed due to the status of the creative. **`invalid-image`**\ One of the images provided is invalid. Please check the image requirements [here](https://help.criteo.com/kb/guide/en/image-ads-8hXUBDeeoo/Steps/775688) **`invalid-redirection-url-image`**\ The redirection URL specified doesn't match the advertiser domain. **`invalid-html-tag`**\ One of the HTML tags is not supported. Please check the list of supported ad servers [here](https://help.criteo.com/kb/guide/en/third-party-ads-QUSq5Astwy/Steps/775787,817360) **`invalid-creative-request`**\ Invalid request on the Creative endpoint. **`invalid-ad-request`**\ Invalid request on the Ad endpoint. # Advertisers Source: https://developers.criteo.com/marketing-solutions/docs/advertisers ## **Introduction** Criteo's Advertisers API will allow you to easily retrieve the names and IDs of all advertisers you've been granted access to.  **Known Limitations** Advertiser creation is not yet available. Currently, you can only retrieve your portfolio of advertisers.\ Full functionality will be added in future releases. *** ## **Advertisers Endpoint** ```http theme={null} https://api.criteo.com/2026-01/advertisers ```
## What's next * [Get Advertiser Portfolio](/marketing-solutions/docs/get-advertiser-portfolio) # Algebra Nodes Source: https://developers.criteo.com/marketing-solutions/docs/algebra-nodes ## Introduction Algebra nodes define the logical rules used to compute Audience membership from Segments. Algebra nodes are the way to mix different Audience Segments.\ For example, you can use them when you want to include users that belong to more than one segment at the time or if you want to exclude users of a specific segment. Each Audience has one Algebra Node, and within it, you can mix your segments to build the audiences you want. Algebra nodes can be mixed together in a flexible way. There are four types of nodes available, and they follow a JSON notation: * Audience Segment nodes: Segments with no operator. * `AND` nodes: used to include the users that belong simultaneously to all the segments within it (like an intersection). * `OR` nodes: used to include users that belong to any of the segments within it. * `NOT` nodes: used to not include the users that belong to the segments within it. We provide examples below. *** ## Nodes Examples ### Audience Segment Node ```json JSON theme={null} // Target users that belong to a single Audience Segment { "audienceSegmentId": "153516" } ``` *** ### `AND` Node This one is used to include the users that belong simultaneously to all the segments (like an intersection). ```json JSON expandable theme={null} // Target users that belong to three Audience Segments "and": [ { "audienceSegmentId": "153516" }, { "audienceSegmentId": "144184" }, { "audienceSegmentId": "328272" } ] // Target users that belong to two groups of Audience Segments "and": [ { "or": [ { "audienceSegmentId": "153516" }, { "audienceSegmentId": "144184" } ] }, { "or": [ { "audienceSegmentId": "144217" }, { "audienceSegmentId": "153522" } ] } ] // Target users that belong to the first group of Audience Segments (42914 or 19234) but not on the last one (144219) "and": [ { "or": [ { "audienceSegmentId": "42914" }, { "audienceSegmentId": "19234" } ] }, { "not": { "audienceSegmentId": "144219" } } ] ``` *** ### `OR` Node This is used to include users that belong to any of the segments within it. ```json JSON theme={null} // Target users that belong to any of these Audience Segments { "or": [ { "audienceSegmentId": "144219" }, { "audienceSegmentId": "153522" }, { "audienceSegmentId": "144217" } ] } ``` *** ### `NOT` Node This is used to exclude the users that belong to the segments within it. ```json JSON theme={null} // Target users that do not belong to the single Audience Segment { "not": { "audienceSegmentId": "144219" } } // Target users that do not belong to any of these Audience Segments { "not": { "or": [ { "audienceSegmentId": "153516" }, { "audienceSegmentId": "144217" } ] } } // Target users that do not belong to these Audience Segments { "not": { "and": [ { "audienceSegmentId": "153516" }, { "audienceSegmentId": "144217" } ] } } ``` # Analytics Source: https://developers.criteo.com/marketing-solutions/docs/analytics ## **Introduction** The **Statistics API** endpoint allows you to retrieve data related to your campaigns' performance. The specific metrics returned and the dimensions that the data is grouped by can be customized. This enables you to merge Criteo data with other sources, build business alerting on Criteo data, or programmatically manage ad spend based on campaign performance.  This provides granularity and flexible insights to help you optimize your campaigns and better understand the results they are delivering.  *** ## **Endpoint** ```http theme={null} https://api.criteo.com/2026-01/statistics/report ``` *** ## **New Features Since `v2021-01`** Since v2021-01, Criteo's Statistics API introduces several new metrics that relate to different marketing goals and channels, including app, web and store campaigns. Additionally, you can now specify your time zone, keep track of your product category history and retrieve a nearly real-time look at your data and campaign performance. **Known Limitation from `v2021-01`Onward** * The maximum number of returned rows per request is limited to 100,000. As a result, you may need to fetch highly granular data by making several smaller requests. This limitation will be addressed in future releases of the /statistics/report endpoint. ## What's next * [Campaign Statistics](/marketing-solutions/docs/campaign-statistics) * [Transaction IDs](/marketing-solutions/docs/transaction-ids) * [Log-Level](/marketing-solutions/docs/log-level) * [Placement](/marketing-solutions/docs/placement) * [Placement Category](/marketing-solutions/docs/placement-category) # Audience Source: https://developers.criteo.com/marketing-solutions/docs/audience The new audience endpoints function according to the bulk operation logic. ## Audiences Audiences have some specific parameters, which can be Required, Optional or Computed (filled automatically after Audience creation)

Field Name

Type

Optional / Required / Computed

Description

id

String

Computed

Unique ID of the audience

name

String

Required

Name of the audience. It must be unique per advertiser.

description

String

Optional

Description of the audience

createdAt

String

Computed

ISO-8601 timestamp in UTC of audience creation (read-only)

updatedAt

String

Computed

ISO-8601 timestamp in UTC of audience update (read-only)

advertiserId

String

Required

Advertiser associated to the audience

adSetIds

String Array

Computed

Ad sets associated to the audience (read-only).

algebra

Algebra Node

Required

Algebra Node with the definition of how the different segments are mixed to create the audience using logical operators: AND, OR, NOT.

*** ## Create Audiences Creates all Audiences with a valid configuration and returns them. For those that cannot be created, one or multiple errors are returned. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audiences/create ``` **Sample request** ```json JSON theme={null} { "data": [ { "type": "Audience", "attributes": { "name": "My audience", "description": "An audience which targets people of interest", "advertiserId": "4949", "algebra": { "and": [ { "or": [ { "audienceSegmentId": "42914" }, { "audienceSegmentId": "19234" } ] }, { "not": { "audienceSegmentId": "3482" } } ] } } } ] } ``` **Sample response** ```json JSON expandable theme={null} { ... "data": [ { "id": "1001", "type": "Audience", "attributes": { "name": "My audience", "createdAt": "2018-07-04T00:00:00Z", "updatedAt": null, "description": "An audience which targets people of interest", "advertiserId": "4949", "algebra": { "and": [ { "or": [ { "audienceSegmentId": "42914" }, { "audienceSegmentId": "19234" } ] }, { "not": { "audienceSegmentId": "3482" } } ] } } } ], "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Update Audiences Updates the properties of all audiences with a valid configuration and returns them. For those that cannot be updated, one or multiple errors are returned. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audiences ``` **Sample request** ```json JSON expandable theme={null} { "data": [ { "id": "1001", "type": "Audience", "attributes": { "name": "My audience (v2)", "description": { value: "An audience which targets a broader set of people of interest except existing customers" }, "algebra": { "and": [ { "or": [ { "audienceSegmentId": "42914" }, { "audienceSegmentId": "19234" } ] }, { "not": { "or": [ { "audienceSegmentId": "3482" }, { "audienceSegmentId": "2842" } ] } } ] } } } ] } ``` **Sample response** ```json JSON expandable theme={null} { ... "data": [ { "id": "1001", "type": "Audience", "attributes": { "name": "My audience (v2)", "createdAt": "2018-07-04T00:00:00Z", "updatedAt": "2018-07-15T00:00:00Z", "description": "An audience which targets a broader set of people of interest except existing customers", "advertiserId": "4949", "algebra": { "and": [ { "or": [ { "audienceSegmentId": "42914" }, { "audienceSegmentId": "19234" } ] }, { "not": { "or": [ { "audienceSegmentId": "3482" }, { "audienceSegmentId": "2842" } ] } } ] } } } ], "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Search Audiences Returns a list of audiences that match the provided filters. If present, the filters are AND'ed together when applied. You can search audiences by audience IDs, advertiser IDs, segment IDs and/or ad set IDs. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audiences/search ```

Name

Required / Optional

Description

limit

optional

The number of elements to be returned. The default is 50 and the maximum is 100.

offset

optional

The (zero-based) offset into the collection. The default is 0.

**Sample request** ```json JSON theme={null} { "data": { "type": "AudienceSearch", "attributes": { "audienceIds": null, "advertiserIds": null, "audienceSegmentIds": null, "adSetIds": ["1001"] } } } ``` **Sample response** ```json JSON expandable theme={null} { ... "meta": { "totalItems": 400, "limit": 50, "offset": 0 }, "data": [ { "id": "1001", "type": "Audience", "attributes": { "name": "My audience", "description": "An audience which targets people of interest", "createdAt": "2018-07-04T00:00:00Z", "updatedAt": "2018-07-15T00:00:00Z", "advertiserId": "4949", "adSetIds": ["49122", "21242"], "algebra": { "and": [ { "or": [ { "audienceSegmentId": "42914" }, { "audienceSegmentId": "19234" } ] }, { "not": { "audienceSegmentId": "3482" } } ] } }, }, /* more search results */ ], "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Delete Audiences Deletes the audiences associated with the given audience IDs. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audiences/delete ``` **Sample request** ```json JSON theme={null} { "data": [ { "id": "1001", "type": "Audience" } ] } ``` **Sample response** ```json JSON theme={null} { ... "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Compute Audiences sizes If you have already created an audience, and would like to use it's size, you can use this endpoint. It returns the size of one or more audience IDs (if available and if supported). For those whose size cannot be retrieved, one or multiple errors are returned. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/compute-sizes ``` **Sample request** ```json JSON theme={null} { "data": [ { "id": "1001", "type": "Audience" }, { "id": "1002", "type": "Audience" }, { "id": "1003", "type": "Audience" } ] } ``` **Sample response** ```json JSON theme={null} { "data": [ { "id": "1001", "type": "AudienceSize", "attributes": { "size": 194730 } }, { "id": "1002", "type": "AudienceSize", "attributes": { "size": 4285 } }, { "id": "1003", "type": "AudienceSize", "attributes": { "size": 978597 } } ] } ``` *** ## Estimate Audience size If you have the structure of the audience, but have not created it yet, and would like to estimate it's size, you can use this endpoint. It returns the size estimation for an audience (if available and if supported). If the size cannot be estimated, an error is returned. This endpoint is resource-intensive, this is why the bulk workflow is not supported. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/estimate-size ``` **Sample request** ```json JSON theme={null} { "data": { "type": "Audience", "attributes": { "advertiserId": "4949", "algebra": { "and": [ { "or": [ { "audienceSegmentId": "42914" }, { "audienceSegmentId": "19234" } ] }, { "not": { "audienceSegmentId": "3482" } } ] } } } } ``` **Sample response** Success ```json JSON theme={null} { "data": { "type": "AudienceSize", "attributes": { "size": 194730 } } } ``` Failure ```json JSON theme={null} { "errors": [ { "type": "validation", "code": "audience-size-too-small", "instance": "/marketing-solutions/audiences/size-estimation", ... } ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Validation Errors In addition to general API errors, you may encounter validation errors when creating or managing Audiences and Segments. Below is a list of error codes for Audience endpoints and a more detailed description of their meaning. `empty-data-object`\ Cannot have an empty data object `pagination-limit-too-big`\ Pagination limit is too big `audience-must-contain-only-existing-segments`\ Audience must contain only existing segments `audience-not-found`\ Audience not found `audience-size-not-available`\ Audience size not available `audience-size-not-supported`\ Audience size not supported `audience-size-too-small`\ Audience size is too small `country-code-must-be-valid`\ Country code must be valid `country-code-must-be-authorized`\ Country code must be authorized `country-code-is-required`\ Country code is required `buying-power-must-be-valid`\ Buying power must be valid `brand-list-must-be-valid`\ Brand list must be valid `interests-list-must-be-valid`\ Interest list must be valid `gender-must-be-valid`\ Gender must be valid `registry-type-must-be-valid`\ Registry type must be valid `price-range-must-be-valid`\ Price range must be valid `poi-list-must-be-not-empty`\ Points of interest list must be nor null nor empty `poi-list-must-be-null-or-empty`\ Points of interest list must be null or empty `radius-must-be-in-range`\ RadiusInKm must be in range `poi-coordinates-must-be-valid`\ Points of interest coordinates must be valid `poi-surface-must-be-valid`\ Points of interest surface area must be valid `poi-radius-must-be-not-null`\ Location segment of type 'PointOfInterest' must have a radius `segment-not-found`\ Segment not found `segment-size-not-available`\ Segment size not available `segment-size-not-supported`\ Segment size not supported `segment-size-too-small`\ Segment size is too small *** ### Audience `undefined-advertiser-id`\ Cannot have an undefined advertiser ID `payload-too-big`\ Cannot create more than 50 audiences at a time `payload-too-big`\ Cannot update more than 50 audiences at a time `non-parsable-id`\ One or more IDs cannot be parsed `duplicate-id`\ Audience ID cannot be duplicated `audience-must-not-be-used-in-non-archived-ad-set`\ Audience must not be used in an active ad set `audience-algebra-and-or-nodes-must-include-more-than-one-node`\ Audience algebra "and" and "or" nodes must include more than one node `audience-with-similar-segment-must-be-correctly-specified`\ Audience with similar segment must be correctly specified `audience-must-contain-included-segment-or-only-excluded-contact-list`\ Audience must contain included segment or only excluded contact list `audience-cannot-switch-to-from-similar`\ Audience cannot switch to/from similar `audience-cannot-switch-to-from-pushback`\ Audience cannot switch to/from pushback `audience-name-must-be-unique`\ Audience name must be unique `name-must-not-be-empty`\ Audience name property must not be empty `advertiser-must-be-opt-in-for-data-sharing`\ Advertiser must be opted in for data sharing *** ### Segment `undefined-advertiser-id`\ Cannot have an undefined advertiser ID `undefined-segment-type`\ Cannot have a segment object without any type defined `multiple-segment-types`\ Cannot have a segment object with multiple types defined `duplicate-name`\ Cannot have duplicated segment names `payload-too-big`\ Cannot create more than 50 segments at a time `payload-too-big`\ Cannot update more than 50 segments at a time `non-parsable-id`\ One or more IDs cannot be parsed `duplicate-id`\ Segment ID cannot be duplicated `name-must-not-be-empty`\ Name must not be empty `segment-must-not-be-used-in-audience`\ Segment must not be used in an audience `commerce-settings-must-be-defined`\ Commerce segment settings must be defined `event-type-must-be-valid`\ Event type must be valid `days-must-be-in-range`\ Days in omnichannel segment must be in range `cannot-create-contact-list`\ Contact list creation error `name-must-be-unique`\ Name must be unique `type-must-be-the-same`\ Type must be the same `type-must-be-the-same`\ Type must be the same ## What's next * [Audience Segments](/marketing-solutions/docs/audience-segments) * [Algebra Nodes](/marketing-solutions/docs/algebra-nodes) # Audience Segments Source: https://developers.criteo.com/marketing-solutions/docs/audience-segments ## Introduction Audience Segments are the building blocks of Audiences, as you can mix them together to ensure you target your desired customer base. An audience segment is the association of an audience segment type with an audience segment value. *** ## Audience Segment Types **Static Values on Audience Segments** Some of the parameters required to define an Audience Segment can take predefined values. For example, to get the different values that the field `In-market Brand Id` can take, use the `audience-segments/in-market-brands` endpoint. Regardless of the Segment type, segments share the following fields. Some of them are *calculated* so you don't need to define them at the creation but can read them after the Segment is created.

Field name and type

Type

Possible value

Optional / Required / Computed

Description

id

String

Required

Unique ID of the segment

name

String

Required

Name of the segment. It must be unique per advertiser.

description

String

Optional

Description of the segment

type

AudienceSegmentType

AudienceSegment

Computed

Type of audience segment (read-only). Once created, the type cannot be changed.

createdAt

String

Computed

ISO-8601 timestamp in UTC of segment creation (read-only)

updatedAt

Computed

ISO-8601 timestamp in UTC of segment update (read-only)

advertiser Id

String

Required

Advertiser associated to the segment

### In-market In-market segments can be used to target users based on high shopping intents and demographics.

Field name

Type

Optional / Required / Computed

Description

In-market

In-market

Optional

Indicates that this should be an Audience Segment of type In-market

A **In-market** object has the following parameters:

Field name

Type

Optional / Required / Computed

Description

country

String

The ISO 3166-1 alpha-2 country code

Required (if In-market is set)

Reach people of a specific country.

buyingPower

BuyingPower array

BuyingPower can be:

  • Low
  • Medium
  • High
  • VeryHigh

Optional

Reach people who frequently purchase high price range items to lower price range items. If empty, don't filter people based on buying power.

gender

Gender

Gender can be:

  • Male
  • Female

Optional

Reach people who’ve shown interest in products made for a specific gender. If empty, don't filter people based on gender.

interestIds

String array

Required (if In-market is set)

Reach new people based on their commercial interests

brandIds

String array

Required (if In-market is set)

Choose the commercial brands your segment might be interested in

priceRange

PriceRange array

PriceRange can be:

  • Low
  • Medium
  • High

Optional

Reach people who’ve shown interest in products within a specific price range. If empty, don't filter people based on price range.

```json Example theme={null} { "type": "AudienceSegment", "attributes": { "name": "My In-market segment", "description": "This is a segment for men in France who look for high priced products", "inMarket": { "country":"FR", "gender": "Male", "interestIds": ["928"], "brandIds": ["289"], "priceRange": ["High"] } } } ``` *** ### Contact List Contact List segments can be used to target people from your contact lists. First, you define the segment and update the data using other endpoints.

Field name

Type

Optional / Required / Computed

Description

contactList

ContactList

Optional

Indicates that this should be an Audience Segment of type Contact List

The *contactList* parameter should be empty on the creation of this type of audience segment. More details on [Manage Contact Lists](/marketing-solutions/docs/audience-segments#manage-contact-lists). A **Contact List** object has the following parameters:

Field name

Type

Optional / Required / Computed

Description

isReadOnly

Boolean

Computed

True if the contact list-specific information cannot be edited through the public API, false otherwise.

Contact Lists can be created through the Public API or through Commerce Growth, and this determines where they’re editable: if created through the Public API, they can only be edited through the Public API; same for Commerce Growth.

Segments created in Commerce Growth will show up as "isReadOnly": true on the Public API.

```json Example theme={null} { "type": "AudienceSegment", "attributes": { "name": "My contact list segment", "description": "An audience segment which targets my customer's database", "advertiserId": "4949", "contactList": { }, } } ``` *** ### Location Location Segments can be used to target users in specific locations.

Field name

Type

Optional / Required / Computed

Description

location

Location

Optional

Indicates that this should be an Audience Segment of type Location

A **Location** object has the following parameters:

Field name

Type

Optional / Required / Computed

Description

registryType

RegistryType

RegistryType can take only one value (for now):

  • PointsOfInterest

Required (if location set)

The type of location audience segment

pointsOfInterest

PointsOfInterest array.

Each point has a name, latitude and longitude

Required (if location set)

Reach users which have been historically located in the given coordinates

→ name

String

Required

Name of the point of interest

→ latitude

Decimal

Required

ISO-6709 latitude

→ longitude

Decimal

Required

ISO-6709 longitude

radiusInKm

Integer

Required (if location set)

The expected maximum distance in kilometers between a user and a point of interest

```json Example theme={null} { "type": "AudienceSegment", "attributes": { "name": "My Location Segment", "description": "Customers close to our main store", "advertiserId": "12345", "location": { "registryType": "PointsOfInterest", "pointsOfInterest": [{ "name": "main store", "latitude": 56.6, "longitude": 40.2 },{ "name": "second store", "latitude": 30.6, "longitude": 20.4 }], "radiusInKm": 10 } } } ``` *** ### Behavioral Criteo-provided pre-built segments. These segments are not created by the user but provided by Criteo. You cannot edit them or delete them, but you can use them to build Audiences (e.g. "People that like shoes", "People that go often to the theater", etc.).

Field name

Type

Optional / Required / Computed

Description

behavioral

Behavioral

Computed

Indicates that this should be an Audience Segment of type Behavioral

A **Behavioral** object has the following parameters:

Field name

Type

Optional / Required / Computed

Default Value

Description

country

String

Computed

The user's country

category

BehavioralCategory.

Can take any of these values:

  • Lifestyles
  • LifeEvents
  • Seasonal
  • BuyingPatterns

Computed

The behavioral's category

startDate

DateTime

Computed (can be empty)

Empty

The date when this audience segment will start to be filled with audience data

endDate

DateTime

Computed (can be empty)

Empty

The date when this audience segment will be cleaned of audience data

**List of Behavioral Segments** To get the list of the available Behavioral segments you can use the Search endpoint filtering by `Behavioral` type. *** ### Prospecting Prospecting segments are used to include users similar to the buyers of the advertiser.

Field name

Type

Optional / Required / Computed

Description

Prospecting

Prospecting

Optional

Indicates that this should be an Audience Segment of type Prospecting

A Prospecting object does not have any attributes, so you need to declare it empty. `"prospecting":{}` ```json Example theme={null} { "type": "AudienceSegment", "attributes": { "name": "My Prospecting Segment", "description": "Customers that are similar to my current website visitors", "advertiserId": "12345", "prospecting": {} } } ``` *** ### Lookalike Lookalike segments allow you to reach users that are similar to a given segment seed. You will be able to reach people who look like, behave like, or are interested in things similar to another segment.

Field name

Type

Optional / Required / Computed

Description

Lookalike

Lookalike

Optional

Indicates that this should be an Audience Segment of type Lookalike

A Lookalike Segment object has the following parameters:

Field

Type

Mandatory

Description

seedSegmentId

string

Yes

Id of existing Contact List or Event segment that will be treated as a seed.

targetSize

int64

No

The target size of the resulting segment after computation.

```json Example theme={null} { "id": "367783", "type": "AudienceSegment", "attributes": { "name": "Sample lookalike", "description": "Sample lookalike segment", "type": "Lookalike", "createdAt": "2023-01-26T19:21:30.76", "updatedAt": "2023-01-26T19:21:30.76", "advertiserId": "44981", "lookalike": { "seedSegmentId": "324415", "targetSize": 5000000 } }, }, ``` **Updating Lookalike segments** It's not possible to update the seed of a lookalike segment, if you need to use another seed, create a new segment instead. *** ### Retargeting The retargeting segments enable you to focus on specific groups of website visitors based on the time frames since their last visit. You have the option to target buyers, non-buyers, or all visitors.

Field name

Type

Optional / Required / Computed

Description

Retargeting

Retargeting

Optional

Indicates that this should be an Audience Segment of type Retargeting

Name

Type

Optional/Required

Description

visitorsType

VisitorsType

Can take three values:

* All

  • Buyers

* NonBuyers

Required

The type of users being targeted.

daysSinceLastVisitMin

Integer

Required

Include users who visited your website before this number of days

daysSinceLastVisitMax

Integer

Required

Include users who visited your website after this number of days

```json JSON theme={null} { "data": [ { "id": "1002", "type": "AudienceSegment", "attributes": { "name": "My retargeting segment", "description": { value: "A segment with buyers" }, "retargeting": { "visitorsType": "Buyers", "daysSinceLastVisitMin": 10, "daysSinceLastVisitMax": 60 } } } ] } ``` *** # Operations ## Get a list of available In-market interests. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/in-market-interests ``` Returns a list with all available In-market interests that can be used to define an In-market audience segment. These In-market interests correspond to the Google product taxonomy. An In-market interest is considered available if there is enough volume for this particular In-market interest in the given country.

Name

Required / Optional

Description

advertiser-id

required

The Advertiser Id

country

required

The ISO 3166-1 alpha-2 country code

*** ## Get a list of available In-market brands. Returns a list with all available In-market brands that can be used to define an In-market audience segment. An In-market brand is considered available if there is enough volume for this particular In-market brand in the given country. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/in-market-brands ```

Name

Required / Optional

Description

advertiser-id

required

The Advertiser Id

country

required

The ISO 3166-1 alpha-2 country code

*** ## Create Audience Segments Create audience segments in bulk mode. Creates all audience segments with a valid configuration and returns their IDs with their advertiser IDs, names, and creation/update dates. One or multiple errors are returned for those that cannot be created. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/create ``` **Sample request** ```json JSON expandable theme={null} { "data": [ { "type": "AudienceSegment", "attributes": { "name": "My contact list segment", "description": "An audience segment which targets my customer's database", "advertiserId": "4949", "contactList": {} } }, { "type": "AudienceSegment", "attributes": { "name": "My In-market segment", "description": "An audience segment which targets people interested in Adidas shoes", "advertiserId": "4949", "inMarket": { "country": "FR", "interestIds": [ "928" ], "brandIds": [ "289" ] } } }, { "type": "AudienceSegment", "attributes": { "name": "My Prospecting segment", "description": "An audience segment which targets people similar to my website visitors", "advertiserId": "4949", "prospecting": { } } }, { "type": "AudienceSegment", "attributes": { "name": "Lookalike segment", "description": "Lookalike description", "advertiserId": "4949", "lookalike": { "seedSegmentId": "335274", "targetSize": 5000000 } } }, { "type": "AudienceSegment", "attributes": { "name": "My retargeting segment", "description": { "value": "A segment including buyers" }, "retargeting": { "visitorsType": "Buyers", "daysSinceLastVisitMin": 10, "daysSinceLastVisitMax": 60 } } } ] } ``` **Sample Response** Success ```json JSON expandable theme={null} { "data": [ { "id": "1001", "type": "AudienceSegment", "attributes": { "name": "My contact list segment", "type": "ContactList", "description": "Contact list description", "createdAt": "2023-05-09T16:30:50.4633333", "updatedAt": null, "advertiserId": "4949", "contactList": { "isReadOnly": false } } }, { "id": "1002", "type": "AudienceSegment", "attributes": { "name": "My In-market segment", "type": "InMarket", "description": "In-Market description", "createdAt": "2023-05-09T16:30:50.4633333", "updatedAt": null, "advertiserId": "4949" } }, { "id": "1003", "type": "AudienceSegment", "attributes": { "name": "My Prospecting segment", "createdAt": "2018-07-04T00:00:00Z", "updatedAt": null, "advertiserId": "4949" } }, { "id": "335275", "type": "AudienceSegment", "attributes": { "name": "Lookalike segment", "description": "Lookalike description", "type": "Lookalike", "createdAt": "2023-05-09T16:30:50.4633333", "updatedAt": "2023-05-09T16:30:50.4633333", "advertiserId": "4949", "lookalike": { "seedSegmentId": "335274", "targetSize": 5000000 } } }, { "id": "129221", "type": "AudienceSegment", "attributes": { "name": "My retargeting segment", "description": { "value": "A segment including buyers" }, "type":"Retargeting", "createdAt": "2023-05-09T16:30:50.4633333", "updatedAt": "2023-05-09T16:30:50.4633333", "retargeting": { "visitorsType": "Buyers", "daysSinceLastVisitMin": 10, "daysSinceLastVisitMax": 60 } } } ], "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` To create a contact list audience segment, you need to add an empty `contactList` parameter, as you can see in the example. To define the content of this audience segment, you should refer to the section [Manage Contact Lists](/marketing-solutions/docs/audience-segments#manage-contact-lists). *** ## Update Audience Segments Update audience segments in bulk mode. Updates the properties of all audience segments with a valid configuration and returns their IDs with their advertiser IDs, names, and creation/update dates. One or multiple errors are returned for those that cannot be updated. **Partial Update Request: Modifying Segment Attributes** When building the update request, you don't need to include all the fields of the Segment. Provide the Id, type and the attributes you would like to modify. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments ``` **Sample request** ```json JSON expandable theme={null} { data: [ { id: "1001", type: "AudienceSegment", attributes: { name: "My contact list segment (v2)", }, }, { id: "1002", type: "AudienceSegment", attributes: { name: "My In-market segment (v2)", description: { value: "A segment which targets men interested in expensive Adidas shoes", }, inMarket: { gender: "Male", priceRange: ["High"], }, }, }, { id: "335275", type: "AudienceSegment", attributes: { name: "Lookalike segment (v2)", lookalike: { targetSize: 5000000, }, }, }, ], } ``` **Sample response** Success ```json JSON expandable theme={null} { ... "data":[ { "id":"1001", "type":"AudienceSegment", "attributes":{ "name":"My contact list segment (v2)", "createdAt":"2018-07-04T00:00:00Z", "updatedAt":"2022-10-28T11:55:20.77", "advertiserId":"4949", "contactList":{ "isReadOnly":false } } }, { "id":"1002", "type":"AudienceSegment", "attributes":{ "name":"My In-market segment (v2)", "description":"A segment which targets men interested in expensive Adidas shoes", "createdAt":"2018-07-04T00:00:00Z", "updatedAt":"2022-10-28T11:55:20.77", "advertiserId":"4949" } }, { "id":"335275", "type":"AudienceSegment", "attributes":{ "name":"Lookalike update", "description":"lookalike desc update", "type":"Lookalike", "createdAt":"2022-10-28T10:57:13.363", "updatedAt":"2022-10-28T11:55:20.77", "advertiserId":"4949", "lookalike":{ "seedSegmentId":"335274", "targetSize":5000000 } } } ], "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` To update contact lists within an audience segment, refer to the section [Manage Contact Lists](/marketing-solutions/docs/audience-segments#manage-contact-lists). *** ## Search Audience Segments Search audience segments by audience segment IDs, audience segment types, or advertiser IDs. It returns a list of audience segments that match the provided attributes. If present, the attributes are AND'ed together when applied (will only return the segments that satisfy ALL those conditions). ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audiences/search ``` **Sample request** ```json JSON theme={null} { "data": { "attributes": { "advertiserIds": [ "44981", "4949" ], "audienceSegmentIds": null, "audienceSegmentTypes": [ "In-market", "Location" ] } } } ``` **Sample response** ```json JSON expandable theme={null} { "meta": { "totalItems": 400, "limit": 50, "offset": 0 }, "data": [ { "id": "1001", "type": "AudienceSegment", "attributes": { "name": "My In-market segment", "description": "A segment which targets people interested in Adidas shoes", "createdAt": "2018-07-04T00:00:00Z", "updatedAt": "2018-07-15T00:00:00Z", "advertiserId": "4949", "inMarket": { "country": "FR", "interestIds": ["928"], "brandIds": ["289"] } }, }, /* more search results */ ], "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Delete Audience Segments Delete audience segments in bulk mode.\ Deletes the audience segments associated with the given audience IDs. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/delete ``` **Sample request** ```json JSON theme={null} { "data": [ { "id": "1002", "type": "AudienceSegment" }, { "id": "1001", "type": "AudienceSegment" } ] } ``` **Sample response** ```json JSON theme={null} { ... "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Compute Audience Segment sizes If you have already created one or more segments, and would like to know their size, you can do so by using this endpoint. It returns the size of one or more audience segment IDs (if available and if supported). For those whose size cannot be retrieved, one or multiple errors are returned. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/compute-sizes ``` **Sample request** ```json JSON theme={null} { "data": [ { "id": "1001", "type": "AudienceSegmentSize", "attributes": { "size": 194730 } }, { "id": "1002", "type": "AudienceSegmentSize", "attributes": { "size": 4285 } }, { "id": "1003", "type": "AudienceSegmentSize", "attributes": { "size": 978597 } } ] } ``` **Sample response** ```json JSON theme={null} { "errors": [ { "type": "validation", "code": "audience-segment-not-found", "instance": "@data/0", ... }, { "type": "validation", "code": "audience-segment-size-not-available", "instance": "@data/1", ... }, { "type": "validation", "code": "audience-segment-size-not-supported", "instance": "@data/2", ... } ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Estimate Audience Segment Size If you know the structure of your segment, but have not created it yet, and would like to estimate its size, you can use this endpoint. It returns the size estimation for an audience segment (if available and if supported).\ If the size cannot be estimated, an error is returned. This endpoint is resource-intensive, this is why the bulk workflow is not supported. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/estimate-size ``` **Sample request** ```json JSON theme={null} { "data": { "type": "AudienceSegment", "attributes": { "advertiserId": "4949", "inMarket": { "country": "FR", "interestIds": ["928"], "brandIds": ["289"], } } } } ``` **Sample response** Success ```json JSON theme={null} { "data": { "type": "AudienceSegmentSize", "attributes": { "size": 194730 } } } ``` Failure ```json JSON theme={null} { "errors": [ { "type": "validation", "code": "audience-segment-size-too-small", "instance": "/audience-segments/size-estimation", ... } ], "warnings": [ /* omitted if no warnings */ ... ] } ``` *** ## Manage Contact Lists After creating an audience segment of the type `contact list`, you can use the following endpoints to update its content. ### Adding and Removing Users ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/{audience-segment-id}/contact-list ``` Users can be added or removed from an audience segment with a `PATCH` request to the audience contact list endpoint with the specific audience segment id in the URL path.\ The request body requires the type of operation, the schema of the identifiers, and the list of the user identifiers to be added. In addition, if the identifier type is `gum`, an additional parameter, the `gumCallerId`, must also be included. Please note that the supported identifier types for Criteo audiences include: `email` (Email Address in plain text, MD5, SHA256 or SHA256MD5-hashed), `madid` (Mobile Ad Identifier), `identityLink` (a user's LiveRamp Identity Link), `gum` (Criteo GUM cookie identifier), `customerid` (only for Retail Media Customer Lists) and `phonenumber` (plain text or sha256 hashed phone numbers, only supported for advertisers in India). **GUM ID** GUM ID's allow clients to maintain a correspondence between their user identification system and Criteo's user identification (UID) if they are unable to send emails or mobile ad identifiers. Please reach out to your Criteo account team for the appropriate `gumCallerId` or to get more information on this GUM sync, if needed. **Phone Number Formats** *Clear phone number* A clear phone number needs to have the “+” sign and the country code, it can contain spaces or “-” or both. example: +33 01 23 45 67 89, +330123456789, +330123-45-6789 *Sha256 hashed phone number* The original clear phone number before `sha256` should be normalized: 1. Trimmed E.164 format including the country code 2. without the leading "+" sign (so only 15 digits, at most): sha256 (for example, `internationalPhoneNumber.replaceAll(/[^0-9]/g, "")`) #### Adding Users To add users to an audience segment, use the 'add' operation in the `PATCH` request as detailed below: ```json Example PATCH Request - Adding Users theme={null} { "data": { "type": "ContactlistAmendment", "attributes": { "operation": "add", "identifierType": "email", "identifiers": [ "example1@gmail.com" ] } } } ``` ```json Example PATCH Request - Adding Users (SHA256 emails) theme={null} { "data": { "type": "ContactlistAmendment", "attributes": { "operation": "add", "identifierType": "email", "identifiers": [ "8614620f4b7591e9270b91928299e1de99456e9f1883eadef140b6fc12c92830", "97e2a275de13f3cef1f16a333baf450fcf3d58ecc7c1e509bfec91462420f3a0" ] } } } ``` The API will respond with an array of the **audience-segment-id**, **operation**, **date of request**, **identifierType**, number of valid or invalid identifiers, and a sample of invalid identifiers if applicable. ```json Example Response Body - Adding Users theme={null} { "data": { "type": "ContactlistAmendment", "attributes": { "contactListId": "12", "operation": "add", "requestDate": "2018-12-10T10:00:50.000Z", "identifierType": "email", "nbValidIdentifiers": 7343, "nbInvalidIdentifiers": 13, "sampleInvalidIdentifiers": [ "InvalidIdentifier" ] } }, "errors": [], "warnings": [] } ``` #### Removing Users To remove users from an audience segment, use the 'remove' operation in the `PATCH` request as detailed below: ```json JSON theme={null} { "data": { "type": "ContactlistAmendment", "attributes": { "operation": "remove", "identifierType": "email", "identifiers": [ "example1@gmail.com" ] } } } ``` The API will respond similarly to the add users call, but with `remove` as the operation. ```json theme={null} { "data": { "type": "ContactlistAmendment", "attributes": { "contactListId": "12", "operation": "remove", "requestDate": "2018-12-10T10:00:50.000Z", "identifierType": "email", "nbValidIdentifiers": 7342, "nbInvalidIdentifiers": 13, "sampleInvalidIdentifiers": [ "InvalidIdentifier" ] } }, "errors": [], "warnings": [] } ``` **Identifier List Size Limit** Note that there is a limit of 50,000 identifiers per single request. If you are adding more than 50,000 users, please split them into chunks of 50,000 and make multiple requests. *** ### Deleting All Users To delete all users from an audience segment, a `DELETE` request can be made to the audience segment contact list endpoint with the specified audience segment id in the URL path. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/{audience-segment-id}/contact-listaudience-segment-id}/contact-list ``` The API will return an array with the specified `audience-segment-id` from which all users were deleted. ```json JSON theme={null} { "data": { "type": "ContactListAudienceSegment", "id": "12" }, "errors": [], "warnings": [] } ``` Note that this will only wipe all of the users from the audience segment and will not delete the audience segment itself. **Note on Audience Computation** Audience updates are processed daily at 0h UTC and 12h UTC and can take around 5 hours to reflect on a live campaign. This is important for audiences that are frequently updated as changes should be ready for processing prior to these two times. *** ## Get Segment Statistics Get the statistics of the contact list audience segment associated with the given ID.\ The endpoint returns the size and other statistics available for an audience segment of the type contact list.\ If the given ID is not of the type contact list, an error is returned. `audience-segment-id` is the Id of the Contact List segment. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/audience-segments/{audience-segment-id}/contact-list/statistics ``` **Sample response** ```json JSON theme={null} { "data": { "id": "1001", "type": "ContactListAudienceSegment" "attributes": { "numberOfIdentifiers": 1000, "numberOfMatches": 500, "matchRate": 0.50 } } } ``` This statistic is not an estimation of the audience size. For it, refer to the [Estimate Audience Segment Size](/marketing-solutions/docs/audience-segments#estimate-audience-segment-size) section. *** # Validation Errors In addition to general API errors, you may encounter validation errors when creating or managing Audience Segments. Below is a list of error codes for Audience Segment Endpoints, and a more detailed description of their meaning. For more codes don't hesitate to check also the [Audiences validation errors](/marketing-solutions/docs/audiences#validation-errors) `advertiser-must-be-opt-in-for-data-sharing` Advertiser must be opt in for data sharing `brand-list-must-be-valid` Brand list must be valid `buying-power-must-be-valid` Buying power must be valid `cannot-create-contact-list` Contact list creation error `in-market-settings-must-be-defined` In-market segment settings must be defined `contact-list-incompatible-with-file` Contact list is incompatible with file `contact-list-statistics-not-supported` Contact list statistics are not supported on this segment `country-code-is-required` Country code is required `country-code-must-be-authorized` Country code must be authorized `country-code-must-be-valid` Country code must be valid `days-must-be-in-range` Days in omnichannel segment must be in range `event-type-must-be-valid` Event type must be valid `file-id-must-be-valid` File ID must be valid `gender-must-be-valid` Gender must be valid `interests-list-must-be-valid` Interest list must be valid `name-must-be-unique` Name must be unique `name-must-not-be-empty` Name must not be empty `name-must-not-be-too-long` Segment name property must not be too long `percentile-must-be-in-range` Percentile must be in range `poi-coordinates-must-be-unique` Points of interest coordinates must be unique `poi-coordinates-must-be-valid` Points of interest coordinates must be valid `poi-list-must-be-not-empty` Points of interest list must be nor null nor empty `poi-list-must-be-null-or-empty` Points of interest list must be null or empty `poi-radius-must-be-not-null` Location segment of type 'Unknown' must have a radius `poi-surface-must-be-valid` Points of interest surface area must be valid `price-range-must-be-valid` Price range must be valid `radius-must-be-in-range` RadiusInKm must be in range `registry-type-must-be-valid` Registry type must be valid `retargeting-segment-days-since-last-visit-are-not-compatible` Retargeting segment MinDaysSinceLastVisit and MaxDaysSinceLastVisit are not compatible `retargeting-segment-days-since-last-visit-are-not-in-acceptable-range` Retargeting segment MinDaysSinceLastVisit and MaxDaysSinceLastVisit are not in the range of acceptable values `segment-has-not-been-found` Segment does not exist `segment-must-have-valid-segment-id` Segment must have a valid segment ID `segment-must-not-be-used-in-audience` Segment must not be used in an audience `segment-not-found` Segment not found `segment-size-not-available` Segment size not available `segment-size-not-available` Segment size cannot be calculated `segment-size-not-supported` Segment size not supported `segment-size-too-small` Segment size is too small `type-must-be-the-same` Type must be the same `Target size must be within the supported rage` In Lookalike Audience Segments, given target size must be within the supported rage. Lower and Upper bound will be included in error details. `Seed segment does not belong to the same advertiser` For Lookalike Audience Segments, the seed segment (seedSegmentId input value) should have the same advertiser Id as the newly created Lookalike segment. `retargeting-segment-from-to-days-ago-are-not-compatible` The From days ago value should be lower than To days ago `retargeting-segment-from-to-days-ago-are-not-in-acceptable-range` Days must be in range: 400 >= ToDaysAgo > FromDaysAgo >= 0 `audience-with-retargeting-segment-must-be-correctly-specified` The retargeting segment must be the unique segment in its audience ## What's next * [Algebra Nodes](/marketing-solutions/docs/algebra-nodes) # Audiences Source: https://developers.criteo.com/marketing-solutions/docs/audiences ## **Introduction** Criteo's **Audience API** allows you to manage your contact lists by creating, deleting, and updating audience data, which is used for your advertising campaigns. You can manage available information including the **name** of your audience, the **description** of the audience, and the **users** included in an audience. You can also retrieve audience data such as the total **number of users** in an audience and the total number of **matched users** in an audience compared to Criteo's Shopper Graph. *** ## **Audience API Endpoint** ```http theme={null} https://api.criteo.com/2026-01/audiences ```
# Authentication Source: https://developers.criteo.com/marketing-solutions/docs/authentication ## Introduction To get started with our APIs, you will need to use the endpoint below to generate an Access Token, with your API credentials or authorization code. The Access Token is a Bearer token that needs to be included in the Authorization Header of all API requests. Multiple tokens may be generated and each is valid for 15 minutes, or 900 seconds *** ## Endpoint ### Generate an Access Token ```http theme={null} POST https://api.criteo.com/oauth2/token ``` If you receive a `401 Unauthorized` HTTP status code, it means your access token has expired. Generate a new token to continue making authenticated requests. **Reference** You can find this endpoint in [our Reference section](/marketing-solutions/reference/authorization/get-token) as well. *** ## Parameters

Parameter

Type

Description

client\_id

string

Please see below for instructions on getting your credentials through Partner Dashboard

client\_secret

string

Please see below for instructions on getting your credentials through Partner Dashboard

grant\_type

string

Must be client\_credentials or authorization\_code

code

string

Only for Authorization Code apps . Authorization code returned during redirection

redirect\_uri

string

Only for Authorization Code apps . Must match the redirect\_uri used for the authorization request.

*** ## Generate an Access Token * This endpoint generates a new access token using your API credentials or authorization code. * To comply with the OAuth2 standards of using `client_credentials`, Criteo API authorization supports `Content-Type: application/x-www-form-urlencoded`, as shown in the example below: ```http theme={null} POST https://api.criteo.com/oauth2/token ``` ```bash Bash theme={null} // Sample Request curl --location --request POST 'https://api.criteo.com/oauth2/token' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'client_id=CLIENT_ID' --data-urlencode 'client_secret=CLIENT_SECRET' --data-urlencode 'grant_type=client_credentials' // Sample Response { "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkVuTTBCZkFELUFrNXZwOU9RMW1ZWXR6T2RaMUVad2RWaHY5T3Z2cVA3YVUiLCJ0eXAiOiJKV1QifQ.eyJjdHg6dXNlcjpkaXNwbGF5TmFtZSI6IkJvYmJ5IFNpYW8gTGVpIEhhbiIsImN0eDp1c2VyOmVtYWlsIjoiYi5oYW5AY3JpdGVvLmNvbSIsImN0eDp1c2VyOnVpZCI6ImIuaGFuIiwiY3R4OnVzZXI6dW1zSWQiOiIzMjM4ODQiLCJzdWIiOiJ1Omk6Yi5oYW5AY3JpdGVvLmNvbSIsImlhdCI6MTYwMTQwNDM1NSwiZXhwIjoxNjAxNDA1MzE1LCJhZGQ6bWFwaTp1bmFtZSI6ImIuaGFuIiwic2NvcGUiOiJnYXRld2F5IiwiY2xpZW50X2lkIjoiYi5oYW4iLCJuYmYiOjE2MDE0MDQ0MTUsImlzcyI6ImNyaXRlby1leGFtb2F1dGgifQ.OI1W8utCbR2a2VbkxOZZaP2JyQ4b8Kf9R2x_yGRp9jjqclvm8huC_iHb9AECLmYVMUYWojvmbIOk0j0BRfLf1xYoOAIvNbcWN-SsrkYOXVh9mYruwOfKJb0t6j8MW7u03PbfvSRtn_29ar3V-7rimDqdMR_iTVhTlBLI0W3jSOCjzKK9sbg0REwtneBu4V3dFLaLNIxXj5EtyaTpLB3v71smFljBHtUC1Go8wRUX2P_GZfWYJCZhatx0xsN46oS8aGQl3a6N4nh4cqdJNA83Y44LYEKpky0ZmBwC9D5j9rpC-BDkUaeWlgkVSicy6yWh-S06JC4e3pJwUHskUMvoiA", "token_type": "Bearer", "expires_in": 900 } ``` **Mandatory Content-Type header** Please ensure you include `Content-Type: application/x-www-form-urlencoded` header in your call to the `/oauth2/token` endpoint. *** ## Use an Access Token Once you have obtained your access token, you can authenticate for all subsequent requests by including an `Authorization` HTTP header, as shown in the example below: ```http Header theme={null} GET https://api.criteo.com/2020-10/advertisers/me Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkVuTTBCZkFELUFrNXZwOU9RMW1ZWXR6T2RaMUVad2RWaHY5T3Z2cVA3YVUiLCJ0eXAiOiJKV1QifQ.eyJjdHg6dXNlcjpkaXNwbGF5TmFtZSI6IkJvYmJ5IFNpYW8gTGVpIEhhbiIsImN0eDp1c2VyOmVtYWlsIjoiYi5oYW5AY3JpdGVvLmNvbSIsImN0eDp1c2VyOnVpZCI6ImIuaGFuIiwiY3R4OnVzZXI6dW1zSWQiOiIzMjM4ODQiLCJzdWIiOiJ1Omk6Yi5oYW5AY3JpdGVvLmNvbSIsImlhdCI6MTYwMTQwNDM1NSwiZXhwIjoxNjAxNDA1MzE1LCJhZGQ6bWFwaTp1bmFtZSI6ImIuaGFuIiwic2NvcGUiOiJnYXRld2F5IiwiY2xpZW50X2lkIjoiYi5oYW4iLCJuYmYiOjE2MDE0MDQ0MTUsImlzcyI6ImNyaXRlby1leGFtb2F1dGgifQ.OI1W8utCbR2a2VbkxOZZaP2JyQ4b8Kf9R2x_yGRp9jjqclvm8huC_iHb9AECLmYVMUYWojvmbIOk0j0BRfLf1xYoOAIvNbcWN-SsrkYOXVh9mYruwOfKJb0t6j8MW7u03PbfvSRtn_29ar3V-7rimDqdMR_iTVhTlBLI0W3jSOCjzKK9sbg0REwtneBu4V3dFLaLNIxXj5EtyaTpLB3v71smFljBHtUC1Go8wRUX2P_GZfWYJCZhatx0xsN46oS8aGQl3a6N4nh4cqdJNA83Y44LYEKpky0ZmBwC9D5j9rpC-BDkUaeWlgkVSicy6yWh-S06JC4e3pJwUHskUMvoiA Accept: text/plain Content-Type: application/*+json ``` **OAuth Flow** You can find more details about how to implement OAuth flow for the different authentication methods in our [OAuth implementation](/marketing-solutions/docs/oauth-implementation) guides. ## What's next * [OAuth Implementation](/marketing-solutions/docs/oauth-implementation) * [/oauth2/token](/marketing-solutions/reference/authorization/get-token) # Campaign Source: https://developers.criteo.com/marketing-solutions/docs/campaign ## Campaign Example The following is an example of the JSON data structure of a Campaign. Additional details about the individual attributes of Campaigns can be found below. ```json JSON theme={null} { "type": "Campaign", "attributes": { "name": "My Campaign", "advertiserId": "12345", "goal": "Retention", "spendLimit": { "spendLimitType": "capped", "spendLimitRenewal": "daily", "spendLimitAmount": 123.45 }, "budgetAutomation": { "enabled": true, "budgetConfiguration": { "adSetObjectives": "conversions" } } } } ``` *** ## Campaign Attributes **`name`**\ Currently read-only. The Campaign name, set by the advertiser. **`advertiserId`**\ Read-only. The advertiser associated with the Campaign. **`goal`**\ The marketing goal of the Campaign. Can be `Acquisition`, `Retention` or `Unspecified` (only for older campaigns). **`spendLimit.spendLimitType`**\ Whether the Campaign spend is capped or not. Can be `capped` or `uncapped`. **`spendLimit.spendLimitRenewal`**\ The cadence of spend limit renewal. Can be `daily`, `monthly`, `lifetime`, or `undefined`. The value `undefined` is only returned for an `uncapped` spend limit. **`spendLimit.spendLimitAmount`**\ A decimal value representing the spend limit for the Campaign in the advertiser's currency. It is required when `spendLimitType` is `capped`. If `spendLimitType` is `uncapped`, the value is `null`. In `PATCH` requests, set it to `null` when switching a Campaign to `uncapped`. **`budgetAutomation.enabled`**\ Whether Campaign-level budget automation is active. To enable budget automation, set this field to `true` and provide a valid `budgetConfiguration`. If omitted, it defaults to `false`. **`budgetAutomation.budgetConfiguration.adSetObjectives`**\ The optimization objective used by budget automation. Can be `conversions`, `revenue`, `visits`, or `videoViews`. This field is required when `budgetAutomation.enabled` is `true`. *** ## Create a campaign A new campaign can be created for a specific advertiser by making a `POST` call to the Campaign's endpoint.\ The request body should specify the type (`Campaign`) and the [campaign attributes](/marketing-solutions/docs/campaign#campaign-attributes). **Spend Limit** If `spendLimitType` is `capped`, both `spendLimitRenewal` and `spendLimitAmount` are required. If `spendLimitType` is `uncapped`, omit `spendLimitRenewal` and `spendLimitAmount` from the request. The response returns `spendLimitRenewal` as `undefined` and `spendLimitAmount` as `null`. **`Goal`** The field `goal` is mandatory and can be either `Acquisition` or `Retention`. **Budget Automation** `budgetAutomation` is optional. To create a Campaign with budget automation enabled, set `enabled` to `true` and provide `budgetConfiguration.adSetObjectives`. If `budgetAutomation` is omitted, the Campaign is created with budget automation disabled. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/campaigns ``` **Request sample** ```json JSON theme={null} { "data": { "type": "Campaign", "attributes": { "name": "My Campaign", "advertiserId": "12345", "goal": "Retention", "spendLimit": { "spendLimitType": "capped", "spendLimitRenewal": "daily", "spendLimitAmount": 123.45 }, "budgetAutomation": { "enabled": true, "budgetConfiguration": { "adSetObjectives": "conversions" } } } } } ``` **Response sample** The API will return an array of ID, the type (`Campaign`) and the Campaign attributes of the new Campaign. ```json theme={null} { "data": { "id": "99999", "type": "Campaign", "attributes": { "name": "My Campaign", "advertiserId": "12345", "spendLimit": { "spendLimitType": "capped", "spendLimitRenewal": "daily", "spendLimitAmount": 123.45 }, "budgetAutomation": { "enabled": true, "budgetConfiguration": { "adSetObjectives": "conversions" } }, "goal": "Retention" } }, "warnings": [], "errors": [] } ``` *** ## Searching Campaigns ### Retrieving Campaigns by Filtering Campaigns can be retrieved by specifying filters to apply to the set of all campaigns in your portfolio. Using filters, you can restrict the returned results to particular `advertiserIds` or specific `campaignIds`. Filters can be combined. For example, to retrieve the Campaigns in your portfolio related to a particular advertiser, filter by `advertiserIds`: ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/campaigns/search ``` **Sample request** ```json JSON theme={null} { "filters": { "advertiserIds": ["12345"] } } ``` **Sample response** The API will return an array of Campaigns that match the provided filters: ```json JSON theme={null} { "data": [ { "type": "Campaign", "id": "99999", "attributes": { "name": "My Campaign", "advertiserId": "12345", "goal": "Retention", "spendLimit": { "spendLimitType": "capped", "spendLimitRenewal": "daily", "spendLimitAmount": 123.45 }, "budgetAutomation": { "enabled": true, "automatedBudgetConfiguration": { "adSetOptimizationObjective": "conversions" } } } } ], "errors": [] } ``` *** ### Retrieving All Campaigns When no filters are specified in the JSON payload, all campaigns in your portfolio will be returned, as in the example below: ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/campaigns/search ``` ```json JSON theme={null} { "filters": {} } ``` *** ### Retrieving One Specific Campaign You can also fetch the details for a single Campaign using a `GET` request: ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/campaigns/{campaign-id} ``` **Sample response**  The response `data` will be a single object containing the Campaign details. ```json JSON theme={null} { "data": { "type": "Campaign", "id": "99999", "attributes": { "name": "My Campaign", "advertiserId": "12345", "goal": "Retention", "spendLimit": { "spendLimitType": "capped", "spendLimitRenewal": "daily", "spendLimitAmount": 123.45 }, "budgetAutomation": { "enabled": true, "automatedBudgetConfiguration": { "adSetOptimizationObjective": "conversions" } } } }, "errors": [] } ``` *** ## Update Campaigns The fields of one or more Campaigns can be updated by making a `PATCH` call to the Campaigns endpoint. The payload should be an array of partial or whole Campaigns, each specifying the fields to be modified. For example, the following call would update the `spendLimit` settings of an existing Campaign: ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/campaigns ``` **Sample request** ```json JSON theme={null} { "data": [ { "type": "Campaign", "id": "99999", "attributes": { "spendLimit": { "spendLimitType": "capped", "spendLimitRenewal": "daily", "spendLimitAmount": 123.45 }, "budgetAutomation": { "enabled": true, "budgetConfiguration": { "adSetObjectives": "conversions" } } } } ] } ``` **Sample response** The API will return an array of Campaigns that have been updated successfully in the response `data`.\ These will contain only two parameters, `type` and `id`. ```json JSON theme={null} { "data": [ { "type": "Campaign", "id": "99999" } ], "errors": [], "warnings": [] } ``` *** ## Partial Success / Partial Failure Each Campaign update is processed individually and can succeed or fail without impacting other updates in the same payload. As a result, those Campaign updates processed successfully will be returned in the `data` array of the response, while Campaign updates that have failed will return as an entry in the `errors` array of the response. **HTTP Response Codes** As a result of this individual processing, the API may respond with a `200` HTTP response code, but the result of its processing may have one or more failures.  For instance, for this payload which intends to update two Campaigns: ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/campaigns ``` **Sample request** ```json JSON theme={null} { "data": [ { "type": "Campaign", "id": "99999", "attributes": { "spendLimit": { "spendLimitRenewal": "daily", "spendLimitType": "capped", "spendLimitAmount": 123.5 } } }, { "type": "Campaign", "id": "88888", "attributes": { "spendLimit": { "spendLimitRenewal": "daily", "spendLimitType": "capped", "spendLimitAmount": -9000 } } } ] } ``` **Sample response** ```json JSON theme={null} { "data": [ { "type": "Campaign", "id": "99999" } ], "errors": [ { "traceIdentifier": "56ed4096-f96a-4944-8881-05468efe0ec8", "type": "validation", "code": "campaign--campaign-update-check--validation-failed-on-spend-limit", "instance": "@data/1", "title": "Validation failed on spend limit", "detail": "There was an issue with the spend limit value specified." } ], "warnings": [] } ``` **Error `instance`** The `instance` field for validation errors will specify the index of the related update, beginning with index 0. For the example above, `@data/1` refers to the second requested update in the request's `data` array. A full list of error codes can be found on the [Validation Errors](/marketing-solutions/docs/campaign#validation-errors-and-warnings) page at the end of this section.\ In addition to [general API errors](/criteo-apis/docs/api-error-types) , you may encounter validation errors when updating a Campaign. Below is a list of error codes for Campaign validation and a more detailed description of their meaning. *** ## Validation Errors and Warnings **Campaign Update Errors:**\ **`campaign--campaign-update-check--spend-limit-does-not-exist`**\ An update to spend limit was attempted on a Campaign which does not have a spend limit (e.g. an uncapped Campaign). Alternatively, the requestor may not have permissions to update the spend limit of the Campaign. **`campaign--campaign-update-check--cannot-decrease-lifetime-spend-limit-below-what-is-already-spent`**\ An update attempted to decrease a *lifetime* spend limit of a Campaign to a value lower than what has already been spent. **`campaign--campaign-update-check--validation-failed-on-spend-limit`**\ TK **`campaign--campaign-update-check--cannot-update-same-campaign-multiple-times`**\ The Campaign is included multiple times in the same update payload. All Campaign field updates should be consolidated into one array item. **`campaign--campaign-update-check--unavailable-feature-for-this-advertiser`**\ TK **Campaign Update Warnings:**\ **`campaign--campaign-update-check--new-spend-limit-amount-will-take-place-at-the-next-period-start`**\ The update to spend limit was processed, but it will not take effect until the next period specified by `spendLimitRenewal` (e.g. the next day). This is typically because the new spend amount specified is lower than the amount already spent in the current period. ## What's next * [Ad Set](/marketing-solutions/docs/ad-set) * [Display Multipliers](/marketing-solutions/docs/display-multipliers) * [Category Bids](/marketing-solutions/docs/category-bids) # Campaign Statistics Source: https://developers.criteo.com/marketing-solutions/docs/campaign-statistics ## **Retrieving Statistics for a Specific Advertiser** The statistics endpoint allows measurement and reporting on campaigns using specified metrics and dimensions. **Response example:** ```json JSON theme={null} { "advertiserIds": "12345", "startDate": "2020-09-10T04:00:00.000Z", "endDate": "2020-09-14T04:00:00.000Z", "format": "csv", "dimensions": ["AdsetId","Day"], "metrics": ["Displays","Clicks"], "timezone": "PST", "currency": "USD" } ```  A report is generated via a `POST` call and the results are returned directly in the response. **Response example:** ```csv CSV theme={null} AdsetId;Day;Currency;Displays;Clicks 54321;2020/9/10;USD;2534;35 54321;2020/9/11;USD;6234;96 54321;2020/9/12;USD;4357;54 54321;2020/9/13;USD;3245;45 54321;2020/9/14;USD;4584;72 ``` *** ### **Creating a Report Request** A complete statistics report request requires the following fields:

Parameter

Definition

Type

Required?

advertiserIds

A list of advertiser ids (comma separated)

string

N

currency

The currency to be used in the report, ISO format.

A list of supported currencies is available here.

string

Y

startDate

Start date, ISO 8601 format.

string

Y

endDate

End date, ISO 8601 format.

string

Y

format

The output format. CSV, JSON, XML or EXCEL.

string

Y

dimensions

See the Dimensions page.

Arrayk:api-he

Y

metrics

See the Metrics page.

Arrayk:api-he

Y

timezone

The timezone for organizing the data in the report.

A list of supported values is available here.

string

N

UTC will be default timezone if not specified.

  **A Note on `AdvertiserIds`** Advertisers which are not in your portfolio will be skipped. The specified advertisers must have at least one campaign to appear in the report. If you do not specify any value for `advertiserIds`, statistics for all advertisers in your portfolio will be returned. *** ## **Response Codes** The following response codes may be returned by the API: `400`: Bad request, invalid syntax or validation error. Review the request to make sure the format is valid.\ `401`: Authentication failed. Ensure the authentication header is formatted properly and your access token hasn't expired.\ `403`: No campaign found. Verify your campaign IDs are correct.\ `429`: Throttling failure. Wait a minute to try again - there is a limit of 200 requests per minute.\ `500`: Unknown error **HTTP Error Status Codes**\ You can find the full list of error status codes [here](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes). *** ## **Validation Errors** Below is a list of error codes for the Statistics endpoint and a more detailed description of their meaning. General guidance on handling API errors can be found [here](/criteo-apis/docs/api-error-types). **`duplicate-dimensions`**\ Duplicate dimension(s) found. **`duplicate-metrics`**\ Duplicate metrics(s) found.. **`insufficient-advertiser-permission`**\ Insufficient advertiser permission. **`insufficient-advertisers-permissions`**\ Insufficient advertisers permission. **`invalid-country`**\ This feature is currently unavailable in the country of advertiser. **`invalid-currency`**\ Invalid currency. **`invalid-date-range`**\ The start date can not be after the end date. **`invalid-environment`**\ Invalid environment. **`invalid-event-type`**\ Invalid Event Type. **`invalid-format`**\ Format is not valid. Must be one of 'csv', 'xml', 'excel' or 'json'. **`invalid-start-date`**\ The start date is too old. **`invalid-timezone`**\ Invalid time zone. **`report-generation-failed`**\ A problem occurred while generating the report. **`required-field`**\ The required field is missing. Examples: * A start date and end date are required. * At least one metric must be provided. * At least one dimension must be provided. * Payload is required. * Currency is required. * At least one advertiser id must be provided.  **`required-request-body`**\ Request body is required. **`unsupported-dimensions`**\ A request is invalid or the server wasn't able to process the request due to a serialization error. **`unsupported-dimensions-combination`**\ The requested dimensions combination is not supported. **`invalid-metrics`**\ The requested metrics are not supported. *** ## **Dimensions** Dimensions allow you to specify the aggregation level suited to your needs. There are no restrictions on the number of dimensions or the order of dimensions. The full list is below:

Type

Dimension

Campaign

AdsetId , Adset , AdvertiserId , Advertiser , CategoryId , Category , CampaignId , Campaign , AdId , Ad , CouponId , Coupon , MarketingObjectiveId , MarketingObjective

Time

Hour , Day , Week , Month , Year

Other

ChannelId , Channel , Os , Device

The `dimensions` array of the stats request should contain all requested dimensions. For example: `['Advertiser','Adset','Day','Hour']` **Names vs. IDs** In the dimensions above, `Advertiser` will return the name of the advertiser, whereas `AdvertiserId` returns the numerical ID. *** ## **Metrics** ### **Naming Convention** Metrics are created with a common structure, such as: `SalesAllPc30d` The naming follows the following pattern:\ `[Measurement][Devices][AttributionModel][LookbackWindow] ` **Measurement**\ What you would like to measure in your report.\ `Clicks`, `Displays`, `AdvertiserCost`, etc. (see full metrics list) **Devices**\ Cross-device sales are sales that occurred on a different device than the one where the click occurred. Specifying `All` includes cross-device sales.\ `All` **Attribution Model**\ A sale is attributed when your customer sees or clicks an ad and converts within a specified window of time. It could be post-click, post-view or your custom attribution, if you send us your attribution data for sales.\ `Pc`,`Pv`, `ClientAttribution` If you are using a newly introduced lookback window (`PC1D`, `PC7D`), your request won’t return data prior to January 1st, 2020. The request will deliver a 0 for these metrics. **Lookback Window**\ The time between a sale and the view or click of an ad.\ `30D`, `7D`, `1D`, `24H` ### **Full List of Metrics** Metrics refer to measurements such as **clicks**, **revenue**, or **cost per visit**. All metrics available in Criteo Commerce Growth are available through the Statistics API v2.   The following is a list of available metrics in Criteo Commerce Growth (**bolded**) and their corresponding metric names for the `metrics` array of your request. **A note about percentages** Percentages will be returned as decimal values between 0 and 1. For example, 99.99% will be returned as .9999  \  **Clicks**\ The number of clicks driven by your ads.\ `Clicks` **Displays**\ The number of ad impressions served on publishers via Criteo.\ `Displays` **Viewed displays**\ The number of ads that have been viewed. A display is considered viewed if at least 50% of the ad appears on the screen for at least one second.\ `ViewableDisplays` **Unviewed displays**\ The number of ads that have not been viewed. A display that doesn't meet the viewed displays' criteria is considered unviewed.\ `NonViewableDisplays` **Untracked displays**\ This is the number of untracked displays. Some displays cannot be tracked because of the display environment (for instance, native banner)\ `UntrackableDisplays` **Cost**\ Total money spent on Criteo advertising.\ `AdvertiserCost` **Qualified Visits**\ The number of users on the target website or app for which at least two events or one sale event occurred within the hour following a click.\ `QualifiedVisits` **Visits**\ The number of users on the target website or app for which at least one event occurred within the hour following a click.\ `Visits` **Cost per Visit**\ The amount of money spent per visit to your website or app.\ `CostPerVisit` **Bounce Rate**\ The proportion of website visitors leaving after only viewing one page.\ `BounceRate` **Potential Displays**\ The number of display opportunities, or the number of bid requests received.\ `PotentialDisplays` **Win Rate**\ The number of displays divided by the total number of display opportunities.\ `OverallCompetitionWin` **Sales**\ The number of transactions or conversions resulting from Criteo ads.\ `SalesClientAttribution`,`SalesAllClientAttribution`,`SalesPc30d`,`SalesAllPc30d`,`SalesPv24h`,`SalesAllPv24h`,`SalesPc30dPv24h`,`SalesAllPc30dPv24h`,`SalesPc1d`,`SalesAllPc1d`,`SalesPc7d`,`SalesAllPc7d` **Revenue**\ The amount of money generated by online sales.\ `RevenueGeneratedClientAttribution`,`RevenueGeneratedAllClientAttribution`,`RevenueGeneratedPc30d`,`RevenueGeneratedAllPc30d`,`RevenueGeneratedPv24h`,`RevenueGeneratedAllPv24h`,`RevenueGeneratedPc30dPv24h`,`RevenueGeneratedAllPc30dPv24h`,`RevenueGeneratedPc1d`,`RevenueGeneratedAllPc1d`,`RevenueGeneratedPc7d`,`RevenueGeneratedAllPc7d` **Exposed Users**\ The number of users who have been served an ad.\ `ExposedUsers` **Audience**\ Potential users who could be served an ad.\ `Audience` **Reach**\ Share of potential users who have been served an ad.\ `Reach` **A Note about Audience and Reach with the Category Dimension** The algorithm used for merging audience count across categories is non-commutative (by design). It is expected that Audience and Reach metrics produce slightly different results when queried with and without the category dimension. **Average Cart**\ Average revenue generated by a conversion or sale.\ `AverageCartClientAttribution`, `AverageCartAllClientAttribution`, `AverageCartPc30d`, `AverageCartAllPc30d`, `AverageCartPv24h`, `AverageCartAllPv24h`, `AverageCartPc30dPv24h`, `AverageCartAllPc30dPv24h`, `AverageCartPc1d`, `AverageCartAllPc1d`, `AverageCartPc7d`, `AverageCartAllPc7d` **CTR (Click Through Rate)**\ Percentage of users served an ad who clicked.\ `ClickThroughRate` **CVR (Conversion Rate)**\ Percentage of conversions or sales compared to the clicks that occurred.\ `ConversionRateClientAttribution`,`ConversionRateAllClientAttribution`,`ConversionRatePc30d`,`ConversionRateAllPc30d`,`ConversionRatePv24h`,`ConversionRateAllPv24h`,`ConversionRatePc30dPv24h`,`ConversionRateAllPc30dPv24h`, `ConversionRatePc1d`,`ConversionRateAllPc1d`,`ConversionRatePc7d`,`ConversionRateAllPc7d` **COS (Cost of Sale)**\ Advertising cost per conversion or sale.\ `ECosClientAttribution`,`ECosAllClientAttribution`,`ECosPc30d`,`ECosAllPc30d`,`ECosPv24h`,`ECosAllPv24h`,`ECosPc30dPv24h`,`ECosAllPc30dPv24h`,`ECosPc1d`,`ECosAllPc1d`,`ECosPc7d`,`ECosAllPc7d` **CPO (Cost perOrder)**\ The price you pay for each order. Calculated as total cost divided by the total number of orders.\ `CostPerOrderClientAttribution`,`CostPerOrderAllClientAttribution`,`CostPerOrderPc30d`,`CostPerOrderAllPc30d`,`CostPerOrderPv24h`,`CostPerOrderAllPv24h`,`CostPerOrderPc30dPv24h`,`CostPerOrderAllPc30dPv24h`,`CostPerOrderPc1d`,`CostPerOrderAllPc1d`,`CostPerOrderPc7d`,`CostPerOrderAllPc7d` **CPC (Cost per Click)**\ Cost per click.\ `Cpc` **CPM (Cost per Mille)**\ Cost per 1000 Impressions.\ `ECpm` **ROAS (Return on Ad Spend)**\ The ratio between revenue generated and the cost.\ `RoasClientAttribution`,`RoasAllClientAttribution`,`RoasPc30d`,`RoasAllPc30d`,`RoasPv24h`,`RoasAllPv24h`,`RoasPc30dPv24h`,`RoasAllPc30dPv24h`,`RoasPc1d`,`RoasAllPc1d`,`RoasPc7d`,`RoasAllPc7d` **Advertiser Value**\ The revenue generated by each product, considering margin (if provided in your product catalog).\ `AdvertiserValue`,`AdvertiserAllValue` **COV (Cost of Advertiser Value)**\ The ratio between the advertiser value generated by sales and the cost of the campaign(s), given as a percentage.\ `CostOfAdvertiserValue`,CostOfAdvertiserValueAll\` **Post-Install Sales**\ The number of your completed events after an app install.\ `PostInstallSales` **App Installs**\ The number of installations of your app.\ `AppInstalls` **Post-Install CVR (Conversion Rate)**\ Percentage of post-install sales compared to the clicks that occurred.\ `PostInstallConversionRate` **Post-Install COS (Cost of Sale)**\ The cost of sale for app install campaigns.\ `PostInstallCostOfSale` **Post-Install Order Value**\ The amount of money generated by sales after an app install.\ `PostInstallOrderValue` **Cost per Install**\ The ad cost per app install.\ `CostPerInstall` **Install Rate**\ The percentage of completed app installs compared to the number of clicks.\ `InstallRate` **Post-Install CPO (Cost per Order)**\ The cost per order for sales after an app install.\ `PostInstallCostPerOrder` **Post-Install ROAS**\ The return on ad spend for sales after an app install.\ `PostInstallRoas` **Omnichannel ROAS (Return on Ad Spend)**\ The ratio between revenue generated online and offline, and the cost.\ `OmnichannelRoasClientAttribution`,`OmnichannelRoasPc30d`,`OmnichannelRoasAllPc30d`,`OmnichannelRoasPv24h`,`OmnichannelRoasAllPv24h` **Omnichannel Revenue**\ The revenue generated by online and offline sales.\ `OmnichannelRevenueClientAttribution`,`OmnichannelRevenuePc30d`,`OmnichannelRevenueAllPc30d`,`OmnichannelRevenuePv24h`,`OmnichannelRevenueAllPv24h` **Omnichannel Sales**\ The number of online and offline transactions or conversions resulting from Criteo ads.\ `OmnichannelsalesClientAttribution`,`OmnichannelSalesPc30d`,`OmnichannelSalesAllPc30d`,`OmnichannelSalesPv24h`,`OmnichannelSalesAllPv24h` **Store ROAS**\ The ratio between the revenue generated offline and the cost.\ `RoasOfflinePc30d`,`RoasOfflinePv24h` **Store Sales**\ The number of completed in-store transactions or purchases.\ `SalesOfflinePc30d`,`SalesOfflinePv24h` **Store Revenue**\ The amount of revenue generated by in-store sales.\ `RevenueGeneratedOfflinePc30d`,`RevenueGeneratedOfflinePv24h` *** ## **Currencies** Below is a table of all currency codes supported for the `currency` field of your stats report requests.

Currency Code

Symbol

Full Name

EUR

Euro

USD

\$

US Dollar

GBP

£

British Pound

CHF

Ch

Swiss Franc

JPY

¥

Japanese Yen

BGN

Л

Bulgarian Lev

CZK

K

Czech Koruna

DKK

Kr

Danish Krone

HUF

Ft

Hungarian Forint

LTL

Lt

Lithuanian Litas

PLN

Z

Polish Zloty

RON

Le

Romanian New Leu

SEK

Kr

Swedish Krona

NOK

Kr

Norwegian Krone

HRK

Kn

Croatian Kuna

RUB

Р

Russian Ruble

TRY

Tl

Turkish Lira

AUD

\$

Australian Dollar

BRL

R\$

Brazilian Real

CAD

\$

Canadian Dollar

CNY

¥

Chinese Yuan Renminbi

HKD

Hk

Hong Kong Dollar

IDR

Rp

Indonesian Rupiah

INR

Rs

Indian Rupee

KRW

N/A

South Korean Won

MXN

\$

Mexican Peso

MYR

Rm

Malaysian Ringgit

NZD

\$

New Zealand Dollar

PHP

N/A

Philippine Peso

SGD

\$

Singapore Dollar

THB

N/A

Thai Baht

ZAR

R

South African Rand

ARS

\$

Argentine Peso

COP

\$

Colombian Peso

AED

د

United Arab Emirates Dirham

KZT

Т

Kazakhstani Tenge

SAR

N/A

Saudi Riyal

UAH

N/A

Ukrainian Hryvnia

EGP

£

Egyptian Pound

MAD

Dh

Moroccan Dirham

ILS

N/A

Israeli Shekel

BHD

Bd

Bahraini Dinar

JOD

Jd

Jordanian Dinar

KWD

ك

Kuwaiti Dinar

LBP

ل

Lebanese Pound

OMR

N/A

Omani Rial

QAR

N/A

Qatari Riyal

NGN

N/A

Nigerian Naira

KES

Ks

Kenyan Shilling

ALL

Le

Albania Lek

ETB

Br

Ethopian Birr

BSD

\$

Bahamian Dollar

BDT

N/A

Bangladeshi Taka

BAM

Km

Bosnia-Herzegovina Convertible Mark

BWP

P

Botswana Pula

MMK

K

Burmese Kyat

AFN

؋

Afghan Afghani

BTN

Nu

Bhutanese Ngultrum

GEL

N/A

Georgian Lari

GHS

Gh

Ghanaian Cedi

GIP

£

Gibraltar Pound

ISK

Kr

Icelandic Krona

KHR

N/A

Cambodian Riel

JMD

J\$

Jamaican Dollar

LAK

N/A

Lao Kip

MKD

Д

Macedonian Denar

MUR

N/A

Mauritian Rupee

MNT

N/A

Mongolian Tögrög

NPR

N/A

Nepalese Rupee

NAD

\$

Namibian Dollar

PKR

N/A

Pakistani Rupee

RWF

Fr

Rwandan Franc

LKR

N/A

Sri Lankan Rupee

SZL

L

Swazi Lilangeni

TZS

Ts

Tanzanian Shilling

TTD

Tt

Trinidad And Tobago Dollar

UGX

Us

Ugandan Shilling

ZMW

Zk

Zambian Kwacha

BOB

\$B

Bolivian Boliviano

CRC

N/A

Costa Rican Colón

DOP

Rd

Dominican Peso

GTQ

Q

Guatemalan Quetzal

HNL

L

Honduran Lempira

NIO

C\$

Nicaraguan Córdoba

PAB

B/

Panamanian Balboa

PYG

Gs

Paraguayan Guaraní

PEN

S/

Peruvian Nuevo Sol

UYU

\$U

Uruguayan Peso

VEF

Bs

Venezuelan Bolívar

XAF

Fr

Central African Cfa Franc

XOF

Fr

West African Cfa Franc

HTG

G

Haitian Gourde

MGA

Ar

Malagasy Ariary

DZD

د

Algerian Dinar

IQD

د

Iraqi Dinar

LYD

ل

Libyan Dinar

TND

د

Tunisian Dinar

YER

N/A

Yemeni Rial

BND

\$

Brunei Dollar

AOA

Kz

Angolan Kwanza

MZN

Mt

Mozambican Metical

AMD

Am

Armenian Dram

AZN

М

Azerbaijani Manat

KGS

Л

Kyrgyzstani Som

TJS

Tj

Tajikistani Somoni

UZS

Л

Uzbekistani Som

MDL

L

Moldovan Leu

RSD

Д

Serbian Dinar

XPF

Fr

Cfp Franc

MOP

Mo

Macanese Pataca

VND

N/A

Viet Nam Dong

TWD

Nt

Taiwan Dollar

CLP

\$

Chilean Peso

*** ## **Timezones** Below is a table of all timezone values supported for the `timezone` field of your stats report requests. UTC will be default timezone if not specified. | Continent / Country / City | | :------------------------------- | | Africa/Abidjan | | Africa/Accra | | Africa/Addis\_Ababa | | Africa/Algiers | | Africa/Asmara | | Africa/Bamako | | Africa/Bangui | | Africa/Banjul | | Africa/Bissau | | Africa/Blantyre | | Africa/Brazzaville | | Africa/Bujumbura | | Africa/Cairo | | Africa/Casablanca | | Africa/Ceuta | | Africa/Conakry | | Africa/Dakar | | Africa/Dar\_es\_Salaam | | Africa/Djibouti | | Africa/Douala | | Africa/El\_Aaiun | | Africa/Freetown | | Africa/Gaborone | | Africa/Harare | | Africa/Johannesburg | | Africa/Juba | | Africa/Kampala | | Africa/Khartoum | | Africa/Kigali | | Africa/Kinshasa | | Africa/Lagos | | Africa/Libreville | | Africa/Lome | | Africa/Luanda | | Africa/Lubumbashi | | Africa/Lusaka | | Africa/Malabo | | Africa/Maputo | | Africa/Maseru | | Africa/Mbabane | | Africa/Mogadishu | | Africa/Monrovia | | Africa/Nairobi | | Africa/Ndjamena | | Africa/Niamey | | Africa/Nouakchott | | Africa/Ouagadougou | | Africa/Porto-Novo | | Africa/Sao\_Tome | | Africa/Tripoli | | Africa/Tunis | | Africa/Windhoek | | America/Adak | | America/Anchorage | | America/Anguilla | | America/Antigua | | America/Araguaina | | America/Argentina/Buenos\_Aires | | America/Argentina/Catamarca | | America/Argentina/Cordoba | | America/Argentina/Jujuy | | America/Argentina/La\_Rioja | | America/Argentina/Mendoza | | America/Argentina/Rio\_Gallegos | | America/Argentina/Salta | | America/Argentina/San\_Juan | | America/Argentina/San\_Luis | | America/Argentina/Tucuman | | America/Argentina/Ushuaia | | America/Aruba | | America/Asuncion | | America/Atikokan | | America/Bahia | | America/Bahia\_Banderas | | America/Barbados | | America/Belem | | America/Belize | | America/Blanc-Sablon | | America/Boa\_Vista | | America/Bogota | | America/Boise | | America/Cambridge\_Bay | | America/Campo\_Grande | | America/Cancun | | America/Caracas | | America/Cayenne | | America/Cayman | | America/Chicago | | America/Chihuahua | | America/Costa\_Rica | | America/Creston | | America/Cuiaba | | America/Curacao | | America/Danmarkshavn | | America/Dawson | | America/Dawson\_Creek | | America/Denver | | America/Detroit | | America/Dominica | | America/Edmonton | | America/Eirunepe | | America/El\_Salvador | | America/Fortaleza | | America/Glace\_Bay | | America/Godthab | | America/Goose\_Bay | | America/Grand\_Turk | | America/Grenada | | America/Guadeloupe | | America/Guatemala | | America/Guayaquil | | America/Guyana | | America/Halifax | | America/Havana | | America/Hermosillo | | America/Indiana/Indianapolis | | America/Indiana/Knox | | America/Indiana/Marengo | | America/Indiana/Petersburg | | America/Indiana/Tell\_City | | America/Indiana/Vevay | | America/Indiana/Vincennes | | America/Indiana/Winamac | | America/Inuvik | | America/Iqaluit | | America/Jamaica | | America/Juneau | | America/Kentucky/Louisville | | America/Kentucky/Monticello | | America/Kralendijk | | America/La\_Paz | | America/Lima | | America/Los\_Angeles | | America/Lower\_Princes | | America/Maceio | | America/Managua | | America/Manaus | | America/Marigot | | America/Martinique | | America/Matamoros | | America/Mazatlan | | America/Menominee | | America/Merida | | America/Metlakatla | | America/Mexico\_City | | America/Miquelon | | America/Moncton | | America/Monterrey | | America/Montevideo | | America/Montserrat | | America/Nassau | | America/New\_York | | America/Nipigon | | America/Nome | | America/Noronha | | America/North\_Dakota/Beulah | | America/North\_Dakota/Center | | America/North\_Dakota/New\_Salem | | America/Ojinaga | | America/Panama | | America/Pangnirtung | | America/Paramaribo | | America/Phoenix | | America/Port\_of\_Spain | | America/Port-au-Prince | | America/Porto\_Velho | | America/Puerto\_Rico | | America/Rainy\_River | | America/Rankin\_Inlet | | America/Recife | | America/Regina | | America/Resolute | | America/Rio\_Branco | | America/Santarem | | America/Santiago | | America/Santo\_Domingo | | America/Sao\_Paulo | | America/Scoresbysund | | America/Sitka | | America/St\_Barthelemy | | America/St\_Kitts | | America/St\_Lucia | | America/St\_Thomas | | America/St\_Vincent | | America/Swift\_Current | | America/Tegucigalpa | | America/Thule | | America/Thunder\_Bay | | America/Tijuana | | America/Toronto | | America/Tortola | | America/Vancouver | | America/Whitehorse | | America/Winnipeg | | America/Yakutat | | America/Yellowknife | | Antarctica/Casey | | Antarctica/Davis | | Antarctica/DumontDUrville | | Antarctica/Macquarie | | Antarctica/Mawson | | Antarctica/McMurdo | | Antarctica/Palmer | | Antarctica/Rothera | | Antarctica/Syowa | | Antarctica/Troll | | Antarctica/Vostok | | Arctic/Longyearbyen | | Asia/Aden | | Asia/Almaty | | Asia/Amman | | Asia/Anadyr | | Asia/Aqtau | | Asia/Aqtobe | | Asia/Ashgabat | | Asia/Baghdad | | Asia/Bahrain | | Asia/Baku | | Asia/Bangkok | | Asia/Beirut | | Asia/Bishkek | | Asia/Brunei | | Asia/Chita | | Asia/Choibalsan | | Asia/Damascus | | Asia/Dhaka | | Asia/Dili | | Asia/Dubai | | Asia/Dushanbe | | Asia/Gaza | | Asia/Hebron | | Asia/Ho\_Chi\_Minh | | Asia/Hong\_Kong | | Asia/Hovd | | Asia/Irkutsk | | Asia/Jakarta | | Asia/Jayapura | | Asia/Jerusalem | | Asia/Kamchatka | | Asia/Karachi | | Asia/Khandyga | | Asia/Krasnoyarsk | | Asia/Kuala\_Lumpur | | Asia/Kuching | | Asia/Kuwait | | Asia/Macau | | Asia/Magadan | | Asia/Makassar | | Asia/Manila | | Asia/Muscat | | Asia/Nicosia | | Asia/Novokuznetsk | | Asia/Novosibirsk | | Asia/Omsk | | Asia/Oral | | Asia/Phnom\_Penh | | Asia/Pontianak | | Asia/Pyongyang | | Asia/Qatar | | Asia/Qyzylorda | | Asia/Riyadh | | Asia/Sakhalin | | Asia/Samarkand | | Asia/Seoul | | Asia/Shanghai | | Asia/Singapore | | Asia/Srednekolymsk | | Asia/Taipei | | Asia/Tashkent | | Asia/Tbilisi | | Asia/Thimphu | | Asia/Tokyo | | Asia/Ulaanbaatar | | Asia/Urumqi | | Asia/Ust-Nera | | Asia/Vientiane | | Asia/Vladivostok | | Asia/Yakutsk | | Asia/Yekaterinburg | | Asia/Yerevan | | Atlantic/Azores | | Atlantic/Bermuda | | Atlantic/Canary | | Atlantic/Cape\_Verde | | Atlantic/Faroe | | Atlantic/Madeira | | Atlantic/Reykjavik | | Atlantic/South\_Georgia | | Atlantic/St\_Helena | | Atlantic/Stanley | | Australia/Brisbane | | Australia/Currie | | Australia/Hobart | | Australia/Lindeman | | Australia/Melbourne | | Australia/Perth | | Australia/Sydney | | Europe/Amsterdam | | Europe/Andorra | | Europe/Athens | | Europe/Belgrade | | Europe/Berlin | | Europe/Bratislava | | Europe/Brussels | | Europe/Bucharest | | Europe/Budapest | | Europe/Busingen | | Europe/Chisinau | | Europe/Copenhagen | | Europe/Dublin | | Europe/Gibraltar | | Europe/Guernsey | | Europe/Helsinki | | Europe/Isle\_of\_Man | | Europe/Istanbul | | Europe/Jersey | | Europe/Kaliningrad | | Europe/Kiev | | Europe/Lisbon | | Europe/Ljubljana | | Europe/London | | Europe/Luxembourg | | Europe/Madrid | | Europe/Malta | | Europe/Mariehamn | | Europe/Minsk | | Europe/Monaco | | Europe/Moscow | | Europe/Oslo | | Europe/Paris | | Europe/Podgorica | | Europe/Prague | | Europe/Riga | | Europe/Rome | | Europe/Samara | | Europe/San\_Marino | | Europe/Sarajevo | | Europe/Simferopol | | Europe/Skopje | | Europe/Sofia | | Europe/Stockholm | | Europe/Tallinn | | Europe/Tirane | | Europe/Uzhgorod | | Europe/Vaduz | | Europe/Vatican | | Europe/Vienna | | Europe/Vilnius | | Europe/Volgograd | | Europe/Warsaw | | Europe/Zagreb | | Europe/Zaporozhye | | Europe/Zurich | | Indian/Antananarivo | | Indian/Chagos | | Indian/Christmas | | Indian/Comoro | | Indian/Kerguelen | | Indian/Mahe | | Indian/Maldives | | Indian/Mauritius | | Indian/Mayotte | | Indian/Reunion | | Pacific/Apia | | Pacific/Auckland | | Pacific/Bougainville | | Pacific/Chuuk | | Pacific/Easter | | Pacific/Efate | | Pacific/Enderbury | | Pacific/Fakaofo | | Pacific/Fiji | | Pacific/Funafuti | | Pacific/Galapagos | | Pacific/Gambier | | Pacific/Guadalcanal | | Pacific/Guam | | Pacific/Honolulu | | Pacific/Kiritimati | | Pacific/Kosrae | | Pacific/Kwajalein | | Pacific/Majuro | | Pacific/Midway | | Pacific/Nauru | | Pacific/Niue | | Pacific/Norfolk | | Pacific/Noumea | | Pacific/Pago\_Pago | | Pacific/Palau | | Pacific/Pitcairn | | Pacific/Pohnpei | | Pacific/Port\_Moresby | | Pacific/Rarotonga | | Pacific/Saipan | | Pacific/Tahiti | | Pacific/Tarawa | | Pacific/Tongatapu | | Pacific/Wake | | Timezone Codes | | :------------- | | GMT | | ACDT | | ACST | | ACT | | ACWST | | ADT | | AEDT | | AEST | | AFT | | AKDT | | AKST | | ALMT | | AMST | | AMT | | ANAST | | ANAT | | ART | | AST | | AWST | | AZOST | | AZOT | | AZST | | AZT | | BNT | | BOT | | BRST | | BRT | | BST | | BTT | | CAST | | CCT | | CDT | | CEST | | CET | | CHADT | | CHAST | | CHUT | | CKT | | CLST | | CLT | | COT | | CST | | CXT | | DAVT | | DDUT | | EASST | | EAST | | EAT | | EDT | | EEST | | EET | | EGST | | EGT | | EST | | FET | | FJST | | FJT | | FKST | | FKT | | FNT | | GALT | | GAMT | | GET | | GFT | | GILT | | GMT | | GYT | | HKT | | HST | | ICT | | IDT | | IOT | | IRKST | | IRKT | | IST | | JST | | KGT | | KOST | | KRAST | | KRAT | | KST | | LHDT | | LHST | | LINT | | MAGST | | MAGT | | MART | | MAWT | | MDT | | MHT | | MMT | | MSD | | MSK | | MST | | MUT | | MVT | | MYT | | NDT | | NFT | | NOVST | | NOVT | | NPT | | NST | | NUT | | NZDT | | NZST | | OMSST | | OMST | | PDT | | PET | | PETST | | PETT | | PGT | | PHOT | | PHT | | PKT | | PMDT | | PMST | | PONT | | PST | | PWT | | PYST | | PYT | | RET | | SAST | | SCT | | SGT | | TAHT | | TFT | | TJT | | TKT | | TMT | | TOT | | TVT | | ULAST | | ULAT | | UTC | | UYST | | UYT | | UZT | | VET | | VLAST | | VLAT | | VUT | | WAKT | | WAST | | WAT | | WET | | WFT | | WGST | | WGT | | YAKST | | YAKT | | YAPT | | YEKST | | YEKT | | UTC / ETC Offsets | | :---------------- | | UTC -12 | | UTC -11 | | UTC -10 | | UTC -9:30 | | UTC -9 | | UTC -8 | | UTC -7 | | UTC -6 | | UTC -5 | | UTC -4 | | UTC -3:30 | | UTC -3 | | UTC -2:30 | | UTC -2 | | UTC -1 | | UTC-12 | | UTC-11 | | UTC-10 | | UTC-9:30 | | UTC-9 | | UTC-8 | | UTC-7 | | UTC-6 | | UTC-5 | | UTC-4 | | UTC-3:30 | | UTC-3 | | UTC-2:30 | | UTC-2 | | UTC-1 | | UTC | | UTC+0 | | UTC+1 | | UTC+2 | | UTC+3 | | UTC+3:30 | | UTC+4 | | UTC+4:30 | | UTC+5 | | UTC+5:30 | | UTC+5:45 | | UTC+6 | | UTC+6:30 | | UTC+7 | | UTC+8 | | UTC+8:30 | | UTC+8:45 | | UTC+9 | | UTC+9:30 | | UTC+10 | | UTC+10:30 | | UTC+11 | | UTC+12 | | UTC+12 | | UTC+12:45 | | UTC+13 | | UTC+13:45 | | UTC+14 | | UTC +0 | | UTC +1 | | UTC +2 | | UTC +3 | | UTC +3:30 | | UTC +4 | | UTC +4:30 | | UTC +5 | | UTC +5:30 | | UTC +5:45 | | UTC +6 | | UTC +6:30 | | UTC +7 | | UTC +8 | | UTC +8:30 | | UTC +8:45 | | UTC +9 | | UTC +9:30 | | UTC +10 | | UTC +10:30 | | UTC +11 | | UTC +12 | | UTC +12:45 | | UTC +13 | | UTC +13:45 | | UTC +14 | | ETC/GMT | | ETC/GMT-0 | | ETC/GMT-1 | | ETC/GMT-2 | | ETC/GMT-3 | | ETC/GMT-4 | | ETC/GMT-5 | | ETC/GMT-6 | | ETC/GMT-7 | | ETC/GMT-8 | | ETC/GMT-9 | | ETC/GMT-10 | | ETC/GMT-11 | | ETC/GMT-12 | | ETC/GMT-13 | | ETC/GMT-14 | | ETC/GMT+0 | | ETC/GMT+1 | | ETC/GMT+2 | | ETC/GMT+3 | | ETC/GMT+4 | | ETC/GMT+5 | | ETC/GMT+6 | | ETC/GMT+7 | | ETC/GMT+8 | | ETC/GMT+9 | | ETC/GMT+10 | | ETC/GMT+11 | | ETC/GMT+12 | | ETC/GMT0 | | ETC/Greenwich | | ETC/UCT | | ETC/Universal | | ETC/UTC | ## What's next * [Transaction IDs](/marketing-solutions/docs/transaction-ids) * [Log-Level](/marketing-solutions/docs/log-level) * [Placement](/marketing-solutions/docs/placement) * [Placement Category](/marketing-solutions/docs/placement-category) # Campaigns Source: https://developers.criteo.com/marketing-solutions/docs/campaigns ## Introduction Criteo's **Campaign API** allows retrieving information about the current configuration of your advertising Campaigns and Ad Sets. This API allows searching for Campaigns based on filters, and updating the Campaigns' objectives and spend limits. It also allows searching for Ad Sets based on filters, to start and stop Ad Sets, and to update the Ad Sets' names, start and end dates, bid amounts, frequency capping, and other targeting controls. **New Campaign Taxonomy** Criteo campaigns follow a three-tier structure: * Campaigns, * Ad Sets, * Ads. Your marketing objective and Campaign spend limit are specified at the **Campaign** level.\ Targeting controls and bid targets are set at the **Ad Set** level. Several Ad Sets can be linked to the same Campaign.\ **Ads** are the actual media that is used to address the audience of a given Ad Set. There can be many Ads associated with a given Ad Set. ## What's next * [Campaign](/marketing-solutions/docs/campaign) * [Ad Set](/marketing-solutions/docs/ad-set) * [Display Multipliers](/marketing-solutions/docs/display-multipliers) * [Category Bids](/marketing-solutions/docs/category-bids) # Campaigns- Concept Guide Source: https://developers.criteo.com/marketing-solutions/docs/campaigns-concept-guide # Introduction Single-Seller campaigns extend Marketplace Performance Outcomes (MPO) to give you per-seller control over advertising. In a classic (multi-seller) MPO setup: * Many sellers share a single campaign configuration (ad set, bidding and optimisation logic). * You primarily optimise at the pooled level across all sellers, even if you use seller-level budgets. In a Single-Seller setup: * Each seller gets their own dedicated campaign (a “Single-Seller campaign”). * All these per-seller campaigns are derived automatically from a shared template campaign configured by Criteo. * You control if a seller runs, when they run, and how much they can spend by managing per-seller budgets via the MPO API. Using the MPO API, you can: * Decide which sellers are active in Single-Seller. * Control when each seller’s campaign is allowed to spend. * Control per-seller spend levels through individual capped budgets. (Optionally) restrict a seller’s campaign to a subset of products using productSet. This guide is intended for: * Marketplace integrators * Technical leads / architects * Developers who need a mental model of Single-Seller before working with the detailed API workflows and reference. Single-Seller builds on top of the existing multi-seller MPO model. Both use the same core entities and endpoints; the differences are how sellers relate to campaigns, how budgets work, and how pacing is handled. ### Core Entities and Identifiers Single-Seller reuses the MPO entity model but adds clear **per-seller relationships**. Understanding these is crucial before writing any code. #### Advertiser * External business entity in Criteo (**your marketplace as an advertiser**). * Typically retrieved via the **Marketing Solutions Advertisers** endpoints. * All Single-Seller activity occurs under one or more advertisers. #### MPO Template campaign (`templateCampaignId`) The template campaign is the **blueprint** for all your Single-Seller campaigns: * It is **provisioned and configured by Criteo**. You do **not** create it via the MPO API. * It contains: * Optimization goal and bidding strategy (e.g., “Target Budget”). * Audience / targeting configuration (who you show ads to). * Creative configuration and other **non-seller-specific** settings. * It must **remain active** for any derived Single-Seller campaigns to be eligible to serve. * It does **not**: * Spend budget * Serve impressions * Represent any one seller You receive its campaign ID from Criteo (we refer to it as `templateCampaignId`), and you use this ID as `campaignId` in MPO budgets calls. #### Seller (`sellerId` and `sellerName`) A seller is a **merchant on your marketplace**: * In your product catalog, you must provide `sellerName` on each product. * MPO’s seller ingestion system: * Reads the `sellerName` from your catalog. * Creates or updates an internal seller entity. * Assigns an internal identifier `sellerId`. You can discover sellers via MPO Sellers endpoints, for example: ```http theme={null} GET /marketplace-performance-outcomes/sellers?sellerName=YoursellerName ``` `sellerName` → the value you sent in the catalog. * `sellerName` is **case-sensitive**. Different casing is treated as different logical sellers and will produce separate `sellerId` values. * You can use your own internal seller identifier as `sellerName` (to simplify mapping), but you must remain consistent. ### Single-Seller campaign (`sellerCampaignId`) A Single-Seller campaign is the **dedicated per-seller campaign** derived from the template: * It represents the join **(`sellerId`, `templateCampaignId`)**. * It is **not** created by a direct “create campaign” call: * It is created **implicitly** when you create the first valid budget for a given (`sellerId`, `templateCampaignId`) pair. * Once created: * It inherits configuration from the **template campaign**. * It is used by MPO **statistics endpoints** (e.g., seller-campaign stats) so you can report per seller. * You will typically see its ID in APIs as `sellerCampaignId` or `id` in seller-campaign resources, often in a combined format like `SELLER_123.TEMPLATE_456`. ### Budget (`budgetId`) The budget is the **main control point** in Single-Seller: * It represents a **capped total amount over a date range** for a (`sellerId`, `templateCampaignId`) pair. * It is created and managed via MPO budgets endpoints: * `POST /marketplace-performance-outcomes/budgets` * `PATCH /marketplace-performance-outcomes/budgets` * `GET /marketplace-performance-outcomes/budgets[...]` * It controls: * **How much** the Single-Seller campaign can spend (total `amount`). * **When** it can spend (`startDate`, `endDate`). * Whether the campaign is eligible to spend or **paused** via `isSuspended`. **Key conceptual rules:** * There is **no daily budget type** for Single-Seller – only **capped total budgets** over a period. * Budgets **must not overlap** for the same (`sellerId`, `templateCampaignId`). * Suspending (`isSuspended = true`) does **not** remove the budget; it: * Pauses spend, and * Frees the period so you can plan a new one if needed. ### `productSet` `productSet` is an **optional server-side filter** that restricts which products a Single-Seller campaign can advertise: * It is attached at the **Single-Seller campaign (seller-campaign) level**. * It defines an inclusion or exclusion rule over product external IDs (`ExternalItemId`). * It is configured via: * `PATCH /marketplace-performance-outcomes/seller-campaigns` * At any given time, **only one** `productSet` is supported per Single-Seller campaign. **Typical pattern:** * `operator`: `IsIn` or `IsNotIn` * `field`: `ExternalItemId` * `values`: list of product external IDs (e.g., `["SKU_001", "SKU_002", ...]`) Some advertisers enforce a **minimum number of products** per `productSet` (e.g., at least 10 or 20 IDs). Requests below that threshold may be rejected with a **validation error**. ### Relationships summary You can think of Single-Seller relationships like this: * One `templateCampaignId` → **many Single-Seller campaigns** (one per seller). * For each (`sellerId`, `templateCampaignId`): * You manage a **timeline of non-overlapping budgets**. * The presence of at least one valid, active budget during a given period makes the **Single-Seller campaign eligible to spend**. * Each Single-Seller campaign may have **0 or 1 attached `productSet`**. **Visual mental model:** * **Template campaign**: “Master config” for the program. * **Single-Seller campaign**: “Per-seller instance” created automatically. * **Budget**: “Time-bounded wallet” for that instance. * **`productSet`**: “Whitelist of products” for that instance (optional). ## Access and Enablement Before you write any code against Single-Seller endpoints, you must confirm two things: 1. Your account has the **right features enabled**. 2. You have the **right data and permissions** in place. ### Feature availability Single-Seller campaigns may be gated or rolled out progressively (enabled only for selected advertisers or test environments at first, then gradually opened to more marketplaces as the rollout proceeds). Before implementing, confirm with your Criteo representative or support contact that: * **MPO API** is enabled on your account. * **Single-Seller campaigns** are enabled and you have at least one **Single-Seller-compatible template**. If Single-Seller is not enabled and you call those flows, you may see: * **Authorization errors** (e.g., you cannot use a given template). * **Validation errors** indicating the template is not marked as Single-Seller-compatible or the operation is not allowed. ### Getting a Single-Seller template You do **not** create Single-Seller template campaigns yourself via the MPO API. They are **set up for you by Criteo**. #### 1. Request a Single-Seller template from Criteo When you talk to your Criteo contact, be ready to share: * Advertiser(s) and vertical(s) you want to use Single-Seller on. * Your optimization goal (for example: maximize seller GMV, stay within budget, focus on ROAS). * Whether Single-Seller will coexist with existing multi-seller campaigns and how you plan to **split sellers between them**. #### 2. Criteo creates and configures the template Based on your inputs, Criteo will: * Create a **Single-Seller-compatible campaign** in their internal tools. * Enable **budget-based cost control** (Single-Seller does not use CPC bidding). * Configure: * The optimization goal, * Default audiences/targeting (geos, devices, etc.), * Any marketplace-specific constraints. #### 3. Criteo sends you the template details You will receive at least: * The template campaign ID (`templateCampaignId`), which you must use as `campaignId` in all Single-Seller **budget** calls. * The **minimum allowed per-seller budget** for this template (for example, the minimum amount per period to ensure learning and delivery). #### 4. You store and use this configuration On your side, you should: * Persist `templateCampaignId` and the associated constraints (minimum budget, allowed date ranges, etc.) in your configuration system. * Use this data whenever you construct Single-Seller budget requests for a seller: * Set `campaignIds = [templateCampaignId]`. * Validate that the requested `amount` and dates **respect the minimums and other rules** shared by Criteo. Once this setup is done, you **do not** need to request a new template for each seller. You **reuse the same** `templateCampaignId` and create **per-seller budgets** attached to it. ### Prerequisite data and permissions To use Single-Seller successfully, your integration should: * Already be using **MPO Sellers** endpoints to discover `sellerId` values. * Have: * The appropriate **permissions** to manage campaigns and budgets on the advertiser. * A working **OAuth 2.0 integration** to get access tokens. * Ability to call: * `/marketplace-performance-outcomes/sellers` * `/marketplace-performance-outcomes/budgets` * `/marketplace-performance-outcomes/stats/...` If you cannot, fix **basic MPO API access first** (authentication, authorization, network constraints) before attempting Single-Seller. ### Application permissions For external integrations using the Criteo Marketing Solutions API in **Single-Seller** mode, your application must have **all Marketing Solutions domain permissions enabled**. Missing permissions can prevent child ad sets from being created when you submit the first budget, which may result in server errors even though the budget itself is stored. > For multi-seller MPO, only the **Campaign – Manage** permission is required. See the Multi-Seller documentation for details. ## Budget Management in Single-Seller campaigns Budgets are the **entry point for controlling Single-Seller campaigns**. There is no standalone “create campaign” call; the act of creating a **budget** is what creates and controls the per-seller campaign. Budgets: * Create the underlying Single-Seller campaign if none exists for (`sellerId`, `templateCampaignId`). * Define **how much** the seller can spend over a given period. * Define **when** the seller can spend (start/end dates). * Control whether that seller is **running, paused, or scheduled** via `isSuspended` and date ranges. ### Budget behavior overview At a high level: * Each Single-Seller budget is a **capped total amount over a date range**: * There is **no daily budget type** and no “uncapped” budget. * You specify the **total amount** you are willing to spend for that seller in that period. * **Daily pacing is automatic**: * The system calculates an **average daily spend target** based on total amount and date range. * If deliveries fluctuate (fewer impressions one day, more the next), the system can adjust within the overall budget and time window. * For a given (`sellerId`, `templateCampaignId`): * Budget periods **must not overlap**. * You can: * Have **one current budget**. * Schedule **future budgets** as long as their periods do not overlap the current or each other. * Suspended budgets (`isSuspended = true`): * Immediately **stop spend** for that combination. * Are treated as **canceled for spend purposes** but remain in the API for **historical and auditing** reasons. * Do **not** prevent you from creating or activating another budget covering the same or a different period, as long as the API’s overlap rules are respected. **Common patterns:** * **Launch** – Create the first budget for (`sellerId`, `templateCampaignId`) → campaign auto-created and starts delivering. * **Top-up** – Increase `amount` mid-flight via an update, keeping the same date range. * **Extend** – Extend `endDate` to continue spend, ensuring no overlap with a future budget. * **Pause** – Set `isSuspended = true` to stop spend temporarily. * **Schedule** – Create a new budget in the future (non-overlapping) to plan the next period of activity. ## `productSet` behavior `productSet` allows you to **restrict a Single-Seller campaign** to advertise only a subset of the seller’s products. This is optional but powerful. ### Key points * A `productSet` acts as a **filter over product external IDs**: * Typically a **whitelist**: “Only these SKUs from this seller should be eligible for ads.” * It is configured at the **Single-Seller campaign (seller-campaign) level**: * It applies to **all ads** served by that campaign. * If **no `productSet`** is configured: * The campaign can use **all eligible products** from the seller’s catalog (subject to other targeting and policy constraints). * At any given time: * A Single-Seller campaign has **at most one `productSet`**. ### Supported pattern For Single-Seller, supported rule shape includes: * `operator`: `IsIn` or `IsNotIn` * `field`: `ExternalItemId` * `values`: array of product external IDs (e.g., `["SKU_001", "SKU_002", "SKU_003"]`) Some environments enforce: * A **minimum number of product IDs** per `productSet` (e.g., at least 10 or 20 values). * Requests below the minimum may be rejected with **4xx errors** referencing `productSet` or `values`. **High-level usage:** * **No `productSet`**: all eligible catalog products can be shown. * **Single `productSet` rule**: only the listed SKUs (or everything except the listed SKUs) can be shown. ## Typical Single-Seller workflows This section ties the concepts together into typical **end-to-end flows**. The detailed API calls live in the Quick Start recipe and API Reference. ### 1. Onboard a seller to a Single-Seller template Goal: transition a seller **from not yet in a Single-Seller campaign** to an **active Single-Seller campaign**. Conceptually: * Ensure `sellerId` is available: * Use `GET /marketplace-performance-outcomes/sellers?sellerName=YoursellerName`to confirm the seller is ingested and mapped from your catalog. * Confirm configuration: * You have a valid `templateCampaignId` for Single-Seller. * You know the **minimum per-seller budget** for that template. * Create the **first budget** for (`sellerId`, `templateCampaignId`): * Valid date range (no overlap with any existing budget). * more: amount ≥ minimum per-seller budget by the number of days where the campaign will run. System behavior: * MPO creates the **Single-Seller campaign** for that seller and template. * After a short provisioning delay, the campaign becomes **eligible to serve impressions**. ### 2. Adjust spend mid-flight Goal: adapt budgets in response to performance or business decisions. Conceptually: * Retrieve the **current budget** for (`sellerId`, `templateCampaignId`) via the budgets endpoints. * Decide whether to: * Increase `amount` (more spend). * Decrease `amount` (protect budget). * Extend the `endDate`. * Update the budget via an appropriate **budget update** call: * Keep **non-overlapping constraints** in mind if you are using multiple periods. * The system **recalculates pacing** based on new total and remaining days. ### 3. Pause or resume seller activity Goal: temporarily stop or resume a seller’s Single-Seller campaign. Conceptually: * To **pause**: * Set `isSuspended = true` on the active budget. * The Single-Seller campaign stops serving but remains in the system. * To **resume**: * If the same budget period is still valid, set `isSuspended = false`. * If the end date has passed, you may need to **create a new budget** with a future period. Because **budgets control activity**: * You do **not** pause the Single-Seller campaign directly; you manage it via **budget suspension**. ### 4. Restrict products for a seller (optional) Goal: limit which products from a seller’s catalog are advertised. Conceptually: * Decide which **SKUs (external IDs)** should be eligible. * Attach or update a `productSet` on the seller-campaign: * A single rule with `operator`, `field = ExternalItemId`, and `values =` your list of SKUs. * The system restricts inventory for that seller to the **filtered subset**. * To revert: * Set `productSet.value = null` (or equivalent) to restore “no extra filter”. ### 5. Monitor budgets and performance Goal: ensure the integration behaves as expected and **diagnose issues**. Conceptually: * Use **budgets endpoints** to: * Check **active and future budgets**. * Confirm `isSuspended`, `amount`, `startDate`, and `endDate`. * Detect **overlapping or missing budgets**. * Use **stats endpoints** to: * Track performance per seller and per seller-campaign. * Monitor spend vs budget, conversions, and other KPIs. If something looks wrong (no delivery, low volume, unexpected spend), you: * Inspect: * Seller state (via **Sellers** endpoints). * Budgets state (via **Budgets** endpoints). * `productSet` state (via **Seller-campaigns** endpoints). * Adjust **budgets** or **`productSet`** accordingly. # Campaigns- Concept Guide Source: https://developers.criteo.com/marketing-solutions/docs/campaigns-concept-guide-1 ## Introduction Multi-Seller campaigns are the original Marketplace Performance Outcomes (MPO) model. They allow many marketplace sellers to share a single campaign configuration and participate in a pooled optimisation strategy. ### Key characteristics * A single campaign serves many sellers. * Targeting, optimisation goal, and bidding strategy are shared. * Budget is primarily managed at the campaign level for each active seller. You control: * Which sellers participate. * How aggressively they bid. * How much budget each seller can consume. ### What you can do with the MPO API * Discover and manage marketplace sellers. * Link sellers to Multi-Seller campaigns. * Control participation via CPC bids and budgets. * Monitor performance at campaign and seller level. ### Audience * Marketplace integrators. * Technical leads / architects. * Developers needing a conceptual understanding before API implementation. ## Core Entities and Identifiers ### Overview

Entity

Description

Advertiser

Marketplace business entity

Campaign ( \{\{campaignId}} )

Shared campaign configuration

Seller ( \{\{sellerId}} )

Marketplace merchant

Seller-Campaign ( \{\{sellerCampaignId}} )

Seller participation in a campaign

Budgets

Campaign-level and seller-level spend controls

### Advertiser * Represents your marketplace in Criteo. * Hosts one or more MPO campaigns. * Retrieved via Marketing Solutions APIs. ### Multi-Seller Campaign (`{{campaignId}}`) Shared campaign across multiple sellers, configured by Criteo (not via MPO API). Defines: * Optimisation goal (traffic, conversions, revenue). * Bidding strategy (typically CPC). * Targeting and audiences. * Creative formats and placements. Does: * Spend campaign-level budgets. * Serve ads with products from multiple sellers. Does **not**: * Represent a single seller. * Store seller-specific bids or budgets. ### Seller (`{{sellerId}}` / `{{sellerName}}`) * Represents a merchant in your marketplace. `sellerName`: * Comes from your catalog (e.g. `seller_id`). * Case-sensitive. `sellerId`: * Internal MPO identifier. * Retrieve via: ```http HTTP theme={null} GET /marketplace-performance-outcomes/sellers?sellerName={{yourSellerIdentifier}} ``` Use consistent `sellerName` values to avoid duplicate sellers. ### Seller-Campaign (`{{sellerCampaignId}}`) Represents the relationship between a seller and a campaign. * Links: (`{{sellerId}}`, `{{campaignId}}`) * Automatically created by MPO (one per seller per MPO campaign); you then configure its CPC bid via the MPO API. Defines: * CPC bid * Participation state Initially, a seller-campaign may be suspended (for example, `NoBudgetDefined`) until you set bids and budgets. **Example ID:** ```text theme={null} SELLER_123.CAMPAIGN_456 ``` ## Budgets

Type

Description

Campaign-level

Shared across all sellers

Seller-level

Optional per seller-campaign

### Campaign-Level Budgets * Managed via Criteo or general APIs. * Global cap for campaign spend. * Should be set high enough to cover (or be higher than) the sum of active seller-level budgets; otherwise you may see under-delivery even when per-seller budgets remain. ### Seller-Level Budgets * Managed via MPO API: ```http HTTP theme={null} POST /marketplace-performance-outcomes/budgets GET /marketplace-performance-outcomes/budgets ``` Use cases: * Cap seller spend. * Schedule campaigns. * Apply different strategies per seller. ## Access and Enablement ### Requirements * MPO enabled for your advertiser. * At least one Multi-Seller campaign exists. * API permissions configured with **Manage Campaign** permissions. ### Potential issues * Authorization errors. * Validation errors. ## Campaign Setup Flow 1. **Request setup**\ Provide: * Advertiser details. * Business goals. * Seller distribution. 2. **Criteo configuration** * Campaign structure. * Targeting and creatives. * MPO features. 3. **Receive configuration** * `campaignId`. * Constraints (budgets, CPC ranges, geos). ## Prerequisites Ensure you have: * Product catalog with a seller field. * OAuth2 authentication. * Required API scopes. Endpoints: ```http theme={null} /marketplace-performance-outcomes/sellers /marketplace-performance-outcomes/seller-campaigns /marketplace-performance-outcomes/budgets /marketplace-performance-outcomes/stats/... ``` ## Budget Management ### Overview

Component

Role

Campaign Budget

Total available spend

CPC Bids

Seller competitiveness

Seller Budgets

Optional caps per seller

### Campaign Budgets * Global spend limit. * Must be large enough to support sellers. ### Seller-Campaign Bids (CPC) * Higher CPC > more exposure. * Lower CPC > reduced spend. * `IsSuspended = true/false` controls participation alongside CPC. ### Seller-Level Budgets * Cap or schedule seller spend. * Associated with a seller-campaign. **Behaviour:** * May reset daily. * May have start/end dates. * Can stop delivery when exhausted. ## Product & Creative Behavior * Shared dynamic ads across sellers. * Products from multiple sellers can appear together. Key points: * No per-seller `productSet` (Single-Seller only). * Products are only eligible when the seller is active (positive CPC and available budget). Campaign targeting (geo, device, audiences) still applies on top, but is not the main factor determining basic product eligibility. ## Typical Workflows ### 1. Onboard Sellers **Steps:** 1. Confirm ingestion: ```http HTTP theme={null} GET /marketplace-performance-outcomes/sellers?sellerName={{seller}} ``` 2. Confirm campaign: * Valid `campaignId`. * Budget configured. 3. Create seller-campaign. 4. Set CPC. 5. Add seller budgets (optional). ### 2. Adjust Spend per Seller * Retrieve current setup. * Choose control method: * **CPC** → performance tuning. * **Budget** → hard cap. **Actions:** * Increase CPC → scale. * Decrease CPC → reduce. ### 3. Suspend / Resume Seller **Suspend:** * `IsSuspended = true` on the relevant budget and/or * Budget inactive. **Resume:** * `IsSuspended = false` on the associated budget. * Ensure budgets are active. ### 4. Monitor & Troubleshoot **Common checks**

Issue

Check

No delivery

Seller exists, CPC > 0, budgets active

Low delivery

CPC too low, budget limited

Under-spend

Campaign budget too small

Over-spend

Budget configuration / reset behaviour

### Application permissions For **multi-seller MPO** integrations, your application needs at least the **Campaign – Manage** permission on the relevant advertiser accounts. # Catalog Source: https://developers.criteo.com/marketing-solutions/docs/catalog For now, `Product Sets` are the only Catalog endpoint available in the Stable version of the Marketing Solutions API. You can find the rest of Catalog endpoints [in the Preview version](/marketing-solutions/v2026-preview/reference/catalog/submit-catalog-products-batch). ## What's next * [Product Sets](/marketing-solutions/docs/product-sets) # Category Bids Source: https://developers.criteo.com/marketing-solutions/docs/category-bids ## Introduction In addition to ad-set-level bid targets, Criteo permits **bid customization** for each product category associated with an ad set. For example, you may wish to set higher bids for particular brands or product lines. **Requirements** * Categories used for bidding must be added as the `category 1`, `category 2`, or `category 3` field when configuring the import of your [product catalog](https://help.criteo.com/kb/guide/en/set-up-your-product-catalog-x21HrwcuTy/Steps/775589). * Category-level bidding must also be explicitly enabled for **one** of the categories above by your Criteo account team. * Ad set must be set with CPC or CPM as cost controller (more details on cost controller [here](/marketing-solutions/docs/ad-set#ad-set-bidding)). If your ad set uses another cost controller, you must refer to the [Display Multipliers](/marketing-solutions/docs/display-multipliers) solution. *** ## Get Category Bids The category bids associated with a specific Ad Set can be retrieved via a `GET` request to the `/ad-sets` endpoint, with the Ad Set ID as a URL parameter and `/category-bids` specified. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/ad-sets/{ad-set-id}/category-bids ``` **Sample response** The API will return an array of categories associated with the ad set: ```json JSON theme={null} { "data":[ { "type": "AdSetCategoryBid", "id": "1234567|432|1", "attributes": { "categoryName": "Shoes", "bidAmount": 1.3 } }, { "type": "AdSetCategoryBid", "id": "1234567|432|2", "attributes": { "categoryName": "Socks", "bidAmount": 1.3 } } ], "errors": [ ] } ``` **`ID`** The ID is composite of the Ad Set Id, a Criteo category ID and a Category level (1, 2 or 3).\ In the above example, the id of the category `shoes` is composed of: * **Ad set ID**: `1234567` * **Category ID**: `432` * **Category Level**: `1` **Default Bid** All categories enabled will be shown in the results. If a specific bid is not set for an available category, it will display the bid amount configured at the ad set level. *** ## Update Category Bids You can update the bid amount of one or more categories of an Ad Set by making a `PATCH` request to the `/ad-sets` endpoint, with the Ad Set ID as a URL parameter and `/category-bids` specified. For example, the following call would update the bid values for the category `Shoes` and `Socks` on the previous `GET` sample: ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/ad-sets/{ad-set-id}/category-bids ``` **Sample request** ```json JSON theme={null} { "data": [ { "type": "AdSetCategoryBid", "id": "1234567|432|1", "attributes": { "bidAmount": 2.0 } }, { "type": "AdSetCategoryBid", "id": "1234567|432|2", "attributes": { "bidAmount": 1.1 } } ] } ``` **Sample response** The API will return an array of Ad Sets that have been updated successfully in the response `data`. These will contain only two parameters, `type` and `id`. ```json JSON theme={null} { "data": [ { "type": "AdSetCategoryBid", "id": "1234567|432|1" }, { "type": "AdSetCategoryBid", "id": "1234567|432|2" } ], "errors": [], "warnings": [] } ``` **Reset Category Bid** Setting the bid amount of a category to the same bid amount at the ad set level will reset the category bid behavior for that category. Thus, this update will make any subsequent changes on the ad set bid apply to that category bid. **Updating Multiple Category Bids** This endpoint allows you to update several category bids within a single call. When updating multiple items, note that some updates may succeed while others fail. *** ## Validation Errors In addition to [general API errors](/criteo-apis/docs/api-error-types), you may encounter validation errors when retrieving or updating a category bid. Below is a list of error codes for category bid validation and a more detailed description of their meaning. **`campaign--category-bid-get-check--invalid-bidding-config`**\ Category bid is only available on ad set with CPC-based or CPM-based cost controllers. If your ad set uses other cost controller, you must refer to the [Display Multipliers](/marketing-solutions/docs/display-multipliers). **`campaign--category-bid-update-check--category-not-enabled`**\ The category targeted by the category bid is not enabled. **`campaign--category-bid-update-check--ad-set-not-enabled`**\ The ad set status is invalid, and the change is not allowed (e.g., the ad set is archived). **`campaign--category-bid-update-check--invalid-bid-amount`**\ The bid amount provided is not in the range of accepted values. **`campaign--category-bid-update-check--cannot-update-same-category-bid-amount-multiple-times`**\ It is not possible to update the same category bid amount multiple times in the same request. *** ## Upcoming Category Bid Functionality A special reset endpoint will be introduced in future releases. This endpoint will allow resetting category bids for all the enabled categories associated with an Ad Set.\ This means that the bid for all categories will be set to the default bid amount of the ad set. As a reminder, in order to enable category bidding functionality, you may have to issue a request to your account strategist. If the feature is turned off and on during the Ad Set/ Account lifetime, the category bids are not reset automatically. Therefore, if you don't plan to use the category bid feature anymore it's a good idea to manually reset category-level bids to those of an ad set, before asking your account strategist to disable the feature. # Commerce Grid Source: https://developers.criteo.com/marketing-solutions/docs/commerce-grid This section documents the Commerce Grid API ## Introduction Criteo's Commerce Grid Audience Segments API allows you to manage your audience segments by creating, deleting, and updating their data. You can find more information about Commerce Grid on [our Help Center](https://docs.commercegrid.criteo.com/kb/en). *** ## Authentication You can authenticate to the Commerce Grid API using the endpoint documented [here](/marketing-solutions/docs/authentication). *** ## Audience Segments Endpoints You can manage available information, including the name and the description of the audience segments. For audience segments of type contact list, you can manage the users included on them, and retrieve their statistics.
## What's next * [Commerce Grid Audience Segments Endpoints](/marketing-solutions/docs/commerce-grid-audience-segments-endpoints) # Commerce Grid Audience Segments Endpoints Source: https://developers.criteo.com/marketing-solutions/docs/commerce-grid-audience-segments-endpoints ## **Introduction** **Audience Segments** represent a groups of users to target. **Partial Approvals** Bulk operations (`create`, `update`, `delete`) use a **partial approval model**. Even if some items in the request fail, the response will return `200 OK`. Any failed items will be listed in the warnings section of the response with an error code and details. Examples of possible warning codes: * `segment-not-found` → Segment is not found. * `name-must-be-unique` → Segment name must be unique. * `name-must-not-be-empty` → Segment name property must not be empty. This list is not exhaustive. Additional warnings may be returned depending on the request context. **Note on Audience Computation** Audience updates are processed daily at 0h UTC and 12h UTC and can take around 5 hours to reflect on a live campaign. This is important for audiences that are frequently updated as changes should be ready for processing prior to these two times. *** ## Endpoints

Verb

Endpoint

Description

POST

/commerce-grid/audience-segments/create

Create a new Audience Segment

PATCH

/commerce-grid/audience-segments

Update an Audience Segment

POST

/commerce-grid/audience-segments/delete

Delete an Audience Segment

POST

/commerce-grid/audience-segments/search

Search for Audience Segments by segment IDs, data provider IDs and/or segment types

GET

/commerce-grid/audience-segments/\{audienceSegmentId}/contact-list/statistics

Retrieve contact list statistics

POST

/commerce-grid/audience-segments/\{audienceSegmentId}/contact-list/add-remove

Add/remove identifiers in contact list Audience Segment

POST

/commerce-grid/audience-segments/\{audienceSegmentId}/contact-list/clear

Clear all identifiers in contact list Audience Segment

*** ## Audience Segment Attributes

Attribute

Data Type

Description

id / audienceSegmentId

string

Audience Segment ID, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

name \*

string

Audience Segment name

Accepted values: string

Writeable? Y / Nullable? N

description

string

Description of the Audience Segment

Accepted values: string

Writeable? Y / Nullable? N

dataProviderId \*

string

Data Provider ID associated with the Audience Segment, generated internally by Criteo

Accepted values: string of int64

Writeable? N / Nullable? N

type

enum

Type of segment

Read-only value, which can be one of:

  • ContactList : users segment defined by list of contact identifiers, manageable by the other endpoints

Writeable? N / Nullable? N

contactList

object

Setting to target users with contact list.

See below for more details

createdAt

timestamp

Timestamp of Audience Segment creation, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss.msZ (in ISO-8601 )

Writeable? N / Nullable? N

updatedAt

timestamp

Timestamp of last Audience Segment update, in UTC

Accepted values: yyyy-mm-ddThh:mm:ss.msZ (in ISO-8601 )

Writeable? N / Nullable? N

*\*Required at create operation* **Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Contact List Segment Attributes

Attribute

Data Type

Description

remoteId

string

ID owned by the client and used to identify the Audience Segment. If none is provided, one will be generated internally by Criteo

Accepted values: string

Writeable? Y / Nullable? N

**Field Definitions** * **Writeable (Y/N)**: Indicates if the field can be modified in requests. * **Nullable (Y/N)**: Indicates if the field can accept null/empty values. * **Primary Key**: A unique, immutable identifier of the entity, generated internally by Criteo. Primary keys are typically ID fields (e.g., `retailerId`, `campaignId`, `lineItemId`) and are usually required in the URL path. *** ## Create Audience Segment This endpoint allows creating **Audience Segments**. The corresponding App should have the "**Audiences Manage**" permission enabled. ```http theme={null} https://api.criteo.com/{version}/commerce-grid/audience-segments/create ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/commerce-grid/audience-segments/create' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "type": "CommerceGridAudienceSegment", "attributes": { "name": "CRM Users 2025", "description": "Segment made of CRM user emails", "dataProviderId": "94", "contactList": { "remoteId": "crm_users.csv" } } }, ] }' ``` **Sample Response** ```json theme={null} { "data": [ { "attributes": { "name": "CRM Users 2025", "description": "Segment made of CRM user emails", "type": "ContactList", "createdAt": "2025-12-12T13:44:53.29Z", "updatedAt": "2025-12-12T13:44:53.29Z", "dataProviderId": "94", "remoteId": "crm_users.csv", "contactList": {} }, "id": "787314040225128448", "type": "CommerceGridAudienceSegment" } ], "warnings": [], "errors": [] } ``` **Sample Request** - auto-generated `remoteId` ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/commerce-grid/audience-segments/create' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "type": "CommerceGridAudienceSegment", "attributes": { "name": "CRM Users 2024", "description": "Segment made of CRM user emails", "dataProviderId": "94", "contactList": {} } }, ] }' ``` **Sample Response** ```json theme={null} { "data": [ { "attributes": { "name": "CRM Users 2024", "description": "Segment made of CRM user emails", "type": "ContactList", "createdAt": "2025-12-12T13:58:12.5366667Z", "updatedAt": "2025-12-12T13:58:12.5366667Z", "dataProviderId": "94", "remoteId": "787317394479550464", "contactList": {} }, "id": "787317394479550464", "type": "CommerceGridAudienceSegment" } ], "warnings": [], "errors": [] } ``` ### Partial `200 OK` response ```json theme={null} { "data": [], "warnings": [], "errors": [ { "traceId": "0ab8cdc52e17ecfd1ba9e5d1dacd102a", "traceIdentifier": "0ab8cdc52e17ecfd1ba9e5d1dacd102a", "type": "validation", "code": "name-must-be-unique", "instance": "@data/0", "title": "Segment name must be unique", "detail": "Another segment exists with the name: CRM users 2025" } ] } ``` *** ## Update Audience Segment This endpoint allows updating **Audience Segments**. The corresponding App should have the "**Audiences Manage**" permission enabled. ```http theme={null} https://api.criteo.com/{version}/commerce-grid/audience-segments ``` **Sample Request** ```bash theme={null} curl -L -X PATCH 'https://api.criteo.com/{version}/commerce-grid/audience-segments' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "id": "738406688413290496", "type": "CommerceGridAudienceSegment", "attributes": { "name": "CRM User E-mails 2025 (Updated)", "description": { "value": "Segment made of CRM user e-mails (Updated)" } } } ] }' ``` **Sample Response** ```json theme={null} { "data": [ { "attributes": { "name": "CRM User E-mails 2025 (Updated)", "description": "Segment made of CRM user e-mails (Updated)", "type": "ContactList", "createdAt": "2025-12-12T13:44:53.29Z", "updatedAt": "2025-12-12T13:46:39.4833333Z", "dataProviderId": "94", "remoteId": "crm_users.csv", "contactList": {} }, "id": "787314040225128448", "type": "CommerceGridAudienceSegment" } ], "warnings": [], "errors": [] } ``` *** ## Delete Audience Segment This endpoint allows deleting **Audience Segments**, either one by one or multiple of them. The corresponding App should have the "**Audiences Manage**" permission enabled. ```http theme={null} https://api.criteo.com/{version}/commerce-grid/audience-segments/delete ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/commerce-grid/audience-segments/delete' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": [ { "id": "738406561971802112", "type": "CommerceGridAudienceSegment" } ] }' ``` **Sample Response** ```json theme={null} { "data": [ { "id": "738406561971802112", "type": "CommerceGridAudienceSegment" } ], "warnings": [], "errors": [] } ``` *** ## Search for Audience Segments This endpoint allows searching for existing **Audience Segments** that satisfy one or multiple attributes at the same time. Results are paginated using `offset` and `limit` query parameters; if omitted, defaults to`0` and `50` respectively. The maximum `limit` is `100`. ```http theme={null} https://api.criteo.com/{version}/commerce-grid/audience-segments/search ``` **Sample Request:** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/commerce-grid/audience-segments/search?limit=50&offset=0' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "CommerceGridAudienceSegmentSearch", "attributes": { "dataProviderIds": [ "94" ], "audienceSegmentTypes": [ "ContactList" ] } } }' ``` **Sample Response** ```json expandable theme={null} { "meta": { "totalItems": 400, "limit": 50, "offset": 0 }, "data": [ { "id": "203134567785554216", "type": "CommerceGridAudienceSegment", "attributes": { "name": "Segment Name", "type": "ContactList", "createdAt": "2024-01-15T12:23:18.180Z", "updatedAt": "2024-01-15T12:23:18.180Z", "dataProviderId": "94", "remoteId": "users.csv", "contactList": { } } }, // ... { "id": "225702933721171456", "type": "CommerceGridAudienceSegment", "attributes": { "name": "Segment Name", "type": "ContactList", "createdAt": "2024-01-23T09:33:40.822Z", "updatedAt": "2024-01-23T09:33:40.822Z", "dataProviderId": "94", "remoteId": "some-other-id", "contactList": { } } } ], "errors": [], "warnings": [] } ``` *** ## Get Contact List Segment Statistics This endpoint allows retrieving statistics from a contact list **Audience Segment**. ```http theme={null} https://api.criteo.com/{version}/commerce-grid/audience-segments/{audienceSegmentId}/contact-list/statistics ``` **Sample Request** ```bash theme={null} curl -L -X GET 'https://api.criteo.com/{version}/commerce-grid/audience-segments/225702933721171456/contact-list/statistics' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** ```json theme={null} { "data": { "id": "225702933721171456", "identifierType": "CommerceGridContactListStatistics", "attributes": { "numberOfIdentifiers": 10000, "numberOfMatches": 5000, "matchRate": 0.5 } }, "errors": [], "warnings": [] } ``` *** ## Add/Remove identifiers in Contact List Audience Segment This endpoint allows to add/remove users in a specific contact list **Audience Segment**. Set `Add` or `Remove` in the `operation` attribute in the request to indicate if you want to add or remove the list of identifiers from the contact list. The corresponding App should have the "**Audiences Manage**" permission enabled.

Attribute

Data Type

Description

operation

enum

Operation required for the sub-set of users provided in the request

Accepted values: Add , Remove

Writeable? Y / Nullable? N

identifierType

enum

Type of identifiers that are being uploaded

Accepted values: Email , MadId , UserIdentifier , IdentityLink (LiveRamp IDs), BidSwitchId , FTrackId , PanoramaId , HadronId , IpAddressV4 , PageUrl , PageDomain , AppId

Writeable? Y / Nullable? N

identifiers

string\[]

Array of identifiers represented as strings

```http theme={null} https://api.criteo.com/{version}/commerce-grid/audience-segments/{audience-segment-id}/contact-list/add-remove ``` **Sample Request** - adding users to existing audience segment ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/commerce-grid/audience-segments/225702933721171456/contact-list/add-remove' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "AddRemoveContactlist", "attributes": { "operation": "Add", "identifierType": "Email", "identifiers": [ "abc@gmail.com", "def@gmail.com", "aef@gmail.com" ] } } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "AddRemoveContactlistResult", "attributes": { "contactListId": 523103620165619700, "operation": "Add", "requestDate": "2024-04-22T14:29:07.994Z", "identifierType": "Email", "nbValidIdentifiers": 3, "nbInvalidIdentifiers": 0, "sampleInvalidIdentifiers": [] } }, /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` **Sample Request** - removing users from existing audience segment ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/commerce-grid/audience-segments/225702933721171456/contact-list/add-remove' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "ContactlistAmendment", "attributes": { "operation": "Remove", "identifierType": "Email", "identifiers": [ "example1@gmail.com" ] } } }' ``` **Sample Response** ```json theme={null} { "data": { "type": "ContactlistAmendment", "attributes": { "operation": "Remove", "requestDate": "2018-12-10T10:00:50.000Z", "identifierType": "Email", "nbValidIdentifiers": 7342, "nbInvalidIdentifiers": 13, "sampleInvalidIdentifiers": [ "InvalidIdentifier" ] } }, /* omitted if no errors */ "errors": [], /* omitted if no warnings */ "warnings": [] } ``` **Identifier List Size Limit** Note that there is a limit of **50,000 identifiers per single request**. If you are adding more than 50,000 users, please split them into chunks of 50,000 and make multiple requests. *** ## Clear all identifiers in Contact List Audience Segment This endpoint resets a contact list **Audience Segment**, erasing all existing users identifiers. The corresponding App should have the "**Audiences Manage**" permission enabled. ```http theme={null} https://api.criteo.com/{version}/commerce-grid/audience-segments/{audienceSegmentId}/contact-list/clear ``` **Sample Request** ```bash theme={null} curl -L -X POST 'https://api.criteo.com/{version}/commerce-grid/audience-segments/225702933721171456/contact-list/clear' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample Response** 🟢 204 No Content (empty response body) Note that this will only wipe all of the users from the audience segment and will not delete the audience segment itself. **Note on Audience Computation** Audience updates are processed daily at 0h UTC and 12h UTC and can take around 5 hours to reflect on a live campaign. This is important for audiences that are frequently updated as changes should be ready for processing prior to these two times. # Coupon Source: https://developers.criteo.com/marketing-solutions/docs/coupon ## **Search Coupon** ### Retrieving Coupons for a Specific Advertiser Coupons created through Criteo's API will be returned for the designated advertiser ID. Only coupons created through API and Commerce Growth are returned. ```http theme={null} /advertisers/{advertiserId}/coupons ```  The API will return an array of the IDs, name, description (if specified) ad set ID, landing page URL, format, start date and end date (if specified) for the specified advertiser ID. Please note that the advertiser ID is required in the request URL. The offset and limit are optionals. **`offset`**\ 0 based index of the first coupon to return in the response. The default is 0. **`limit`**\ The number of coupons to be returned. The default is 50. **Response example:** ```json JSON expandable theme={null} { "data": [ { "type": "Coupon", "id": "18", "attributes": { "name": "My first coupon", "description": "Description of my first coupon", "author": "r.deckard", "advertiserId": "51", "adSetId": "345", "landingPageUrl": "https://my-landing-page.com", "startDate": "2021-11-23T18:25:43.511Z", "format": "LogoZone", "status": "Live", "images": [ { "width": 300, "height": 250, "slideUrls": ["https://static.criteo.net/image_1.jpg"] }, { "width": 130, "height": 90, "slideUrls": ["https://static.criteo.net/image_2.jpg"] } ], "showEvery": 3, "showDuration": 3, "rotationsNumber": 2, "id": "18", } }, { "type": "Coupon", "id": "19", "attributes": { "name": "My second Coupon", "description": "Description of my second coupon", "author": "r.deckard", "advertiserId": "51", "adSetId": "502", "landingPageUrl": "https://my-landing-page.com", "startDate": "2021-12-19T18:25:43.511Z", "endDate": "2022-01-01T10:00:00.511Z", "format": "FullFrame", "status": "Live", "images": [ { "width": 300, "height": 250, "slideUrls": ["https://static.criteo.net/image_1.jpg", "https://static.criteo.net/another-imagejpg"] }, { "width": 120, "height": 600, "slideUrls": ["https://static.criteo.net/image_2.jpg", "https://static.criteo.net/alternative-image.jpg"] } ], "showEvery": 1, "showDuration": 1, "rotationsNumber": 3, "id": "19" } ], "errors": [ ] /* omitted if no errors */ "warnings": [ ] /* omitted if no warnings */ } ``` ### Retrieving a Specific Coupon Coupon created through Criteo's API will be returned for the designated coupon ID. ```http theme={null} /advertisers/{advertiserId}/coupons/{couponId} ```  The API will return an array of the ID, type and coupon specific attributes for the specified coupon ID. Please note that the advertiser ID and coupon ID are required in the request URL. **Response example:** ```json JSON expandable theme={null} { "data": { "type": "Coupon", "id": "18", "attributes": { "name": "My first coupon", "description": "Description of my first coupon", "author": "r.deckard", "advertiserId": "51", "adSetId": "345", "landingPageUrl": "https://my-landing-page.com", "startDate": "2021-11-23T18:25:43.511Z", "format": "LogoZone", "images": [ { "width": 300, "height": 250, "slideUrls": ["https://static.criteo.net/image_1.jpg"] }, { "width": 130, "height": 90, "slideUrls": ["https://static.criteo.net/image_2.jpg"] } ], "showEvery": 3, "showDuration": 3, "rotationsNumber": 2 } }, "errors": [ ], /* omitted if no errors */ "warnings": [ ] /* omitted if no warnings */ } ``` *** ## **Get the list of Coupons supported sizes** Supported sized for the coupons will be returned for the designated ad set ID. ```http theme={null} /advertisers/{advertiserId}/coupons-supported-sizes ```  The API will return an array of the supported sizes by format (`LogoZone` and `FullFrame`) for the specified adset ID. Please note that the advertiser ID and adset ID are required in the request URL. **Response example:** ```json JSON theme={null} { "data": { "type": "CouponSupportedSizes", "attributes": { "logoZone": [ "300x40", "130x90", "300x54 ", "105x50", ... ], "fullFrame": [ "300x250", "160x600", "728x90", "300x600", ... ], "id": null }, "errors": [ ], /* omitted if no errors */ "warnings": [ ] /* omitted if no warnings */ } ``` *** ## **Creating A New Coupon** A new coupon can be created for a specific advertiser by making a `POST` call to the coupons' endpoint.\ The request body should specify the name, ad set ID, description (optional) and the coupon attributes. ### Coupon Attributes **`landingPageUrl `**\ Web redirection of the landing page url. **`startDate`**\ The date when the Coupon will be launched. **`endDate`**\ The date when the coupon will stop being displayed. If the end date is not specified (i.e. null), the coupon will always be displayed. **`format`**\ Format of the coupon. Can be `FullFrame ` or `LogoZone`. **`images`**\ List of slides images. **`showEvery`**\ Show the coupon every N seconds. Can be between 1 and 10. **`showDuration`**\ Show coupon for a duration of N seconds. Can be between 1 and 5. **`rotationsNumber`**\ Number of rotations for the coupons. The number can be between 1 and 10. ```http theme={null} /advertisers/{advertiserId}/coupons ``` **Request example:** ```json JSON theme={null} { "data": { "type": "CreateCouponRequest", "attributes": { "name": "New coupon", "adSetId": "345", "description": "Description of my new coupon", "landingPageUrl": "https://my-landing-page.com", "startDate": "2021-11-25T18:25:43.511Z", "format": "FullFrame", "images": [ { "width": 300, "height": 250, "slideBase64Strings": [ "{base 64 encoded image string}", "{another base 64 encoded image string}" ] } ], "showEvery": 1, "showDuration": 1, "rotationsNumber": 1 } } } ``` The API will return an array of the name, ad set ID, description (optional) and the coupon attributes of the new coupon. Please note that the advertiser ID is required in the request URL. **Response example:** ```json JSON expandable theme={null} { "data": { "type": "Coupon", "id": "18", "attributes": { "name": "New coupon", "description": "Description of my new coupon", "author": "r.deckard", "advertiserId": "510", "adSetId": "345", "landingPageUrl": "https://my-landing-page.com", "startDate": "2021-11-24T18:25:43.511Z", "format": "FullFrame", "images": [ { "width": 300, "height": 250, "slideUrls": [ "https://static.criteo.net/image.jpg", "https://static.criteo.net/image-2.jpg" ] } ], "showEvery": 1, "showDuration": 1, "rotationsNumber": 1, "id": "18" } }, "errors": [ ], /* omitted if no errors */ "warnings": [ ] /* omitted if no errors */ } ``` *** ## **Updating a Coupon** The coupon start date and end date can be updated by making a PUT request to the coupons' endpoint with a specific coupon ID and advertiser ID in the URL path. ```http theme={null} /advertisers/{advertiserId}/coupons/{couponId} ``` **Request example:** ```json JSON theme={null} { "data": { "type": "UpdateCouponRequest", "attributes": { "startDate": "2024-06-25T18:25:43.511Z" } } } ``` *** ## **Deleting a coupon** A coupon can be deleted by specifying the coupon ID and advertiser ID in the URL path of a `DELETE` call to the coupons' endpoint. ```http theme={null} /advertisers/{advertiserId}/coupons/{couponId} ``` The API will return an array with the coupon ID that was deleted. *** ## **Preview a coupon** Coupon can be previewed for the designated coupon ID ```http theme={null} /advertisers/{advertiserId}/coupons/{couponId}/preview ```  The API will return an array of the coupon HTML preview for the specified coupon ID. Please note that the advertiser ID and coupon ID are required in the request URL. **Response example:** ```json JSON theme={null} { "data": { "type": "CouponPreview", "attributes": { "previewHtml": " " } }, "errors": [ ], /* omitted if no errors */ "warnings": [ ]/* omitted if no warnings */ } ``` *** ## **Validation Errors** **`user-request-forbidden-advertiser `**\ The user doesn't have the permission to access the specified advertiser. **`user-request-forbidden-creative`**\ The user doesn't have the permission to access the specified creative. **`user-request-forbidden-ad`**\ The user doesn't have the permission to access the specified ad. **`invalid-action-with-managed-creative`**\ The action cannot be performed on a managed service creative. **`invalid-action-with-managed-ad`**\ The action cannot be performed on a managed service ad. **`invalid-creative-action-with-status `**\ The action cannot be performed due to the status of the creative. **`invalid-image`**\ One of the images provided is invalid. Please check the image requirements [here](https://help.criteo.com/kb/guide/en/image-ads-8hXUBDeeoo/Steps/775688) **`invalid-redirection-url-image`**\ The redirection URL specified doesn't match the advertiser domain. **`invalid-html-tag`**\ One of the HTML tags is not supported. Please check the list of supported ad servers [here](https://help.criteo.com/kb/guide/en/third-party-ads-QUSq5Astwy/Steps/775787,817360) **`invalid-creative-request`**\ Invalid request on the Creative endpoint. **`invalid-ad-request`**\ Invalid request on the Ad endpoint. # Creatives Source: https://developers.criteo.com/marketing-solutions/docs/creative ## **Search Creatives** ### Retrieving Creatives for a Specific Advertiser Creatives created through Criteo's API will be returned for the designated advertiser ID. Only static images, HTML Ad Tags, Adaptive and dynamic creatives created through API and Commerce Growth are returned. ```http theme={null} /advertisers/{advertiserId}/creatives ```   The API will return an array of the IDs, formats and creative specific attributes for the specified advertiser ID. Please note that the advertiser ID is required in the request URL. The offset and limit are optionals. **`offset`**\ 0 based index of the first creative to return in the response. The default is 0. **`limit`**\ The number of creatives to be returned. The default is 50. Response example: ```json JSON expandable theme={null} { "data": [ { "id": "18", "type": "Creative", "attributes": { "name": "My image", "description": "Description of the creative", "author": "r.deckard", "status": "Live", "format": "Image", "advertiserId": "51", "datasetId": "49", "imageAttributes": { "urls": [ "https://static.criteo.net/image_1.jpg", "https://static.criteo.net/image_2.jpg" ], "landingPageUrl": "https://my-landing-page.com" }, "id": "18" } }, { "type": "Creative", "id": "19", "attributes": { "name": "My HTML ad", "description": "Description of the creative", "author": "r.deckard", "status": "Draft", "format": "HtmlTag", "advertiserId": "51", "datasetId": "49", "htmlTagAttributes": { "tags": [ { "htmlTag": "", "size": { "width": 600, "height": 400 } } ] }, "id": "19" } }, { "type": "Creative", "id": "20", "attributes": { "name": "My dynamic creative", "description": "Description of the creative", "author": "r.deckard", "status": "Draft", "format": "Dynamic", "advertiserId": "51", "datasetId": "49", "dynamicAttributes": { "logos": [ { "shape": "Horizontal", "url": "https://static.criteo.net/image_1.jpg" } ], "creativeBackgroundColor": "#A1A1A1", "bodyTextColor": "#A2A2A2", "pricesColor": "#A3A3A3", "primaryFont": "Arial", "callsToAction": [ "Go!", "Buy now" ], "productImageDisplay": "ShowFullImage" } }, "id": "20" } ], "errors": [ ], "warnings": [ ] } ``` ### Retrieving a Specific Creative Creative created through Criteo's API will be returned for the designated creative ID. ```http theme={null} /creatives/{creativeId} ```  The API will return an array of the ID, format and creative specific attributes for the specified creative ID. Please note that the creative ID is required in the request URL.\ Response example: ```json JSON theme={null} { "data": { "id": "18", "type": "Creative", "attributes": { "name": "My image", "description": "Description of the creative", "author": "r.deckard", "status": "Live", "format": "Image", "advertiserId": "51", "datasetId": "49", "imageAttributes": { "urls": [ "https://static.criteo.net/image_1.jpg", "https://static.criteo.net/image_2.jpg" ], "landingPageUrl": "https://my-landing-page.com" }, "id": "18" } }, "errors": [], "warnings": [] } ``` *** ## **Generating new Creatives** You can use API endpoints detailed below to generate new creatives. Depending on the Creative format chosen some attributes will vary. Here is the list of attributes that can be included in the request. If not specified as *optional*, the attribute is mandatory. **`name`**\ The name of Creative **`description`** (optional)\ The description of Creative **`format`**\ It should have the value `Image`, `Dynamic`, `Adaptive` or `HtmlTag` **`datasetId`**\ Dataset linked to the Creative **`ImageWriteAttributes`** (optional)\ Encapsulates all the attributes of **Image** creatives, it's mandatory only for creatives of that format. **`HtmlTagWriteAttributes`** (optional)\ Encapsulates all the attributes of **HtmlTag** creatives, it's mandatory only for creatives of that format. **`DynamicWriteAttributes`** (optional)\ Encapsulates all the attributes of **Dynamic** creatives, it's mandatory only for creatives of that format. **`AdaptiveWriteAttributes`** (optional)\ Encapsulates all the attributes of **Adaptive** creatives, it's mandatory only for creatives of that format. *** ## **Creating A New Image Creative** A new image creative can be created for a specific advertiser by making a POST call to the creatives' endpoint. The request body should specify the name, ad set ID, description (optional), format (`Image`), dataset ID and image attributes of the new image creative. ```http theme={null} /advertisers/{advertiserId}/creatives ``` **Request example:** ```json JSON theme={null} { "data": { "type": "CreativeRequest", "attributes": { "name": "New image", "description": "Description of the new Image creative", "format": "Image", "datasetId": "49", "imageWriteAttributes": { "base64Strings": [ "{base 64 encoded image string}", "{base 64 encoded image string}" ], "landingPageUrl": "https://my-landing-page.com" } } } } ``` The API will return an array of the ID, name, description (if specified), author, status, format , advertiser ID, dataset ID and image attributes of the new image creative. Please note that the advertiser ID is required in the request URL.  **Response example:** ```json JSON theme={null} { "data": { "id": "20", "type": "Creative", "attributes": { "name": "New image", "description": "Description of the new Image creative", "author": "r.deckard", "status": "Draft", "format": "Image", "advertiserId": "51", "datasetId": "49", "imageAttributes": { "urls": [ "https://www.criteo.com/myimage_1", "https://www.criteo.com/myimage_2" ], "landingPageUrl": "https://my-landing-page.com" }, "id": "20" } }, "warnings": [], "errors": [] } ``` *** ## **Creating a new HTML Ad Tags** A new HTML Ad Tag can be created for a specific advertiser by making a POST call to the creatives' endpoint. The request body should specify the name, adset ID, description (optional), format (`HtmlTag`), dataset ID and HTML attributes of the new HTML creative. ```http theme={null} /advertisers/{advertiserId}/creatives ``` **Request example:** ```json JSON theme={null} { "data": { "type": "CreativeRequest", "attributes": { "name": "New HTML Tag Creative", "description": "Description of the new HTML Tag Creative", "format": "HtmlTag", "datasetId": "49", "htmlTagWriteAttributes": { "tags": [ { "htmlTag": "", "size": { "width": 300, "height": 250 } }, { "htmlTag": "", "size": { "width": 600, "height": 400 } } ] } } } } ``` The API will return an array of the ID, name, description (if specified), author, status, format , advertiser ID, dataset ID and HTML attributes of the new HTML Ad Tag creative. Please note that the advertiser ID is required in the request URL.  **Response example:** ```json expandable theme={null} { "data": { "id": "21", "type": "Creative", "attributes": { "name": "New HTML Tag Creative", "description": "Description of the new HTML Tag Creative", "author": "r.deckard", "status": "Draft", "format": "HtmlTag", "advertiserId": "51", "datasetId": "49", "htmlTagAttributes": { "tags": [ { "htmlTag": "", "size": { "width": 300, "height": 250 } }, { "htmlTag": "", "size": { "width": 600, "height": 400 } } ] }, "id": "21" } }, "warnings": [], "errors": [] } ``` *** ## **Creating a new dynamic creative** A new dynamic creative can be created for a specific advertiser by making a POST call to the creatives' endpoint. The request body should specify the name, adset ID, description (optional), format (`Dynamic`), dataset ID, inventory type (`native` or `display`) and dynamic attributes of the new HTML Tag creative. ### Dynamic attributes **`logoBase64String`**\ Logo displayed in the banner. **`creativeBackgroundColor`**\ Background color of the banner. Hexadecimal value **`bodyTextColor`**\ Main text color used in the banner. Hexadecimal value **`pricesColor`**\ Color applied to the product prices. Hexadecimal value **`primaryFont`**\ Primary font used in the banners. Available fonts listed [here](https://help.criteo.com/kb/guide/en/dynamic-ads-BlOsyHZFaF/Steps/775669) **`callsToAction`**\ Array of Call-to-Action. **`productImageDisplay`**\ Display format of the product images. Can be `ShowFullImage` (images fit inside the allocated space) or `ZoomOnImage`. If you choose `ZoomOnImage`, there may be some image cropping. ```http theme={null} /advertisers/{advertiserId}/creatives ``` **Request example:** ```json JSON theme={null} { "data": { "type": "CreativeRequest", "attributes": { "name": "New dynamic creative", "description": "Description of the new dynamic creative", "format": "Dynamic", "datasetId": "49", "dynamicWriteAttributes": { "logoBase64String": "{base 64 encoded image string}", "creativeBackgroundColor": "ab00f", "bodyTextColor": "496b4n", "pricesColor": "d56d2e", "primaryFont": "Arial", "callsToAction": ["Buy now", "Go"], "productImageDisplay": "ShowFullImage" } } } } ```  The API will return an array of the ID, name, description (if specified), author, status, format, advertiser ID, dataset ID and dynamic attributes of the new dynamic creative. Please note that the advertiser ID is required in the request URL. **Response example:** ```json JSON expandable theme={null} { "data": { "id": "22", "type": "Creative", "attributes": { "name": "New dynamic creative", "description": "Description of the new dynamic creative", "author": "r.deckard", "status": "Draft", "format": "Dynamic", "advertiserId": "51", "datasetId": "49", "dynamicAttributes": { "logos": [ { "shape": "Horizontal", "url": "https://www.criteo.com/myimage_1" } ], "creativeBackgroundColor": "ab00f", "bodyTextColor": "496b4n", "pricesColor": "d56d2e", "primaryFont": "Arial", "callsToAction": ["Buy now", "Go"], "productImageDisplay": "ShowFullImage" }, "id": "22" } }, "warnings": [], "errors": [] } ``` *** ## **Creating a new Adaptive creative** A new Adaptive creative can be created for a specific advertiser by making a POST call to the creatives' endpoint. The path should specify the Advertiser ID. The request body should specify the `adaptiveWriteAttributes`. ### `adaptiveWriteAttributes` elements **`layouts`** The adaptive formats that should be enabled. It can contain any of the following values: "Editorial", “Montage“ or "InBannerVideo". **`logoBase64String`**\ Logo image as a base-64 encoded string\ Accepted formats: jpeg, png under 5MB (same as dynamic creatives) **`headlineText`**\ The headline of the banner. **`headlineFont`**\ The font of the headline. **`descriptionText`**\ The description of the banner. **`descriptionFont`**\ The font of the description. **`colors`**\ The color aliases used by Adaptive banners in Hexadecimal format. All the following have to be defined: → *logoAreaAndTitleColor*: The color of the logo area\ → *backgroundColor*: The color of the background.\ → *text1Color*: The color of the headline and description.\ → *text2Color*: The color of the image set headline.\ → *ctaBackgroundColor*: The color of the background of the cta button.\ → *ctaTextColor*: The color of the text in cta button. **`callsToAction`**\ A Call-to-Action (CTA) is an action-driven instruction to your audience intended to provoke an immediate response, such as “Buy now” or “Go!”. **`ImageSetsBase64`**\ Represents multiple image sets, each image set consists of the headline and multiple images in base64. Accepted formats: jpeg, png, under 5MB This field becomes required only if the `Montage` layout is enabled. The field is applicable to the other formats. **`imageDisplay`**\ Value can be `ShowFullImage` or `ZoomOnImage`.\ Choose whether your image set should fit inside the allocated space (`ShowFullImage`) or whether they should fill that space (`ZoomOnImage`). If `ZoomOnImage` is chosen, there may be some image cropping. The field becomes required when the `Montage` layout is enabled or if the the scope of the ad that the user wants to create later is `Native`. This option is not used in the other cases. **`videoBase64Strings`**\ Represents one video as base64 in different ratios. Ideally 2 videos will be provided, one having a horizontal ratio and the other one a vertical ratio so that the use can deploy its creative. Accepted formats: mp4, under 25MB. This field becomes required only if `InBannerVideo` layout is enabled. **`landingPageUrl`**\ The web redirection URL to which the user will be redirected when clicking on the banner. ```http theme={null} /advertisers/{advertiser-id}/creatives ``` **Request example:** ```json JSON expandable theme={null} { "data": { "type": "CreativeRequest", "attributes": { "datasetId": "49", "name": "new adaptive creative", "description": "description for adaptive crea", "format": "Adaptive", "adaptiveWriteAttributes": { "layouts": ["Editorial", "Montage", "InBannerVideo"], "logoBase64String": "{base 64 encoded image string}", "headlineText": "This a headline", "headlineFont": "Arial", "descriptionText": "This a description", "descriptionFont": "Arial", "colors": { "logoAndTitleColor": "#CD3414", "backgroundColor": "#1FCD14", "text1Color": "#0B41AB", "text2Color": "#CD3414", "ctaBackgroundColor": "#1FCD14", "ctaTextColor": "#0B41AB" }, "callsToAction": ["Go go go", "Click me"], "imageSetsBase64": [{ "imageBase64Strings": [ "{base 64 encoded image1 string}", "{base 64 encoded image2 string}", "{base 64 encoded image3 string}" ], "headlineText": "image set 1 headline" }, { "imageBase64Strings": [ "{base 64 encoded image4 string}", "{base 64 encoded image5 string}", "{base 64 encoded image6 string}" ], "headlineText": "image set 2 headline" } ] }, "imageDisplay": "ShowFullImage", "videoBase64Strings": [ "{base 64 encoded video1 string}", "{base 64 encoded video2 string}" ], "landingPageUrl": "https://example.com/" } } } } ``` **Response example:** ```json JSON expandable theme={null} { ... "data": { "type": "Creative", "id": "18", "attributes": { "advertiserId": "51", "datasetId": "49", "name": "new adaptive crea", "description": "description for adaptive crea", "format": "Adaptive", "status": "Live", "author": "r.deckard", "adaptiveAttributes": { "layouts": ["Editorial", "Montage", "InBannerVideo"], "logos": [{ "shape": "Horizontal", "url": "https://static.criteo.net/toto.jpg" }], "headlineText": "This a headline", "headlineFont": "Arial", "descriptionText": "This a description", "descriptionFont": "Arial", "colors": { "logoAndTitleColor": "#CD3414", "backgroundColor": "#1FCD14", "text1Color": "#0B41AB", "text2Color": "#CD3414", "ctaBackgroundColor": "#1FCD14", "ctaTextColor": "#0B41AB" }, "callsToAction": ["Go go go", "Click me"], "imageSets": [{ "images": [{ "shape": "Horizontal", "url": "https://static.criteo.net/image_horizontal1.jpg" }, { "shape": "Vertical", "url": "https://static.criteo.net/image_vertical1.jpg" }, { "shape": "Square", "url": "https://static.criteo.net/image_square1.jpg" } ], "headlineText": "image set 1 headline" }, { "images": [{ "shape": "Horizontal", "url": "https://static.criteo.net/image_horizontal2.jpg" }, { "url": "https://static.criteo.net/image_vertical2.jpg", "shape": "Vertical" }, { "url": "https://static.criteo.net/image_square2.jpg", "shape": "Square" } ], "headlineText": "image set 2 headline" } ] }, "imageDisplay": "ShowFullImage", "videos": [{ "duration": 25.3422, "shape": "Horizontal", "url": "https://static.criteo.net/video_horizontal.mp4" }, { "duration": 30, "shape": "Vertical", "url": "https://static.criteo.net/video_vertical.mp4" } ], "landingPageUrl": "https://example.com/" } } }, "errors": [ /* omitted if no errors */ ... ], "warnings": [ /* omitted if no warnings */ ... ] ... } ``` *** ## **Previewing a Creative** You can generate the preview HTML of a creative given a size (width x height). The parameters are passed as query parameters and not in the body. ### Dynamic attributes **`creative-id`** (mandatory)\ The ID of the creative to preview. **`height`** (mandatory)\ The height of the banner to generate. **`width`** (mandatory)\ The width of the banner to generate. ```http theme={null} /creatives/{creative-id}/preview ``` **Response example:** ```html HTML theme={null} ... ...
Click me!
... ``` *** ## **Updating a Creative** The creative name, description and creative specific attributes can be updated by making a PUT request to the creatives' endpoint with a specific creative ID in the URL path. Please note that the advertiser ID, dataset ID, ad set ID and format (`Image`, `HtmlTag`,`Adaptive` or `Dynamic`) are required in the PUT body. ```http theme={null} /creatives/{creativeId} ``` **Request example:** ```json JSON theme={null} { "data": { "type": "CreativeRequest", "attributes": { "name": "Image title updated", "description": "Image description updated", "format": "Image", "advertiserId": "51", "datasetId": "49", "imageWriteAttributes": { "base64Strings": [ "{base 64 encoded image string}", "{base 64 encoded image string}" ], "landingPageUrl": "https://new-landing-page.com" } } } } ```   The API will return an array of the ID, name, description, format, author, status and image/HTML Ad Tag attributes of the specified creative ID. **Response example:** ```json JSON theme={null} { "data": { "id": "20", "type": "Creative", "attributes": { "name": "Image title updated", "description": "Image description updated", "author": "r.deckard", "status": "Live", "format": "Image", "advertiserId": "51", "datasetId": "49", "imageAttributes": { "urls": [ "https://www.criteo.com/myimage_3", "https://www.criteo.com/myimage_4" ], "landingPageUrl": "http://new-landing-page.com" }, "id": "20" } }, "warnings": [], "errors": [] } ``` *** ## **Deleting a creative** A creative can be deleted by specifying the creative ID in the URL path of a DELETE call to the creatives' endpoint. ```http theme={null} /creatives/{creativeId} ```  The API will return an array with the creative ID that was deleted. **Response example:** ```json JSON theme={null} { "errors": [], "warnings": [] } ``` Make sure that the Creative is not linked to any Ad set before deletion. *** ## **Validation Errors** **`user-request-forbidden-advertiser `**\ The user doesn't have the permission to access the specified advertiser. **`user-request-forbidden-creative`**\ The user doesn't have the permission to access the specified creative. **`user-request-forbidden-ad`**\ The user doesn't have the permission to access the specified ad. **`invalid-action-with-managed-creative`**\ The action cannot be performed on a managed service creative. **`invalid-action-with-managed-ad`**\ The action cannot be performed on a managed service ad. **`invalid-creative-action-with-status `**\ The action cannot be performed due to the status of the creative. **`invalid-image`**\ One of the images provided is invalid. Please check the image requirements [here](https://help.criteo.com/kb/guide/en/image-ads-8hXUBDeeoo/Steps/775688) **`invalid-redirection-url-image`**\ The redirection URL specified doesn't match the advertiser domain. **`invalid-html-tag`**\ One of the HTML tags is not supported. Please check the list of supported ad servers [here](https://help.criteo.com/kb/guide/en/html-ad-tags-QUSq5Astwy/Steps/775787) **`invalid-creative-request`**\ Invalid request on the Creative endpoint. **`invalid-ad-request`**\ Invalid request on the Ad endpoint. ## What's next * [Ads](/marketing-solutions/docs/ads) * [Coupon](/marketing-solutions/docs/coupon) # Creatives Source: https://developers.criteo.com/marketing-solutions/docs/creatives **Creative Taxonomy** Criteo offers different creative types to build based on your business needs and marketing goals: * Image creatives allow an advertiser to decide how to tell a brand story with ready-made static or animated GIF images in a range of sizes. * HTML Ad Tags allow an advertiser to set creatives that are not hosted by Criteo but on a different ad server such as Google, Sizmek, or AdForm. They are created with HTML tags provided by the ad server. For the list of supported [ad servers](https://help.criteo.com/kb/guide/en/html-ad-tags-QUSq5Astwy/Steps/775787) and supported sizes per country. **Ad Taxonomy** Ads link the image or HTML Ad Tags to Ad sets to define what an audience will see in your creatives as they browse the web and mobile devices. They use the visuals from your creatives such as images or HTML Ad Tags and link them to Ad sets. You can define the name, scheduling date, campaign, and ad set. The Creative API endpoint allows you to manage your Creatives and Ads by creating, deleting, and updating them to meet your business needs. This API allows you to set-up images and HTML Ad Tags to use across several ad sets, and retrieve the list of ads for an overview of what is live for an advertiser or campaign. # Display Multipliers Source: https://developers.criteo.com/marketing-solutions/docs/display-multipliers ## Introduction Criteo has historically permitted **bid customization for each category** of products associated with your Ad Set. Previously, each product category had its own separate, absolute bid level.\ For example, an Ad Set with a bid level of `$2.00 USD` might have a bid level of `$1.00 USD` set for **Category A** and `$4.00 USD` for **Category B**. With the Criteo API, this bidding behavior can be achieved with **display multipliers**. With **display multipliers**, these values are now expressed as a **fraction** of the overall Ad Set bid level. In the example above, **Category A** would have a display multiplier value of `0.5` and **Category B** would have a display multiplier value of `2`. *** ## Retrieve Display Multipliers for an Ad Set The display multipliers associated with a specific Ad Set can be retrieved via a `GET` request to the `/ad-sets` endpoint, with the Ad Set ID as a URL parameter and `/display-multipliers` specified. ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/ad-sets/{adSetId}/display-multipliers ``` **Sample response** The API will return an array of categories associated with the campaign: ```json JSON theme={null} { "data": [ { "type": "ReadAdSetDisplayMultiplier", "attributes": { "id": "12345|1", "categoryName": "Shoes", "displayMultiplier": 1.2 } }, { "type": "ReadAdSetDisplayMultiplier", "attributes": { "id": "12345|2", "categoryName": "Scarves", "displayMultiplier": 0.8 } } ], "errors": [] } ``` *** ## Update Display Multipliers The fields of one or more of an Ad Set's display multipliers can be updated by making a `PATCH` request to the `/ad-sets` endpoint, with the Ad Set ID as a URL parameter and `/display-multipliers` specified. For example, the following call would update the `displayMultiplier` values for the category IDs `1` and `2`:  ```http theme={null} https://api.criteo.com/2026-01/marketing-solutions/ad-sets/{adSetId}/display-multipliers ``` **Sample request** ```json JSON theme={null} { "data": [ { "type": "WriteAdSetDisplayMultipliers", "attributes": { "id": "12345|1", "displayMultiplier": 2.0 } }, { "type": "WriteAdSetDisplayMultiplier", "attributes": { "id": "12345|2", "displayMultiplier": 1.1 } } ] } ```  **Sample response** The API will return an array of Ad Sets that have been updated successfully in the response `data`. These will contain only two parameters, `type` and `id`. ```json JSON theme={null} { "data": [ { "type": "ReadAdSetDisplayMultiplier", "id": "12345|1" }, { "type": "ReadAdSetDisplayMultiplier", "id": "12345|2" } ], "errors": [], "warnings": [] } ``` **Updating Multiple Display Multiplayers** This endpoint allows you to update several display multipliers within a single call. When updating multiple items, note that some updates may succeed while others fail. *** ## Validation Errors In addition to [general API errors](/criteo-apis/docs/api-error-types), you may encounter validation errors when updating a display multiplier. Below is a list of error codes for display multiplier validation and a more detailed description of their meaning. **`campaign--display-multiplier-update-check--category-not-enabled`**\ The category targeted by the display multiplier is not enabled. **`campaign--display-multiplier-update-check--invalid-display-multiplier`**\ The value provided in the display multiplier field is not valid. Expected values are between 0.5 and 2.0, inclusive. ## What's next * [Category Bids](/marketing-solutions/docs/category-bids) # Get Advertiser Portfolio Source: https://developers.criteo.com/marketing-solutions/docs/get-advertiser-portfolio # MPO Real-Time Asynchronous API Source: https://developers.criteo.com/marketing-solutions/docs/getting-realtime-mpo-statistics **Important Data Usage Warning** This data is generated in real time and is intended **only for real-time reporting purposes**. It is not subject to standard data cleaning practices (deduplication, quality checks) and **must not be used for pricing, bidding, invoicing, or any financial decision-making.** **BETA Access**
The API is currently in **beta** and is only available to a limited list of clients onboarded by the Criteo technical team. You can find the reference for the endpoints mentioned in the page in [the **Preview** version](/marketing-solutions/v2026-preview/reference/analytics/get-realtime-product) of this documentation.
*** ## Overview This API provides real-time reporting for **Marketplace Performance Outcomes (MPO)** via an asynchronous export workflow designed for large volumes of data. * **Data latency:** Approximately 10 minutes. * **Base URL:** ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/ ``` * **Compatibility:** This endpoint supports both **multi-seller** and **single-seller** campaign configurations. The workflow is: 1. Create an asynchronous report job with your filters. 2. Poll the job status until it is complete. 3. Download the generated export file (CSV or JSON). *** ### 1. Create a report job **Endpoint:** `POST /stats/realtime-reports/export` Submit a request with your desired filters. The API creates an export job and returns an identifier (UUID) and a `status` (typically `Pending`). ### 2. Poll for Completion **Endpoint:** `GET /stats/report-jobs/{reportId}` Poll the job status until it reaches `Done`. Do not poll more than once every 5–10 seconds to remain within rate limits. * **Status options:** `Pending`, `Done`, `Failure`, `Expired`. * **Note:** Identical requests may reuse cached results, returning a previously generated ID. ### 3. Download the report **Endpoint:** `GET /stats/realtime-reports/{reportId}` Once the status is `Done`, this call returns the raw file bytes. * **CSV output:** `Content-Type: text/csv`. * **JSON output:** `Content-Type: application/json`. *** ## Data models ### Request attributes (`RealTimeProductReportJob`) *(\*) - Required* #### Dimensions #### Metrics *** ## Step 1. Create an Async Report Job ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/realtime-reports/export ``` This endpoint creates a new asynchronous report job for a real-time product report. The backend triggers production of an export file and may reuse cached results when the same request has already been processed. ### Sample Request ```json theme={null} { "data": { "type": "RealTimeProductReportJob", "attributes": { "fileFormat": "csv", "advertiserIds": ["321"], "campaignIds": ["12345", "56789"], "sellerIds": ["254614150"], "dimensions": ["advertiserId", "campaignId", "sellerId"], "metrics": ["clicks", "displays", "cost"], "startDate": "2026-01-09T08:00:00Z", "endDate": "2026-01-09T09:00:00Z", "timezone": "UTC" } } } ``` ### Sample Response #### Successful Response ```json theme={null} { "exportId": "45f7ec55-1008-4372-9144-1da37d8dccc2", "status": "Pending", "message": null } ``` #### Error Example: unsupported `fileFormat` If `fileFormat` is not one of `csv` or `json`, the API returns a `400 Bad Request` validation error. ```json theme={null} { "warnings": [], "errors": [ { "traceId": "31500d5059bb85b2168e9256f8722fa8", "type": "validation", "code": "json-serialization-error", "title": "JSON error", "detail": "data.attributes.fileFormat 'xls' not valid. Must be one of 'Csv','Json'" } ] } ``` *** ## Step 2. Poll for completion ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/report-jobs/{reportId} ``` This endpoint polls the job status until it reaches `Done`.
Do not poll more than once every 5–10 seconds to remain within rate limits. * **Status options:** `Pending`, `Done`, `Failure`, `Expired`. * **Note:** Identical requests may reuse cached results, returning a previously generated ID. *** ## Step 3. Download Report Output ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/realtime-reports/{reportId} ``` This endpoint downloads the file corresponding to a completed export job. Download availability window Export files generated by the MPO Real-Time Asynchronous API are only guaranteed to be available for download for a short period after the job reaches `status = Done` (typically up to **4 hours**). If the file has expired, you must create a new export job and download its output within this retention window. * If `fileFormat = csv` → `Content-Type: text/csv` * If `fileFormat = json` → `Content-Type: application/json` ### Path Parameters *(\*) - Required* ### Example Request ```http theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/realtime-reports/45f7ec55-1008-4372-9144-1da37d8dccc2 ``` #### Successful response * **200 OK** only if job status is `Done`. * Body contains **raw file bytes** (CSV or JSON). ### Output formats #### CSV output The response contains a header row followed by data rows. ```csv theme={null} "advertiserId","campaignId","clicks","displays","cost" 321,12345,1873,800247,992.21671380425 321,56789,17927,5275096,3460.71409576333 ... ``` #### JSON output The response contains a columnar JSON payload with a `data` array and top-level `columns` and `rows` fields. ```json theme={null} { "columns": [ "advertiserId", "campaignId", "clicks", "displays", "cost" ], "data": [ [ 321, 12345, 17927, 5275096, 3460.71409576333 ], [ 321, 56789, 1873, 800247, 992.21671380425 ] ], "rows": 2 } ``` *** ## Validation rules The following validation rules are explicitly described via field notes and domain errors. ### 1) Required fields * `advertiserIds` is **required**. * Missing required fields yields `invalid-query`. ### 2) File format * `fileFormat` must be one of `csv` or `json`. * Otherwise the API returns `json-serialization-error` (as shown in the example). ### 3) Time interval definition You must use **exactly one** of: * **Relative interval:** `lookbackWindow` (minutes from now). * **Absolute interval:** `startDate` (and optionally `endDate`). Rules: * `lookbackWindow` must be within **60–1440**. * `lookbackWindow` **cannot** be combined with `startDate` and/or `endDate`. * `startDate` is **mutually exclusive** with `lookbackWindow`. * `startDate` must be within the **last 24 hours** relative to “now”. Requests with an older `startDate` are **rejected**. * If `startDate` is provided and `endDate` is omitted, `endDate` defaults to the **current time**. ### 4) Time zone * `timezone` must exist in the IANA Time Zone database. * Invalid time zones yield `invalid-query` (as part of "invalid query definition"). ### 5) Dimension combination constraints * Only **one** of the following dimensions can be used in a single request: * `productId` * `hour` * `minute` Violations yield `invalid-dimensioncombination`. ### 6) Report lifecycle constraints * Downloading output is only valid when `status == Done`. * If the job does not exist (or is not visible), the API returns `export-not-found` and maps it to HTTP `403`. * If the job exists, but the output has been permanently deleted, the API returns `export-alreadyexpired`. ### 7) Caching behavior (identical requests) * Identical requests may reuse cached results, meaning a previous export/report ID may be returned instead of generating a new export. *** ## Errors & status codes ### HTTP status codes ### Domain errors / validation errors ## What's next * [Validation Errors](/marketing-solutions/docs/validation-errors) * [MPO Standard Reporting API](/marketing-solutions/docs/mpo-standard-reporting-api) # Getting Statistics Source: https://developers.criteo.com/marketing-solutions/docs/getting-statistics ## Overview Single-Seller performance is exposed via the **same MPO stats APIs** used for multi-seller campaigns. The key difference is using the **right combination of identifiers** to get data at the correct granularity. ### Available stats endpoints

Endpoint

Use case

GET /marketplace-performance-outcomes/stats/campaigns

Template-level aggregation across all sellers

GET /marketplace-performance-outcomes/stats/sellers

Per-seller aggregation across campaigns

GET /marketplace-performance-outcomes/stats/seller-campaigns

Per seller-campaign (most granular)

You can find full endpoint details in the\ [Marketplace Performance Outcomes – Stats Reference](/marketing-solutions/reference/campaign/get-marketplace-advertisers). ### Choosing the right identifiers Use the appropriate combination of identifiers depending on the granularity you need:

Identifier

When to use

campaignId (template)

Filter stats for all sellers under a specific template

sellerId

Filter stats for a specific seller across templates

sellerCampaignId

Filter stats for a specific seller on a specific template (most precise)

### Monitoring after onboarding After creating a seller's first budget and once the Single-Seller campaign is provisioned: * Allow for the **asynchronous provisioning delay** before expecting impressions. * Query `GET /marketplace-performance-outcomes/stats/seller-campaigns` with: * `sellerId` = the onboarded seller * `campaignId` = the template campaign ID * Monitor **impression volume and spend**; if a `productSet` is configured, a whitelist with many invalid or inactive IDs may result in **under-delivery**. # Is Criteo API for you? Source: https://developers.criteo.com/marketing-solutions/docs/is-criteo-api-for-you With the Criteo API, you can programmatically create, manage, and scale campaigns. You may benefit from the Criteo API if you fall into one of the following categories: * **Advertiser**: You require a custom solution to programmatically create, manage, and view reports on your Criteo campaigns beyond what’s available in Commerce Growth. You have internal engineering resources to connect to the API * **Agency**: You offer complementary tools to advertisers who lack the resources and bandwidth to integrate with the Criteo API directly * **Partners**: You offer complementary tools to advertisers or agencies to enrich their Criteo campaigns Before getting started with the Criteo API, review our [API Versioning Policy](/criteo-apis/docs/versioning-policy) and follow our [Get Started](/criteo-apis/docs/create-your-partner-account) guide. # Log-Level Source: https://developers.criteo.com/marketing-solutions/docs/log-level ## **Introduction** The Criteo API can provide log-level, publisher-oriented information on your ad impressions and clicks in the form of daily reports. These reports include publisher domains where ads are displayed, timestamps of displayed ads, the price you are paying for each click, and contextual information such as user environment and device. You can retrieve this information at any time through the Criteo API in the form of reports that can integrate back into your systems. Reports are available for up to 30 days, starting from yesterday. *** ## Endpoint Below is an example using a basic cURL request: ```bash theme={null} curl -X POST "https://api.criteo.com/2026-01/log-level/advertisers/{advertiser-id}/report" -H "accept: text/plain" -H "Content-Type: application/json-patch+json" -H "Authorization: Bearer XXXXX " -d "{ \"startDate\": \"2021-02-03\", \"endDate\": \"2021-02-04\"}" ``` The call above will return an array of objects containing links to download the reports. The reports will be split out by advertiser and day. No result will be returned if the query pre-dates a 30-day period (starting from yesterday). Due to the high volume of impression date, this query only supports daily files. **Response example:** ```json JSON theme={null} { "data": [ { "type": "TransparencyReport", "attributes": { "advertiserId": "XXXXX", "tokenValidUntil": "2021-02-04T22:42:44.3437476Z", "files": [ { "fileName": "2021-02-03_v1.csv.gz", "url": "https://criteocpp.blob.core.windows.net/XXXXX }, { "fileName": "2021-02-04_v1.csv.gz", "url": "https://criteocpp.blob.core.windows.net/XXXXX }, ] } } ] } ``` In the array returned, the report address will be located in the `stats` section under the `url` parameter. You will need to retrieve the report from this location to see the data. There are many ways to retrieve this report but in this example, we will be using curl. ```bash theme={null} curl -o "saved_report.csv.gz" "#link from the url param#" ``` Once the report is downloaded, you will need to un-compress it and open it. The downloaded report will contain column headers; please refer to the documentation below. *** ## Data specification

Column in CSV

Metric

Type

Description

A

Day

String

Day of impression or click event

B

Hour

Integer

Hour of impression or click event

C

Timestamp

Integer

Timestamp of impression or click event

D

Event type

String

Impression or click event specification

E

Campaign ID

Integer

Criteo-assigned numerical AdSet identifier

F

Campaign name

String

Name of AdSet as seen in Commerce Growth

G

Ad format

String

Format of display (i.e. 'mozaic' is a dynamic banner)

H

Banner ID

Integer

Criteo-assigned numerical banner identifier

I

Category ID

Integer

Identifier of product category in the catalog

J

Category name

String

Name of product category in the catalog

K

Referrer

String

Publisher domain on which ad was served

L

Environment

String

Browsing medium (web or app)

M

Device family

String

Device specification of user agent

N

OS family

String

Operating system specification of user agent

O

App ID

String

Identifier of app

P

App name

String

Specification of app

Q

Viewability

String

Indicates if display was viewable for at least 50% of a continuous second

-1 = impression was untracked; no insight into if it was viewed

0 = impression was tracked, but not viewable

1 = impression was tracked, and was viewable

R

Marketplace revenue currency

String

Currency of the impression display cost

S

Marketplace revenue (local)

Double

Impression display cost in local currency

T

Marketplace revenue (USD)

Double

Impression display cost in USD currency

U

Click revenue currency

String

Currency of the click cost

V

Click revenue (local)

Double

Cost per click in local currency

W

Click revenue (USD)

Double

Cost per click in USD currency

When reading over the report, there are a few things to note. Those are listed below in a table for easy reference:

Question

Answer

How do I differentiate my AdSets from one another?

If you have multiple AdSets under a given advertiser, they will be identified uniquely in the reports by the AdSet ID field. You can also reference the AdSet field.

Why does the referrer field contain "null" or "unknown"?

Due to legal and technical limitations, we might not receive the exact publishers' domain information (also known as blind traffic). These instances are tracked as “null” under the “referrer” field in the Log-level reports. This is a general behavior in the industry and it is common to have around 10% of traffic that falls under this definition.

Why am I seeing a lot of itunes.apple.com and play.google.com?

Our inApp displays will report as itunes.apple.com or play.google.com depending on the operating system the user has.

itunes.apple.com = iOS

play.google.com = Android

Why am I seeing users from different countries included in these reports?

User targeting is derived from continental data base location. Every AdSet has an account ID that is linked to a specific data base. Unless there is a country-specific geofilter applied on the AdSet, it technically can target any user in that geographical region.

For example, an AdSet linked to one of our Americas data centers could target a user in any North or South American country unless it has a country-specific geofilter applied.

Why am I seeing values of 0 in the category\_ID field? And "unknown" in the category\_name field?

If your Criteo product catalog does not have category IDs mapped to specific product IDs, this will display a value of 0. Likewise, this is why "unknown" appears in the category\_name field.

“Why do I sometimes see revenue related to clicks, and other times related to display?

If the AdSet is using an adaptive optimizer or a target budget mechanism, it will show a click revenue of 0 because we are billing displays, not clicks. If you’re using a standard click-billed AdSet, you will see a click cost unless smoothing is activated.

*** ## Example of Parsing The CSV file is produced with no quotes, Newline as a line terminator, backslash as an escape character, and comma as a separator. Please see below an example of parsing. ```python theme={null} import csv csv.register_dialect('crto', delimiter=',' ,quoting=csv.QUOTE_NONE,escapechar='\\',lineterminator = '\n') with open('test_om.csv', newline='') as csvfile: spamreader = csv.reader(csvfile, dialect='crto') for row in spamreader: print('rowcount ', len(row)) print(', '.join(row)) ``` If you notice any issues don't hesitate to reach out through the Discussion section or your dedicated account representative. ## What's next * [Placement](/marketing-solutions/docs/placement) * [Placement Category](/marketing-solutions/docs/placement-category) # Managing Budgets Source: https://developers.criteo.com/marketing-solutions/docs/managing-budgets ## Overview Budget objects are the primary control surface for Single-Seller campaigns. A budget: * Creates the underlying Single-Seller campaign if one does not yet exist for a `(sellerId, templateCampaignId)` pair. * Defines **how much** and **when** that campaign is allowed to spend. * Controls pause / resume state via an `isSuspended` flag. ## Budget behavior Each budget is a **capped total amount over a date range**: * No **daily** or **uncapped** budget types in Single-Seller mode. Daily pacing is **automatic**: * The system computes an average daily amount from the total budget and dates. * Under-delivery or over-delivery on a given day can be compensated later, as long as the budget period is active. For a given `(sellerId, templateCampaignId)`: * Budget periods **must not overlap**. * You can schedule **future budgets** as long as their periods do not overlap existing active budgets. * **Suspended budgets** do not block future budgets for the same period (they are treated as logically canceled). ## Typical budget fields

Field

Required

Description

sellerId

Yes

Marketplace seller identifier for which the budget applies

campaignIds

Yes

List containing the Single-Seller template campaign ID (length = 1)

amount

Yes

Total amount for the budget period (monetary value in your currency)

startDate

Yes

Date when the budget becomes active

endDate

Yes

Date when the budget stops allowing spend

budgetType

Yes

Must be "Capped" for Single-Seller

isSuspended

Optional

true \= paused; false \= active

id

Response

Unique budget identifier ( budgetId ) returned by the AP

*** ## Workflow: Create the first budget (and campaign) This is the flow to onboard a seller onto a Single-Seller template for the first time. ### Preconditions You have: * `advertiserId` * `templateCampaignId` (Single-Seller template campaign ID, provided by Criteo) * `sellerId` * Your account is enabled for Single-Seller. * You know the **minimum allowed budget per seller** for this template. ### Step 1 – Construct the budget payload Endpoint: ```http theme={null} POST https://api.criteo.com/2026-01/marketing-solutions/marketplace-performance-outcomes/budgets Content-Type: application/json ``` Sample request: ```json JSON theme={null} [ { "campaignIds": ["456"], "sellerId": "123", "startDate": "2026-04-16", "endDate": "2026-04-30", "budgetType": "Capped", "amount": "1200" } ] ``` **Key points:** * `campaignIds` contains exactly one ID: the Single-Seller template campaign ID. * `amount` must be ≥ the minimum per-seller budget communicated by Criteo, multiplied by the number of days between `startDate` and `endDate`. * `startDate` / `endDate` must describe a valid period (`startDate ≤ endDate`). ### Step 2 – Interpret the response A successful response will return: * The new budget ID (`budgetId`). * Echoed fields with normalized formats (for example: truncated seconds, normalized dates). * An `isSuspended` value and possibly other status information. From the moment this first valid budget is accepted for a `(sellerId, templateCampaignId)` pair: * Criteo creates the corresponding Single-Seller campaign synchronously. * You should plan for a short asynchronous provisioning delay before impressions begin. ### Step 3 – Avoid overlapping budgets When planning future periods: * Do **not** create budgets whose date ranges overlap for the same `(sellerId, templateCampaignId)`. If you need to extend or change a period: * Update the existing budget when possible (see next workflow), or * Suspend it and create a new, **non-overlapping** budget. ## Workflow: Update an existing budget Use budget updates to adjust **amount**, **dates**, or **suspension status**. ### Preconditions You have: * The `budgetId` (from creation or a previous GET). * A budget still within a modifiable state (see reference docs for immutable fields or cutoffs). ### Example: Increase budget amount mid-flight Endpoint: ```http theme={null} PATCH https://api.criteo.com/2026-01/marketing-solutions/marketplace-performance-outcomes/budgets Content-Type: application/json ``` Request body: ```json JSON theme={null} { "budgetId": "789", "amount": "2000" } ``` **Behavior:** * The total budget is increased (for example, `1200 → 2000`) for the overall period. * The pacing logic recomputes daily caps for the remaining days of the budget period. * The update is **idempotent**: sending the same PATCH twice with the same values results in the same final state. ### Example: Extend the end date Request body: ```json JSON theme={null} { "budgetId": "789", "endDate": "2026-05-31" } ``` **Guidance:** * Ensure the extended period still does **not overlap** with any other active budgets for the same `(sellerId, templateCampaignId)`. * If the system enforces max duration or future-horizon limits, violations will be returned as 4xx errors with field-specific messages. ## Retrieving and inspecting budgets ### List or filter budgets ```http theme={null} GET /marketplace-performance-outcomes/budgets ``` Supported query parameters include: * `sellerId` * `campaignId` (template campaign ID) * Date filters (see API reference for exact names) ### Retrieve one budget by ID ```http theme={null} GET /marketplace-performance-outcomes/budgets/{budgetId} ``` Use these endpoints to: * Synchronize your internal state with the server. * Debug issues (for example: confirm whether a budget is suspended, verify effective dates and amounts). ## Workflow: Adjust spend mid-flight (putting it together) 1. **Retrieve the current budget:** ```http theme={null} GET /marketplace-performance-outcomes/budgets?sellerId=...&campaignId=templateCampaignId ``` 2. **Decide on the new amount or dates**, incorporating minimum/maximum constraints and your own business logic. 3. **PATCH the budget** with the updated fields. 4. **Confirm the updated state** by: * Re-fetching the budget, and/or * Checking campaign performance via stats endpoints. ## Workflow: Pause and resume a seller (putting it together) * **Pause a seller:** ```http theme={null} PATCH /marketplace-performance-outcomes/budgets ``` * **Resume a seller:** ```http theme={null} PATCH /marketplace-performance-outcomes/budgets ``` with: ```json JSON theme={null} { "budgetId": "789", "isSuspended": false } ``` (This only resumes delivery if `endDate` is still in the future.) * **Cancel scheduled future budgets:** * Set `isSuspended: true` on the future budget and treat it as canceled. * Create a new budget for the desired future period if you need to replace it. # Managing Campaigns Source: https://developers.criteo.com/marketing-solutions/docs/managing-campaigns ## Overview In Single-Seller setups, you do not create seller-campaigns directly. Instead, the underlying per-seller campaign is created implicitly by Criteo when you create the first valid budget for a `(sellerId, templateCampaignId)` pair. Once created, you can configure and control the campaign through two main surfaces: * **Budget suspension** (to pause/resume the campaign). * **productSet configuration** (to restrict which products can be advertised). ## The Single-Seller campaign entity A **Single-Seller campaign** (identified by `sellerCampaignId`) is the per-seller campaign derived from the template. Key characteristics: * Created implicitly when the first valid budget for a `(sellerId, templateCampaignId)` pair is accepted. * There may be a short asynchronous provisioning delay before delivery begins after creation. * Used by MPO stats endpoints when querying performance at the seller-campaign level. * Can have **at most one** `productSet` attached at any given time. To retrieve seller-campaigns and inspect their current state: ```http theme={null} GET /marketplace-performance-outcomes/seller-campaigns ``` ### Suspension reasons When a Single-Seller campaign is not delivering, the API returns a `suspensionReasons` array explaining why.

Reason

Description

Action required

ManuallyStopped

Campaign manually paused

Resume via budget

NoBudgetDefined

No valid budget linked

Create a budget

NoCpcDefined

No CPC set

Set CPC via API

NoMoreBudget

Budget fully spent

Create a new budget

RemovedFromCatalog

Products removed

Restore products

NotYetStarted

Newly created

Wait

NoMoreDailyBudget

Daily limit reached

Wait for daily reset

Other

Internal/system issue

Contact your Criteo team

#### Checking campaign status ```json JSON theme={null} { "id": "SELLER_123.TEMPLATE_CAMPAIGN_456", "sellerId": "SELLER_123", "campaignId": "TEMPLATE_CAMPAIGN_456", "suspendedSince": "2026-04-28T10:00:00Z", "suspensionReasons": ["NoMoreDailyBudget"] } ```
* If `suspendedSince` is `null` and `suspensionReasons` is empty → the campaign is active. * If `suspendedSince` is set and one or more reasons are present → the campaign is currently suspended. ## Suspending and resuming a Single-Seller campaign You do **not** pause Single-Seller campaigns directly via a campaign-level endpoint. Instead, you control campaign run state by suspending or resuming the associated **budget**. ### Suspend (pause) a campaign To stop spend for a seller, set `isSuspended: true` on the active budget: ```http POST theme={null} POST https://api.criteo.com/2026-01/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Content-Type: application/json ``` ```json JSON theme={null} { "budgetId": "789", "isSuspended": true } ``` **Expected behavior:** * The budget becomes inactive and the associated Single-Seller campaign stops serving. * The budget remains present in the API for auditing and historical purposes. ### Resume a campaign To resume spend, set `isSuspended: false`: ```http POST theme={null} POST https://api.criteo.com/2026-01/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Content-Type: application/json ``` ```json JSON theme={null} json { "budgetId": "789", "isSuspended": false } ``` **Guidance:** * If the `endDate` is in the past, resuming will **not** restart delivery; you may need to create a new budget with a future period. * If there is a future budget scheduled for the same `(sellerId, templateCampaignId)`, the campaign will automatically resume when that future budget’s `startDate` is reached (assuming that future budget is not itself suspended). ### Cancel a scheduled future budget To logically cancel a future, not-yet-active budget: ```http POST theme={null} POST https://api.criteo.com/2026-01/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Content-Type: application/json ``` ```json JSON theme={null} { "budgetId": "FUTURE_BUDGET_1011", "isSuspended": true } ``` After suspension: * Treat the budget as **canceled**. * You can create a new budget covering the same period if needed; suspended budgets do **not** block new ones for the same dates. ## productSet for Single-Seller campaigns The `productSet` feature lets you restrict a Single-Seller campaign to a specific list of product IDs from the seller’s catalog. ### Overview A `productSet` is a **whitelist of product IDs**: * Only products whose external item IDs are in the `productSet` are eligible to be advertised by that Single-Seller campaign. The `productSet`: * Is configured at the **seller-campaign** level. * Applies to **all ads** served by that campaign. * Is **optional**; if no `productSet` is configured, the campaign can use all eligible products from the seller’s catalog (subject to other targeting and policy constraints). * There is at most **one** `productSet` per Single-Seller campaign at any given time. > `productSet` configuration is only supported for Single-Seller campaigns associated with a Single-Seller template. Do not attempt to use `productSet` on legacy multi-seller campaigns or other campaign types. ## Inspecting the current productSet When you retrieve a Single-Seller campaign, the response will: * Return no `productSet` or `productSet: null` if no `productSet` has ever been configured. * Return a structured rule when a `productSet` is configured. **Example response fragment:** ```json JSON theme={null} { "data": [ { "id": "SELLER_123.TEMPLATE_CAMPAIGN_456", "sellerId": "SELLER_123", "campaignId": "TEMPLATE_CAMPAIGN_456", "productSet": { "rules": [ { "operator": "IsIn", "field": "ExternalItemId", "values": [ "SKU_1", "SKU_2", "SKU_3" ] } ], "productSetStatus": "Valid", "productSetNumberOfProducts": 3 } } ] } ``` **Interpretation:** * `productSet.rules` contains an array of rules; in Single-Seller mode, only a **single rule** is supported. * Each rule: * `operator: "IsIn"` — inclusion list. * `field: "ExternalItemId"` — field in the seller’s catalog feed. * `values` — list of product IDs (strings). * If `productSet` is `null` or omitted, no additional product-ID filter is applied. ## Create / Update: Attaching a productSet To create or update the `productSet` for a Single-Seller campaign, call the seller-campaign update endpoint with a `productSet` object. ```http theme={null} PATCH https://api.criteo.com/2026-01/marketing-solutions/marketplace-performance-outcomes/seller-campaigns Content-Type: application/json ``` **Example request body:** ```json JSON theme={null} [ { "id": "SELLER_123.TEMPLATE_CAMPAIGN_456", "productSet": { "value": [ { "operator": "IsIn", "field": "ExternalItemId", "values": [ "SKU_001", "SKU_002", "SKU_003", "SKU_004", "SKU_005", "SKU_006", "SKU_007", "SKU_008", "SKU_009", "SKU_010", "SKU_011" ] } ] } } ] ``` **Behavior:** * If the Single-Seller campaign had no `productSet` before, this **creates and attaches** a new `productSet`. * If a `productSet` already existed, this **replaces** the existing rule with the new one (it is not additive). * After a successful update, subsequent GETs for this campaign will return the new `productSet` configuration. **Constraints:** * Only: * `operator = "IsIn"` or `operator = "IsNotIn"`, with * `field = "ExternalItemId"`\ is supported for Single-Seller usage. * A **minimum number of product IDs per `productSet`** may be enforced per advertiser (default: 20). Providing fewer IDs than configured will return a **4xx** error. ## Delete / Unset: Removing the productSet To remove the `productSet` and revert to no additional product filter, set `productSet.value` to `null`: ```json JSON theme={null} [ { "id": "SELLER_123.TEMPLATE_CAMPAIGN_456", "productSet": { "value": null } } ] ``` **Expected behavior:** * The Single-Seller campaign stops using a `productSet` to filter products. * A subsequent GET for this campaign will show `productSet: null` (or omit the field, depending on the schema). * Products are once again selected from the seller’s catalog without additional ID whitelisting, subject to other targeting rules and policies. ## Supported productSet patterns

Pattern

Supported?

Notes

Single-Seller + no productSet (default)

Yes

All eligible products from the seller are used.

Single-Seller + one IsIn rule on ExternalItemId

Yes

Recommended pattern for SKU restriction.

Multiple productSet rules per Single-Seller

No

Updates replace the existing rule.

productSet on a multi-seller campaign

No

*** ## Workflow: Restrict products for a seller 1. **Obtain product IDs** from your catalog or internal systems for the seller. 2. **Attach `productSet`** via: ```http theme={null} PATCH /marketplace-performance-outcomes/seller-campaigns ``` with: * `operator: "IsIn"` * `field: "ExternalItemId"` * `values: ["SKU_1", "SKU_2", ...]` 3. **Update or remove later as needed:** * Update the `values` list to change the whitelist. * Set `productSet.value` to `null` to remove the filter entirely. # Managing Sellers Source: https://developers.criteo.com/marketing-solutions/docs/managing-sellers ### Overview In Single-Seller setups, sellers are **not created or managed through MPO**. They exist in your marketplace catalog and are discoverable through the **same MPO Sellers endpoints** used for multi-seller campaigns. This article covers how to find sellers and use their identifiers in Single-Seller workflows. ### The Seller entity Each seller in your marketplace is represented by a **`sellerId`** — a unique identifier used across MPO endpoints to associate **budgets**, **campaigns**, and **statistics** with a specific seller. * Sellers are sourced from your **catalog**, not created via MPO. * The same `sellerId` values used in **multi-seller** campaigns apply in **Single-Seller** setups. ### Discovering sellers Use the MPO Sellers endpoint to look up `sellerId` values: ```http HTTP theme={null} GET /marketplace-performance-outcomes/sellers ``` **Example — filter by seller name:** ```http theme={null} http GET /marketplace-performance-outcomes/sellers?sellerName=YourSellerName ``` Use the returned `sellerId` values when: * Creating or updating budgets: * `POST /marketplace-performance-outcomes/budgets` * `PATCH /marketplace-performance-outcomes/budgets` * Filtering statistics by seller. * Configuring `productSet`s on seller-campaigns. ### Syncing your seller list For automated integrations, fetch and store seller IDs as part of your onboarding flow for each new seller: 1. Call `GET /marketplace-performance-outcomes/sellers` to obtain `sellerId` values. 2. Store them in your system alongside the corresponding `templateCampaignId`. 3. Use the **(`sellerId`, `templateCampaignId`) pair** as the key for all subsequent **budget** and **campaign** operations. # Marketplace Performance Outcomes Source: https://developers.criteo.com/marketing-solutions/docs/marketplace-performance-outcomes ## What MPO is **Marketplace Performance Outcomes (MPO)** is designed for marketplaces that want to activate and scale **offsite advertising for sellers** through a structured, API-driven workflow. At a high level, MPO gives marketplaces a way to: * Onboard sellers. * Control campaign delivery. * Allocate and manage budgets. * Monitor performance across sellers and campaigns. MPO supports two main activation models: * **Multi-seller** – multiple sellers share the same campaign. * **Single-seller** – each seller gets a **dedicated ad set/campaign** based on a marketplace-defined template. These two models are **complementary**, not mutually exclusive: * **Multi-seller**: pooled activation at scale, especially for long-tail or smaller-budget sellers. * **Single-seller**: dedicated setup for sellers that need **greater transparency or control**. *** ## What makes MPO different MPO is designed to optimize advertising performance at the **seller level**. Unlike traditional DSP setups, where optimization is typically applied **at campaign level across multiple advertisers**, MPO uses the **seller** as the primary unit of configuration and optimization. In practice: * Each **seller’s budget** is managed **independently**. * Budget is spent toward **that seller’s configured objective**. * Performance is tracked at **seller** and **seller-campaign** level. This model allows marketplaces to manage many sellers within a shared framework while maintaining **per-seller control and visibility**. ## Why MPO MPO can be used to: * Integrate **seller advertising into marketplace workflows**. * Manage **campaigns, budgets, and sellers programmatically**. * Access **performance data** across sellers and campaigns. In short, MPO is designed to support **scalable, API-driven seller advertising** within marketplace environments. ## How MPO works A typical MPO integration follows this flow: 1. **Identify the advertiser** (your marketplace context). 2. **Create and manage sellers** (via catalog + MPO Sellers endpoints). 3. **Configure seller campaign delivery** (ad sets and templates). 4. **Set and manage budgets** per seller. 5. **Retrieve performance statistics** to optimize and monitor. Targeting and delivery controls are defined at the **ad set / campaign level**, which determines how campaigns are executed. This structure allows marketplaces to integrate MPO into existing systems while keeping **seller activation and campaign management fully programmatic**. ## Singleseller and multiseller in MPO MPO supports two complementary activation models: ### Multiseller * Multiple sellers share one campaign or ad set. * Simplified structure for **onboarding many sellers quickly**. * Commonly used for **smaller seller budgets**. ### Singleseller * **One seller per ad set/campaign**, based on a **shared template**. * **Dedicated budget per seller**. * More **granular configuration and reporting**. ### SingleSeller vs MultiSeller MPO campaigns “Single-Seller” campaigns build on top of the **multi-seller** model where multiple sellers share a single campaign. **When to use each** Use **Single-Seller** when: * Per-seller budget control is required. * Granular per-seller performance tracking and troubleshooting are needed. * Specific sellers need dedicated configuration or reporting. Use **Multi-seller** when: * Onboarding many sellers quickly is a priority. * Seller budgets are small or highly variable. * A pooled setup is sufficient for business goals. *For more detail, see the public guide:*\ *[MPO Single Seller Campaigns](/marketing-solutions/docs/single-seller-campaigns).* *** ## What You Can Do With the MPO API The MPO API includes endpoints for: * **Advertisers** * **Sellers** * **Seller campaigns** * **Budgets** * **Statistics** These APIs allow marketplaces to: * Automate **seller advertising workflows**. * Integrate MPO deeply into **internal systems** (e.g., marketplace UI, data warehouse, reporting). * Build custom orchestration, monitoring, and optimization logic on top of Criteo delivery. *** ## Optimization Strategies MPO supports multiple optimization strategies, allowing marketplaces to align campaign delivery with different seller goals. Campaigns can be configured to optimize for: * **Sales / revenue** * **Conversions** * **Leads** * **Traffic / landing visits** * **Click volume** These strategies can be selected depending on: * The seller’s **objective** (performance vs scale). * The seller’s **stage in the funnel** (prospecting vs retargeting vs always-on). *** ## How to Use this Documentation Use this page as the **entry point** to MPO. Then continue with the documentation that matches your integration and use case: * **Single-seller documentation**: * Concepts and entities for Single-Seller. * Single-Seller Quick Start (create first budget and campaign). * Managing Single-Seller budgets and `productSet`s. * Single-Seller troubleshooting and FAQs. * **Multi-seller documentation**: * Concepts and entities for multi-seller setups. * Multi-seller onboarding and campaign management flows. * Budgeting and optimization best practices. * **Statistics**: * Available stats endpoints (`/stats/campaigns`, `/stats/sellers`, `/stats/seller-campaigns`). * How to choose identifiers (`campaignId`, `sellerId`, `sellerCampaignId`) for different reporting needs. * Patterns for monitoring performance and building dashboards. ### Multiseller Guides Explore the endpoints for seller management via API. Explore the endpoints allowing to manage campaigns. Explore the programmatic ways to manage budgets. Learn more about MPO Multiseller statistics. ### Singleseller Guides Start by exploring the campaign-related concepts. Learn how to quick start by launching a Single-Seller Campaign via MPO. Explore the endpoints for seller management via API. Explore the endpoints allowing to manage campaigns. Explore the programmatic ways to manage budgets. Learn more about MPO Singleseller statistics. # Best Practices for MPO API Integration Source: https://developers.criteo.com/marketing-solutions/docs/mpo-api-integration-best-practices Recommended patterns and key considerations for integrating with the Marketplace Performance Outcomes (MPO) API, covering activation model, entity mapping, budgets, bids, error handling, reporting, and seller lifecycle. This article outlines the recommended patterns and key considerations for integrating with the Marketplace Performance Outcomes (MPO) API. Following these practices helps ensure a stable, scalable, and operationally efficient implementation. Successful MPO implementations begin with commercial and technical design before development starts. We recommend following this sequence: 1. Define how you sell MPO — bundled as part of a larger ad package, or as a standalone offsite product. 2. Complete the MPO Integration Design Template (PRD) with Criteo to validate your architecture, surface unsupported requirements early, and align on best practices. 3. Begin API implementation once your selling model and architecture are agreed. Completing the PRD before implementation reduces rework during development. ## Before you start: decide how you'll sell MPO Before writing a single API call, define which MPO activation model you are implementing: * **Bundle Extension** — offsite advertising is sold as part of a larger ad package (for example, bundled with an onsite ad platform, or combined with other offsite products). This model is recommended when you already operate an onsite advertising platform or a broader media offering. * **Standalone Offsite** — offsite advertising is offered as a separate product or campaign, independent from onsite. The activation model determines how you design your entity mapping, budget structure, and reporting setup. Choosing the wrong model or starting implementation before aligning with Criteo is the most common cause of rework. The table below shows how each model shapes key implementation decisions: | Implementation area | Bundle Extension | Standalone Offsite | | ------------------- | ---------------------------------------------------------- | ------------------------------------------------------ | | Entity mapping | Seller maps to an existing onsite campaign or product | Seller maps to a dedicated offsite product or campaign | | Budget structure | Shared budgets across seller-campaigns are common | Individual budgets per seller-campaign are typical | | Reporting | Aggregated view alongside onsite metrics is often required | Separate offsite reporting unit required | | Activation | Offsite activated as an add-on to an existing product | Offsite onboarded independently, no onsite dependency | Do not start implementation without first aligning your chosen model with Criteo. ## Entity mapping Map your internal structure to MPO entities before implementing any workflow: | Your internal concept | MPO entity | | --------------------- | --------------- | | Advertiser | account | | Marketplace seller | Seller | | Per-seller campaign | Seller-Campaign | | Advertising budget | Budget | | Product inventory | Catalog | Getting this mapping wrong is the most common source of post-launch issues. Confirm with Criteo that your mapping is correct before proceeding. ## Seller ingestion Sellers in MPO are not created via API in the standard flow. They are automatically extracted from your product catalog. * Each product in your catalog must include the `SellerId` field (the raw seller identifier from your system) and `SellerName` (the display name). * A Seller-Campaign is automatically created for every seller × campaign pair after ingestion. * Ingestion runs hourly, but the end-to-end process takes 24–48 hours from the time you upload your catalog. **Best practice:** Do not attempt to activate seller-campaigns immediately after catalog upload. Instead, poll `GET /marketplace-performance-outcomes/sellers` and match returned records using `sellerName` — this corresponds to the seller identifier you sent through the catalog. Once matched, use the `id` field returned by Criteo as the stable seller ID for all subsequent API calls. ## Budget management ### Choose the right budget type | Budget type | Use when | | ----------- | ----------------------------------------------------------------------------------------------- | | Capped | You want a fixed total spend limit over a date range | | Uncapped | You want unlimited spend with no total cap | | Daily | You want to limit daily spend — requires an active Capped or Uncapped budget to also be present | ### Shared vs. individual budgets A budget can be shared across multiple Seller-Campaigns belonging to the same seller. Use shared budgets when: * The seller operates across multiple campaigns (for example, web and app). * You want unified budget control across those campaigns. Use individual budgets when you need per-campaign spend accountability. Shared budgets are only available in the Multi-Seller model. They are not supported in Single-Seller Campaigns. ### Budget refresh and timezone By default, all dates and times in the MPO API are in UTC. Local timezone configuration is supported but must be set up by Criteo. Budget refresh timing is based on the configured timezone. If your operations require a local timezone, contact your Criteo point of contact to request this configuration. ### Overspend protection If you implement a daily spend hard limit, you are responsible for monitoring spend via the statistics endpoints and suspending budgets or setting CPC to 0 when the threshold is reached. MPO does not enforce client-defined hard limits automatically. Recommended approach for hard limit enforcement: 1. Poll `GET /stats/seller-campaigns` at a defined cadence (for example, every 15–30 minutes). 2. Compare cost against your threshold. 3. If exceeded, call `PATCH /budgets/{budgetId}` with `isSuspended: true` or `PATCH /seller-campaigns/{sellerCampaignId}` with `bid: 0`. Unlike onsite advertising, where spend is tightly controlled by auction mechanics, offsite campaigns can overdeliver against a set budget within a given time window. This is because ad serving and billing events are not always processed in real time, meaning a campaign can continue to serve briefly after a budget threshold is reached. The MPO budget amount sets a ceiling on what will be billed to the client: actual billed spend will not exceed the configured budget amount. However, actual delivery may briefly exceed it before the system catches up. To monitor budget consumption, use the budget endpoint, not the statistics endpoints: * `GET /budgets/{budgetId}` returns the `spend` field for the given budget. * If you need to check actual delivery spend at seller-campaign level, use the statistics endpoints (`GET /stats/seller-campaigns`). These two figures may differ and that is expected. To enforce a hard limit, suspend the budget when your threshold is reached: * `PATCH /budgets/{budgetId}` with `isSuspended: true` ## Bid management Bids are set at the Seller-Campaign level. Key principles: * Setting a bid to 0 effectively pauses the Seller-Campaign without suspending the budget. * If the Seller-Campaign uses a shared budget, set bid to 0 to pause without affecting other Seller-Campaigns sharing that budget. * If the Seller-Campaign uses an individual budget, suspending the budget directly is the cleaner approach. **Dynamic bid adjustment pattern:** * If spend is running too fast → decrease the bid via `PATCH /seller-campaigns/{sellerCampaignId}`. * If spend is running too slow → increase the bid via the same endpoint. ## Error handling and resilience * Implement exponential back-off for HTTP 500 and 503 responses. These are typically transient network errors. * The API supports up to 2,000 budgets per call (0.5 MB payload limit). * Partial failure is not supported in bulk operations. If a call fails, check the `errors` array in the response for per-record issue detail. * Use circuit breakers on write operations (budget creation, budget update, seller-campaign update) to protect your system from burst failures. ## Reporting and statistics Three statistics endpoints are available: | Endpoint | Granularity | | ----------------------------- | ---------------------------------------------- | | `GET /stats/sellers` | Per seller, per time interval | | `GET /stats/campaigns` | Per campaign, per time interval | | `GET /stats/seller-campaigns` | Per (seller, campaign) pair, per time interval | Key reporting considerations: * Statistics are returned in UTC. Apply timezone conversion on your side if needed. * Use `clickAttributionPolicy` (`SameSeller`, `AnySeller`, or `Both`) to control how post-click conversions are attributed at the seller level. * The default attribution window is PC30 (30-day post-click). Specify a different window explicitly if your reporting standard differs. * Attribution-insensitive metrics (impressions, clicks, CTR, cost) are stable regardless of attribution settings. Attribution-sensitive metrics (`saleUnits`, `revenue`, CR, CPO, COS, ROAS) change depending on the attribution window and policy used. ## Seller lifecycle operations ### Pausing a seller * If using an individual budget: `PATCH /budgets/{budgetId}` with `isSuspended: true`. * If using a shared budget: `PATCH /seller-campaigns/{sellerCampaignId}` with `bid: 0`. ### Offboarding a seller 1. Suspend all active budgets associated with the seller. 2. If the seller is not expected to relaunch soon, remove their products from the catalog. 3. Seller-Campaign budgets are archived after 6 months. ### Re-onboarding a seller 1. Ensure the seller's products are present in the catalog with the correct `externalSellerId`. 2. Wait for the ingestion job to process (24–48 hours). 3. Verify seller availability via `GET /sellers/{sellerId}`. 4. Reactivate the budget or create a new one, then reset the bid. ## Common mistakes to avoid | Mistake | Impact | Correct approach | | ----------------------------------------------------------------- | -------------------------- | -------------------------------------------------- | | Assuming sellers appear immediately after catalog upload | API returns no seller data | Wait 24–48 hours and poll `GET /sellers` | | Setting budget before bid | `NoCpcDefined` suspension | Always set bid first, then budget | | Treating `sellerName` as the stable seller identifier | `sellerName` is deprecated | Use `sellerId` (numeric hashed value) | | Assuming all suspension reasons are surfaced in every environment | Missing suspension data | Check config-as-code flag availability with Criteo | | Building product-level reporting into MVP | Delivery delays | Separate product-level reporting to a future phase | # MPO Attribution Source: https://developers.criteo.com/marketing-solutions/docs/mpo-attribution How MPO attributes post-click outcomes in reporting, which metrics are affected, supported attribution windows, and same-seller vs. any-seller logic. Attribution in Marketplace Performance Outcomes (MPO) determines which post-click outcomes are credited to MPO delivery in reporting. Because MPO operates in a marketplace context, attribution can also depend on whether the purchased product belongs to the same seller that received the click. ## What this page covers * How MPO attributes post-click outcomes in reporting * Which metrics change when attribution settings change * The supported attribution windows * Same-seller vs. any-seller attribution behavior *** ## Default attribution behavior If no attribution window is specified in MPO reporting, the default is **PC30**: a 30-day post-click attribution window. A conversion can be attributed to an MPO click if it occurs within 30 days after that click. *** ## Post-click vs. last-click attribution These are two distinct models: **Post-click (PC)** — a conversion is attributed to MPO as long as the user clicked any MPO ad and the purchase happened within the attribution window. It does not matter how many other ads the user clicked in between. **Last-click** — a conversion is attributed to MPO only if an MPO ad was the very last ad clicked before the purchase. Any subsequent click on a non-MPO ad removes the attribution. MPO uses post-click attribution by default. Last-click logic appears in MPO specifically as a fallback for cross-seller attribution at the seller level: when no same-seller product click can be found for a purchased product, the sale is attributed to the last click event at campaign level. *** ## Attribution-sensitive vs. attribution-insensitive metrics Not every MPO metric is affected by attribution settings. **Attribution-insensitive** — these metrics describe delivery activity and do not change when attribution settings change: * `displays` * `impressions` * `clicks` * `CTR` * `cost` **Attribution-sensitive** — these metrics depend on attribution settings and can change based on the attribution window and click attribution policy: * `saleUnits` * `revenue` * `cr` * `cpo` * `cos` * `roas` Two reporting requests can return identical delivery metrics but different sales and efficiency metrics if they use different attribution settings. *** ## Attribution windows | Window | Description | | --------- | ----------------------------------- | | `PC1` | 1-day post-click | | `PC7` | 7-day post-click | | `PC30` | 30-day post-click *(default)* | | `PC1PV1` | 1-day post-click + 1-day post-view | | `PC1PV7` | 1-day post-click + 7-day post-view | | `PC7PV1` | 7-day post-click + 1-day post-view | | `PC7PV7` | 7-day post-click + 7-day post-view | | `PC30PV1` | 30-day post-click + 1-day post-view | | `PC30PV7` | 30-day post-click + 7-day post-view | Use shorter windows for more conservative, recent attribution. Use longer windows for a broader view of performance over time. *** ## Same-seller vs. any-seller attribution In MPO, attribution can be evaluated at seller level using the `clickAttributionPolicy` parameter. ### `SameSeller` A conversion is attributed only when the click and the purchased product belong to the same seller. Use this for the strictest seller-level attribution logic. **Example:** user clicks Seller A → buys from Seller A → attributed. ### `AnySeller` A conversion can be attributed even if the purchased product belongs to a different seller from the one that received the click. Use this for a broader marketplace view of post-click performance. **Example:** user clicks Seller A → buys from Seller B → attributed. ### `Both` Returns both same-seller and any-seller interpretations in a single request, so you can compare them directly. *** ## Examples | Scenario | SameSeller | AnySeller | | ---------------------------------------------- | -------------- | -------------- | | Click Seller A → buy Seller A (within window) | Attributed | Attributed | | Click Seller A → buy Seller B (within window) | Not attributed | Attributed | | Click Seller A → buy Seller A (outside window) | Not attributed | Not attributed | *** ## Choosing the right settings | Goal | Recommended setting | | ---------------------------- | ----------------------------- | | Standard MPO reporting view | Default `PC30` | | Recent, stricter attribution | Shorter window (`PC7`, `PC1`) | | Seller-level accountability | `SameSeller` | | Broader marketplace impact | `AnySeller` | | Compare strict vs. broad | `Both` | # Latency in MPO Source: https://developers.criteo.com/marketing-solutions/docs/mpo-latency What latency means in MPO, why it exists, and what delays to expect across catalog ingestion, delivery, and reporting workflows. MPO combines catalog processing, campaign configuration, delivery systems, and reporting pipelines — and those systems do not all update at the same speed. This page explains what latency means in MPO, why it exists, what delays to expect across common workflows, and how to interpret those delays when integrating with the API. ## What this page covers * Why MPO changes are not always visible immediately * Which MPO surfaces are near-real-time vs. delayed * Expected delays for catalog ingestion, seller availability, delivery changes, and reporting * How to troubleshoot cases where data or changes do not appear yet *** ## What latency means in MPO In MPO, latency is the delay between an input or change and the moment that change becomes visible in the relevant system. Examples: * Updating a product catalog and waiting for sellers to appear in the Sellers API * Creating or updating a budget and waiting for delivery state to reflect the change * Generating impressions or clicks and waiting for those events to appear in reporting * Checking real-time monitoring vs. checking standard reporting Latency does not necessarily mean something is broken. In many cases it reflects asynchronous processing between ingestion, delivery, and reporting systems. *** ## Why latency exists MPO is not a single synchronous system. Different parts of the workflow are processed by different services and pipelines. Latency can come from: * Processing large volumes of data (e.g. catalog ingestion) * Scheduled or batch processing jobs (catalog imports, reporting aggregation, synchronization workflows) * Asynchronous provisioning of sellers and seller-campaigns * Budget, pacing, and delivery state propagation across downstream systems * Third-party reporting delays (e.g. when SSPs or external trackers notify Criteo later than expected) * Timezone and reporting window processing * Temporary backend load or processing delays *** ## Typical latency by component The timings below are operational guidance, not formal SLAs. Exact delays can vary by workflow, system load, import cadence, and partner-side behavior. ### Catalog ingestion and seller availability MPO sellers are inferred from the product catalog rather than created manually through MPO onboarding flows. After the catalog is processed correctly and the relevant MPO setup is in place, sellers become available through the MPO Sellers endpoints only after the relevant import and downstream processing cycle completes. This means: * Catalog updates are not reflected instantly in seller availability * New sellers may not appear immediately after a feed update * Onboarding and validation flows should allow for asynchronous processing time If sellers do not appear immediately after a valid catalog update, wait for the ingestion window before treating it as a failure. ### Standard reporting Standard reporting is designed for aggregated performance analysis, not immediate operational monitoring. Reporting data may take several hours to appear depending on the workflow and processing stage. Use standard reporting when you need: * Aggregated performance trends * Seller, campaign, or seller-campaign reporting over time * Stable reporting views for analysis and reconciliation Do not use standard reporting to validate a change made only a few minutes ago. ### Real-time reporting The [Real-Time Asynchronous API](/marketing-solutions/docs/getting-realtime-mpo-statistics) is the lower-latency monitoring surface in MPO. It is intended for operational visibility rather than long-term performance analysis. Even this surface has a processing delay and should not be treated as an instant reflection of delivery state. Use real-time reporting when you need: * Near-immediate delivery monitoring * Operational checks during campaign setup or budget changes * Fast feedback on whether delivery is active *** ## Practical guidance | Workflow | Expected behavior | | -------------------------------------- | --------------------------------------- | | Catalog update → seller appears in API | Not immediate; wait for ingestion cycle | | Budget update → delivery state change | Not immediate; propagation takes time | | Impression / click → standard report | Several hours delay by design | | Impression / click → real-time report | Lower latency, but not instant | When integrating with MPO, build your workflows assuming asynchronous state propagation and do not rely on immediate consistency between input actions and API responses. # MPO Standard Reporting API Source: https://developers.criteo.com/marketing-solutions/docs/mpo-standard-reporting-api ## Overview The MPO Standard Reporting API provides aggregated performance statistics for Marketplace Performance Outcomes (MPO) across both: * **Multi-Seller campaigns** * **Single-Seller campaigns** These endpoints are designed for historical and batched reporting (days, weeks, months).
They are typically used for: * Marketplace BI dashboards and data warehouses * Scheduled exports and reporting pipelines * Seller-facing performance reports For low-latency / near real-time monitoring, use the [**MPO Real-Time Asynchronous API**](/marketing-solutions/docs/getting-realtime-mpo-statistics) instead. *** ## When to Use Standard vs. Real-Time Stats Use the **Standard Reporting API** when you need: * Aggregated metrics over longer time ranges (for example, last 30 days, last quarter) * Stable, post-processed data suitable for billing, margin analysis, and long-term trends * Scheduled batch exports into your own reporting stack Use the [**Real-Time API**](/marketing-solutions/docs/getting-realtime-mpo-statistics) when you need: * Short-window metrics (for example, last minutes or hours) * Monitoring of launches, tests, or rapid changes (budgets, activation, CPC) * Near real-time dashboards or alerts *** ## Shared Concepts ### Supported Metrics All standard MPO stats endpoints expose the same core metrics: * `impressions` – Number of times products were shown in banners. * `clicks` – Number of clicks on products. * `cost` – Amount spent for those clicks. * `saleUnits` – Number of products sold attributed to those clicks. * `revenue` – Revenue generated by attributed sales. * `cr` – Conversion rate (`saleUnits / clicks`). * `cpo` – Cost per order (`cost / saleUnits`). * `cos` – Cost of sale (`cost / revenue`). * `roas` – Return on ad spend (`revenue / cost`). Exact metric definitions and attribution rules are identical for **Multi-Seller** and **Single-Seller**. What changes is which identifier (campaign, seller, seller-campaign) you aggregate by. *** *** ## Aggregation Interval You control the aggregation granularity with `intervalSize`, typically: * **Day** – one row per day * **Month** – one row per calendar month * **Year** – one row per calendar year * **Hour** – for shorter windows; may have stricter max range Exact allowed values and maximum date range depend on your environment; see the API reference for constraints. *** ## Common Filtering Parameters All three endpoints share a common set of filters. The most important are: ### Time range * `startDate` – include events from the start of this day (inclusive) * `endDate` – include events up to the end of this day (inclusive) ### Row limit * `count` – maximum number of rows to return ### Attribution * `clickAttributionPolicy` – `SameSeller`, `AnySeller`, or `Both` (where supported) ### Time zone * `timeZoneId` – IANA time zone code (for example, `Asia/Seoul`, `Asia/Tokyo`) used to determine day/hour bucket boundaries for aggregation. Optional; defaults to UTC-0 if not provided, preserving prior behavior for existing integrations. Each endpoint then adds its own identifier filters (for example, `campaignId`, `sellerId`). *** # Endpoints ## Seller Statistics **Purpose:** Performance aggregated per seller over time. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/sellers ``` ### Typical Use Cases * Per-seller reporting for marketplace account management * Identifying top or underperforming sellers * Feeding seller-facing dashboards ### Key Parameters * `advertiserId` (integer, optional)
Restrict metrics to a specific advertiser (your marketplace). * `sellerId` (string, optional)
Restrict to a single seller. If omitted, returns one row per seller per interval. * `startDate`, `endDate` (date, optional)
Filter events to a given date range. If omitted: * `endDate` defaults to today. * `startDate` defaults to `endDate` (one day). * `intervalSize` (enum, optional)
Aggregation granularity: `Day`, `Month`, `Year`, and in some environments `Hour`. * `count` (integer, optional)
Maximum number of rows to return (useful for pagination or sampling). * `clickAttributionPolicy` (enum, optional)
Attribution mode: `SameSeller`, `AnySeller`, or `Both` (where supported). * `timeZoneId` (string, optional)
IANA time zone code used for aggregation boundaries (for example, `Asia/Seoul`). Defaults to UTC-0 if omitted. ### Response Shape (Conceptual) The response uses a **"columns + data"** structure like so: ```json expandable theme={null} { "columns": [ "sellerId", "sellerName", "day", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [ "1200972", "sellerA", "2026-03-01", 14542, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0 ] ], "rows": 1 } ``` * The first columns identify the seller (`sellerId`, `sellerName`) and time bucket. * The remaining columns are the metrics. For **Single-Seller** and **Multi-Seller**, the schema is identical; what differs is how you populate `sellerId` and `sellerName`from your catalog and seller mapping. *** ## Campaign Statistics **Purpose:** Performance aggregated per campaign over time. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/campaigns ``` This endpoint works for: * Multi-Seller MPO campaigns * Template / Single-Seller campaigns where you want statistics at campaign ID level ### Key Parameters * `advertiserId` (integer, optional)
Restrict to a specific advertiser. * `campaignId` (string, optional)
Restrict to one campaign. If omitted, returns one row per campaign per interval. * `startDate`, `endDate`, `intervalSize`, `count`, `clickAttributionPolicy`
Same semantics as for seller stats. * `timeZoneId` (string, optional)
Same semantics as for Seller Statistics. ### Response Shape (Conceptual) ```json expandable theme={null} { "columns": [ "campaignId", "day", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [ "168423", "2026-03-01", 3969032, 13410, 1111.295, 985, 190758099, 0.073, 1.128, 0.0, 171653.88 ] ], "rows": 1 } ``` ### Typical Use Cases * Overall performance for a Multi-Seller or template campaign * High-level reporting for commercial or product stakeholders * Sanity checks before drilling down at seller or seller-campaign level ### Example Request ```bash theme={null} curl -X 'GET' \ 'https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/campaigns?intervalSize=Day&clickAttributionPolicy=AnySeller&startDate=2026-08-06&endDate=2026-08-07&campaignId=2&advertiserId=2&timeZoneId=Asia%2FSeoul' ``` This aggregates stats by day, using the Asia/Seoul day boundary instead of UTC. The same parameter works on `/stats/sellers` and `/stats/seller-campaigns`. *** ## Seller-Campaign Statistics **Purpose:** Performance aggregated per (campaign, seller) pair over time. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/seller-campaigns ``` This endpoint is the most granular standard reporting view and is key for: * Understanding how a specific seller performs within a given campaign * Comparing sellers within the same campaign * Single-Seller setups, where each seller effectively has a dedicated campaign ID ### Key Parameters * `advertiserId` (integer, optional)
Restrict to a specific advertiser. * `campaignId` (string, optional)
Restrict to a specific campaign (or template). * `sellerId` (string, optional)
Restrict to one seller. If omitted, you get rows across all sellers/campaigns. * `startDate`, `endDate`, `intervalSize`, `count`, `clickAttributionPolicy`
Same semantics as for the other endpoints. * `timeZoneId` (string, optional)
Same semantics as for the other endpoints. ### Response Shape (Conceptual) ```json expandable theme={null} { "columns": [ "campaignId", "sellerId", "sellerName", "day", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [ "168423", "1110222", "sellerA", "2026-03-01", 14542, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0 ] ], "rows": 1 } ``` ### Typical Use Cases * Per-seller performance within a multi-seller campaign * Single-Seller reporting when you want to filter on one (`sellerId`, `templateCampaignId`) pair * Feeding a seller dashboard that shows per-campaign breakdowns *** ## Multi-Seller vs Single-Seller: How to Think About IDs The endpoints are shared; what changes is how you interpret IDs: ### Multi-Seller * `campaignId` – ID of a shared MPO campaign. * `sellerId` – marketplace seller identifier managed via MPO Sellers. * Seller-campaign rows show how each seller performs inside the pooled campaign. ### Single-Seller * `campaignId` – often the template campaign ID (for high-level views). * `sellerId` – marketplace seller; still the primary key for per-seller reporting. * In some setups, a dedicated `sellerCampaignId` exists and may be used in other APIs; here you still filter by `campaignId` + `sellerId`. ### When designing your reporting model * Use **Seller Stats** when you care primarily about seller-level performance, regardless of campaign. * Use **Campaign Stats** when you care primarily about campaign-level performance, regardless of seller. * Use **Seller-Campaign Stats** when you need the intersection and want to understand how a seller behaves inside a specific campaign. *** ## Pagination and Count The `count` parameter lets you limit the maximum number of rows returned. Combined with `startDate` / `endDate`, you can build simple pagination, for example: 1. Request `startDate = 2026-03-01`, `endDate = 2026-03-31`, `count = 100`. 2. If you receive 100 rows and expect more: * Use the last date returned as the new `startDate` for the next page (plus one day, depending on your logic). * Repeat until a page returns fewer than `count` rows. If you need robust cursor-based pagination, check the latest API reference for advanced options. *** ## Error Handling The Standard Reporting API uses the same error semantics as other MPO endpoints: ### 4xx – Client errors * Invalid date range (for example, start date after end date, or too long) * Unsupported `intervalSize` * Invalid `clickAttributionPolicy` * Invalid or unauthorized `advertiserId`, `campaignId`, or `sellerId` ### 5xx – Server / transient errors * Retry with backoff; avoid tight retry loops. **Best practices:** * Validate inputs on your side (date formats, ranges, enums) before sending. * Implement backoff for network errors and 5xx responses. * Log both the HTTP status and error payload for diagnosis. ## Integration Patterns A few common patterns for marketplaces: ### Daily batch export for BI * Once per day, call Seller Stats and Campaign Stats for the previous day. * Load into your data warehouse and join with internal catalog and seller metadata. ### Seller-facing reporting * Use Seller Stats (and optional Seller-Campaign Stats) filtered by `sellerId`. * Aggregate over a seller’s preferred time window (for example, last 7 days, last 30 days). * Expose metrics via your own portal UI. ### Performance diagnosis * Use Seller-Campaign Stats for a given (`campaignId`, `sellerId`) to diagnose: * Why a seller is under-delivering * How performance changes after budget or template changes For short-window operational monitoring (for example, “did today’s budget change have an effect?”), complement these APIs with the **Real-Time Asynchronous API**. ## What's next * [MPO Real-Time Asynchronous API](/marketing-solutions/docs/getting-realtime-mpo-statistics) # MPO Standard Reporting API Metric Definitions Source: https://developers.criteo.com/marketing-solutions/docs/mpo-standard-reporting-api-metric-definitions Definitions for all metrics returned by the MPO Standard Reporting API, including displays, impressions, clicks, cost, and attribution-sensitive metrics. The Standard Reporting API returns aggregated MPO performance metrics across campaigns, sellers, and seller-campaigns. This page explains how to interpret each metric. *** ## Displays A display is one ad serving event: one banner shown to a user, regardless of the creative format or the number of seller products visible inside it. * 1 ad rendering = 1 display * The display count does not increase with the number of sellers or products shown inside the creative **Examples:** * *Single-seller creative:* one ad containing one seller product was shown → 1 display * *Multi-seller creative:* one ad displayed 4 seller products → 1 display (all 4 products appeared within a single banner) *** ## Impressions In MPO seller reporting, an impression is a seller/product-level exposure rather than a banner-level serving event. * One banner can generate multiple impressions if it shows multiple seller products * Impression counts are therefore not always equal to display counts A useful rule of thumb: | Metric | Measures | | ---------- | ---------------------------------------- | | Display | One banner shown | | Impression | One seller/product shown inside a banner | *** ## Clicks A click is a user click attributed to MPO delivery for the relevant reporting scope. In seller-level MPO reporting, clicks are interpreted in a seller-aware way, because MPO reporting tracks performance at seller and seller-campaign level rather than only at whole-banner level. *** ## Cost Cost is the advertising spend recorded for the selected MPO reporting scope and time range. Its interpretation differs by setup: * **Multi-seller MPO** — billing is click-based. Cost reflects click revenue: the sum of the clicked seller CPC multiplied by the number of attributed clicks. * **Single-seller MPO** — billing is display-based. Cost reflects display revenue under eCPM billing. Depending on the endpoint, cost can represent spend aggregated at campaign, seller, or seller-campaign level. *** ## saleUnits `saleUnits` is the number of products bought from a given seller. This metric is used instead of a generic orders count because MPO transactions can involve multiple sellers in a single purchase flow. `saleUnits` reflects seller-level purchased product volume, not basket-level order count. *** ## Revenue Revenue is the attributed sales value associated with the selected reporting scope and attribution settings. Because MPO reporting can be seller-specific, revenue interpretation depends on the attribution logic and seller scope used for the query. See [MPO Attribution](/marketing-solutions/docs/mpo-attribution) for details on how attribution settings affect this metric. *** ## CR (Conversion Rate) CR is the conversion rate for the selected reporting scope. Use it as an efficiency metric to understand how effectively MPO clicks convert into attributed sale activity for the reporting slice you selected. *** ## CPO CPO is the cost per order (or cost per outcome) returned by MPO standard reporting. Use it to understand how much spend is required to generate attributed sale activity. *** ## COS COS is the cost of sale ratio returned by MPO standard reporting. Use it to compare spend against attributed revenue for the selected reporting scope. *** ## ROAS ROAS is return on ad spend: the revenue generated relative to advertising spend. Use it as the primary efficiency metric when evaluating MPO revenue performance against spend. *** ## Key distinction: displays vs. impressions In MPO, displays and impressions are not interchangeable. Confusing them is a common source of reporting misinterpretation. | Metric | Measures | | ---------- | ------------------------------------------------- | | Display | The ad serving event itself — one banner rendered | | Impression | Seller/product exposure within that banner | **Example — multi-seller creative:** * 1 banner served = **1 display** * 4 seller products shown inside that banner = **4 impressions** This distinction matters when comparing seller visibility, delivery volume, and campaign exposure across MPO reporting surfaces. # Multi-Seller Source: https://developers.criteo.com/marketing-solutions/docs/multiseller Explore the endpoints for seller management via API. Explore the endpoints allowing to manage campaigns. Explore the programmatic ways to manage budgets. Learn more about MPO Multiseller statistics. # Getting Statistics Source: https://developers.criteo.com/marketing-solutions/docs/multiseller-getting-statistics The statistical endpoints allows you to review the performance of your campaigns and pass on seller specific statistics to your sellers. ## Metrics The metrics reported by the endpoints are: | | Metric Group | Description | | :- | :--------------------------- | :------------------------------------------- | | A | `impressions` | Number of times product is shown in a banner | | B | `clicks` | Number of clicks on product | | C | `cost` | Amount spent for clicks on products | | D | `saleUnits` | Number of products sold attributed to clicks | | E | `revenue` | Revenue generated by sales | | F | `CR` = Conversion Rate | salesUnits / clicks | | G | `CPO` = Cost Per Order | cost / salesUnits | | H | `COS` = Cost of Sale | cost / revenue | | I | `ROAS` = Return On Add Spend | revenue / cost |  \ The last six metrics can be computed in two ways, depending on the policy to count only the sales that result from clicks on the same seller's product in a banner (same-seller) or not (any-seller). Reporting can be controlled by `clickAttributionPolicy`. *** ## Aggregation Interval Size The duration of the aggregation interval for the fundamental events is controlled by the filter parameter **intervalSize**. (Consider also the name **frequency**.) The valid values for this parameter are:

Parameter

Definition

Type

Required?

advertiserId

Show only metrics for this advertiser.

integer

No

clickAttributionPolicy

Specify the click attribution policy for salesUnits, revenue, CR, CPO, COS, and ROAS

string (enum: Both , SameSeller , AnySeller )

No

count

Return up to the first count rows of data (default is all rows).

integer

No

endDate

Filter out all events that occur after date (default is today’s date).

string (date-time)

No

intervalSize

Specify the aggregation interval for events used to compute stats (default is "day").

string (enum: Hour , Day , Month , \`Year) | No

sellerId

Show only metrics for this seller (default all sellers).

string \` | No

startDate

Filter out all events that occur before date (default is the value of endDate ).

string (date-time)

No

For example, the following request fetches aggregated seller statistics for the current day with a granularity of one row per hour. Every seller managed by this advertiser will have up to 24 rows in the response. ```http theme={null} /marketplace-performance-outcomes/stats/sellers ``` The default interval size is `day`. If the interval size is `hour`, then the maximum date range allowed is one month. *** ## Date Filtering Filtering the results to events that happened in a temporal interval is done by setting the date filter parameters. These are `startDate` and the `endDate`. The start date includes all events timestamped since the beginning of that day, while the end date includes events until the end of day.

Query Parameter

Format

Meaning

startDate

YYYY-MM-DD

Filter out all events that occur before date (default is the value of endDate )

endDate

YYYY-MM-DD

Filter out all events that occur after date (default is today’s date)

If the end date is left off, it defaults to today. If the start date is left off, it defaults to the end date. As a result, the default query returns one day of stats. Using just the end date returns a single day as well: ```http theme={null} /marketplace-performance-outcomes/stats/sellers ``` There are a few constraints. The start date must not be in the future and must be on or precede the end date. The format to use for each is `YYY-MM-DD` (e.g. `2018-04-30`). The maximum duration of the date range is 1 year. If the granularity is `hour`, then the maximum duration of the date range is 1 month. Note that month and year aggregate values may contain partial data if filtered by date. *** ## Count Filtering Filtering the results to a maximum number of data rows is done by setting the count filter parameter. When combined with `startDate` this can be used to perform simple pagination. For example, the first page can have a count of 100; the second page can start on the day after the last date in the first result and still have a count of 100 and so on. 

Query Parameter

Options

Meaning

count

Int > 0

Return up to the first count rows of data (default is to return all rows available).

 \ The following query will return up to 100 rows of data. ```http theme={null} /marketplace-performance-outcomes/stats/sellers ``` The default is to report all rows. *** ## Seller Stats Get performance statistics aggregated for sellers.

Parameter

Definition

Type

Required?

advertiserId

Show only metrics for this advertiser.

integer

No

clickAttributionPolicy

Specify the click attribution policy for salesUnits, revenue, CR, CPO, COS, and ROAS

string (enum: Both , SameSeller , AnySeller )

No

count

Return up to the first count rows of data (default is all rows).

integer

No

endDate

Filter out all events that occur after date (default is today’s date).

string (date-time)

No

intervalSize

Specify the aggregation interval for events used to compute stats (default is "day").

string (enum: Hour, Day, Month, Year)

No

sellerId

Show only metrics for this seller (default all sellers).

string

No

startDate

Filter out all events that occur before date (default is the value of endDate ).

string (date-time)

No

```http theme={null} /marketplace-performance-outcomes/stats/sellers ``` **Sample response** ```json JSON theme={null} { "columns": ["sellerId", "sellerName", "month", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas"], "data": [ [1200972, "sellerA", "2019-05-01", 14542, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0], [1200972, "sellerA", "2019-06-01", 16619, 53, 3.71, 0, 0.0, 0.0, null, null, 0.0], [1200974, "sellerB", "2019-05-01", 10102, 47, 3.29, 3, 396000.0, 0.063, 1.096, 8.308E-6, 120364.741], [1200974, "sellerB", "2019-06-01", 11576, 54, 3.78, 1, 132000.0, 0.018, 3.78, 2.863E-5, 34920.634] ], "rows": 4 } ``` The seller id appears in the output in the first column and the seller name appears in the second. The time interval appears in the output as the third column. The remaining columns are metrics. *** ## Campaign Stats Get performance statistics aggregated for campaigns.

Parameter

Definition

Type

Required?

advertiserId

Show only metrics for this advertiser.

integer

No

campaignId

Show only metrics for this campaign (default all campaigns).

string

No

clickAttributionPolicy

Specify the click attribution policy for salesUnits, revenue, CR, CPO, COS, and ROAS

string (enum: Both , SameSeller , AnySeller )

No

count

Return up to the first count rows of data (default is all rows).

integer

No

endDate

Filter out all events that occur after date (default is today’s date).

string (date-time)

No

intervalSize

Specify the aggregation interval for events used to compute stats (default is "day").

string (enum: Hour , Day , Month , Year )

No

startDate

Filter out all events that occur before date (default is the value of endDate ).

string (date-time)

No

```http theme={null} /marketplace-performance-outcomes/stats/campaigns ``` **Sample response** ```json JSON theme={null} { "columns": [ "campaignId", "month", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [168423, "2019-05-01", 3969032, 13410, 1111.295, 985, 190758099, 0.073, 1.128, 0.000, 171653.880 ], [168423, "2019-06-01", 8479603, 25619, 2190.705, 740, 152783656, 0.028, 2.960, 0.000, 69741.775 ] ], "rows": 2 } ``` The campaign id appears in the output as the first column. The time interval appears in the output as the second column. The remaining columns are metrics. *** ## Seller Campaign Stats Get performance statistics aggregated for seller campaigns.

Parameter

Definition

Type

Required?

advertiserId

Show only metrics for this advertiser.

integer

No

campaignId

Show only metrics for this campaign (default all campaigns).

string

No

clickAttributionPolicy

Specify the click attribution policy for salesUnits, revenue, CR, CPO, COS, and ROAS

string (enum: Both , SameSeller , AnySeller )

No

count

Return up to the first count rows of data (default is all rows).

integer

No

endDate

Filter out all events that occur after date (default is today’s date).

string (date-time)

No

intervalSize

Specify the aggregation interval for events used to compute stats (default is "day").

string (enum: Hour, Day, Month, Year)

No

sellerId

Show only metrics for this seller (default all sellers).

string

No

startDate

Filter out all events that occur before date (default is the value of endDate ).

string (date-time)

No

```http theme={null} /marketplace-performance-outcomes/stats/seller-campaigns ``` **Sample response** ```json JSON theme={null} { "columns": [ "campaignId", "sellerId", "sellerName", "month", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [168423, 1110222, "118883955", "2019-05-01", 14542, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0], [168423, 1110222, "118883955", "2019-06-01", 16619, 53, 3.71, 0, 0.0, 0.0, null, null, 0.0], [168423, 1110225, "117980027", "2019-05-01", 12502, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0], [168423, 1110225, "117980027", "2019-06-01", 20266, 53, 3.71, 0, 0.0, 0.0, null, null, 0.0] ], "rows": 4 } ``` The `campaignId`, `sellerId`, and `sellerName` appear in the first three columns of the output. These are followed by the interval size column. The remaining columns are metrics. # Managing Budgets Source: https://developers.criteo.com/marketing-solutions/docs/multiseller-managing-budgets ## Introduction Budget are used to specify budget constraints for one or more Seller-Campaigns of the same Seller. You have different types of budgets : * **Uncapped** : Define an unlimited amount, * **Capped** : Define a limited amount, * **Daily** : Define a limited daily amount. A Budget can specify a `startDate` and an `endDate` : * **`startDate`**: date at which you want your budget to be taken into consideration. * **`endDate`**: date until which the budget is taken into consideration. A Budget status can be either : * **Active** : this budget can be consumed in one or more Seller-Campaigns for delivering ads. A budget is active when all the following conditions are met: * the budget has not been suspended (see "[Suspending budgets](/marketing-solutions/docs/managing-budgets#suspending-budgets)" section), * the current date is between `startDate` and `endDate`, * the spent amount of the budget is smaller than the specified amount. * **Inactive** : when a budget is not Active, it is Inactive. It cannot be consumed in any Seller-Campaign for delivering ads. Notice that there is at most **one** active daily budget and **one** active non-daily budget *** ## Creating Budgets for Seller-Campaigns In order to create Budgets for Seller-Campaigns, you need to make the following call: ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "sellerId": "1", "campaignIds": ["10001"], "budgetType": "Capped", "amount": 10.00, "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "sellerId": "2", "campaignIds": ["10001"], "budgetType": "Capped", "amount": 20.00, "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "sellerId": "3", "campaignIds": ["10001"], "budgetType": "Capped", "amount": 30.00, "startDate": "2019-05-01", "endDate": "2019-05-31" }] ``` **`SellerId`** The `sellerId` of the Seller for which you want to create a budget. **`campaignIds`** Array of `campaignIds` of the campaigns for which you want the budgets. **`budgetType`** Type of budget. You have 3 possible values for this `Uncapped`, `Capped`, `Daily`. **`amount`** Amount of money you want to specify for this budget. **`startDate`** Date at which you want your budget to be taken into consideration. **`endDate`** Date until which the budget is taken into consideration. *** ### Creating Capped Budgets When creating budgets, you have the choice between 3 different types of budgets. One of these is the capped budget, it enables you to define the maximum amount of money you would like to spend on a given time period. *** ### Creating Uncapped Budgets If you don't want to define a maximum amount of money you would like to spend on a given time period, you can create Uncapped budgets. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "sellerId": "1", "campaignIds": ["10001"], "budgetType": "Uncapped", "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "sellerId": "2", "campaignIds": ["10001"], "budgetType": "Uncapped", "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "sellerId": "3", "campaignIds": ["10001"], "budgetType": "Uncapped", "startDate": "2019-05-01", "endDate": "2019-05-31" }] ``` If you want to control how fast the money is spent, you can combine the Uncapped budget with a Daily budget. *** ### Creating Daily Budgets Additionally to the Capped and Uncapped budgets, you can define Daily budgets. This means that you can define how fast you want to spend your budget for a given time period. The Daily budget defines the maximum amount of money you would like to spend in average in the 7 last days with a maximum of 150% of the daily budget in a day. Notice that Daily Budgets only work if you have also specified a Total budget. This Total budget is specified either by a **Capped** or **Uncapped**budget. If you have not specified a Total budget, your Seller-Campaigns will not deliver ads (even if you specified a Daily-Budget). For example, you can create a daily Budget of \$5 for the Sellers 1,2, and 3 and back them with an unlimited total budget (Uncapped Budget): ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON expandable theme={null} [{ "sellerId": "1", "campaignIds": ["10001"], "budgetType": "Uncapped", "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "sellerId": "2", "campaignIds": ["10001"], "budgetType": "Uncapped", "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "sellerId": "3", "campaignIds": ["10001"], "budgetType": "Uncapped", "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "sellerId": "1", "campaignIds": ["10001"], "budgetType": "Daily", "startDate": "2019-05-01", "endDate": "2019-05-31", "amount": 5 },{ "sellerId": "2", "campaignIds": ["10001"], "budgetType": "Daily", "startDate": "2019-05-01", "endDate": "2019-05-31", "amount": 5 },{ "sellerId": "3", "campaignIds": ["10001"], "budgetType": "Daily", "startDate": "2019-05-01", "endDate": "2019-05-31", "amount": 5 }] ``` *** ## Getting Budgets You can list of your budgets with following calls: ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Response example** ```json JSON expandable theme={null} [{ "id" : "101", "sellerId": "1", "campaignIds": ["10001"], "budgetType": "Capped", "amount": 30.00, "startDate": "2019-05-01", "endDate": "2019-05-31", "spend" : 0, "status" : "Scheduled", "isSuspended" : false },{ "id" : "102", "sellerId": "2", "campaignIds": ["10001"], "budgetType": "Capped", "amount": 30.00, "startDate": "2019-05-01", "endDate": "2019-05-31", "spend" : 0, "status" : "Scheduled", "isSuspended" : false },{ "id" : "103", "sellerId": "3", "campaignIds": ["10001"], "budgetType": "Capped", "amount": 30.00, "startDate": "2019-05-01", "endDate": "2019-05-31", "spend" : 0, "status" : "Scheduled", "isSuspended" : false }] ``` **`sellerId`** The internal ID that our system has attributed to your seller. **`spend`** Amount of money already spent on this budget. **`isSuspended`** The suspension status of your budget. If your budget is suspended, the system will stop using this budget for delivery clicks in the associated Seller-Campaigns. **`status`** * **Scheduled** : the budget will be used in the future starting at the `startDate`, * **Current** : the budget is currently being used to deliver ads, * **Archived** : the budget is not used anymore because it's `endDate` has been reached.

Parameter

Definition

Type

Required?

advertiserId

Return only budgets that pay for a given advertiser. Default is to not filter on advertiser

integer

No

campaignId

Return only budgets that pay for a given campaign. Default is to not filter on campaign

integer

No

sellerId

Return only budgets belonging to the given seller. Default is to not filter on seller.

string

No

endAfterDate

Return budgets that end after the given date. Default is today ( yyyy-MM-DD ).

string

No

startBeforeDate

Return budgets that start on or before the given date. Default is to not filter on startDate.

string

No

status

Return only budgets with the given status. Default is to not filter on status. Possible values: Archived , \*\*

Current ,

Scheduled\*\*

string

No

type

Return only budgets of the given type. Default is to not filter on budget type. Possible values: Capped , \*\*

Uncapped ,

Daily\*\*

string

No

withBalance

Return budgets with remaining balance. Default is to not filter on balance.

boolean

No

withSpend

Return budgets with any positive spend. Default is to not filter on spend

boolean

No

*** ## Get one specific budget You can also fetch the details of a single budget using the following request: ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} ``` **Sample response** ```json theme={null} { "id": "1759183", "sellerId": "321392", "campaignIds": [ 143962 ], "budgetType": "Capped", "amount": 1000, "startDate": "2021-01-11", "endDate": "2021-01-12", "spend": null, "status": "Active", "isSuspended": false } ``` *** ## Updating Budgets Once you have created budgets, you can modify them for: * Increasing their budget amount. * Decreasing their budget amount. * Changing their dates. * Changing the Campaigns that uses these budget. * Suspending budgets. Notice that you can do all this changes with one single `PATCH` request or separately ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "budgetId" : "101", //id of the budget "campaignIds": ["10001"], "amount": 10.00, "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "budgetId" : "102", //id of the budget "campaignIds": ["10001"], "amount": 20.00, "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "budgetId" : "103", //id of the budget "campaignIds": ["10001"], "amount": 30.00, "startDate": "2019-05-01", "endDate": "2019-05-31" }] ``` *** ### Increase Budget amounts When updating budgets, you can increase the budget amounts. The increased amount will be taken into account immediately. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "budgetId": "101", "amount": 20.00, },{ "budgetId": "102", "amount": 30.00, },{ "budgetId": "103", "amount": 40.00, }] ``` *** ### Decrease Capped Budget amounts When decreasing a capped budget amount, the new amount will be taken into account this new budget immediately. However, the spend amount can continue decreasing a little bit after your change. This is because some clicks that occurred just before your change were not yet taken into account in the spend at the moment of the change. This means that the spend amount can exceed this new decreased amount (even if the set amount was above the spend at the moment of the decrease). For example, if your current budget has an amount of \$100 with a spend of \$49, and you decrease your budget to \$50, the new spend might still reach \$52 (to take into account the few clicks that occurred before the change). ```http theme={null} /marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "budgetId": "101", "amount": 5.00, },{ "budgetId": "102", "amount": 15.00, },{ "budgetId": "103", "amount": 25.00, }] ``` *** ### Decrease Daily Budget amounts When decreasing a daily budget amount, we will try to achieve this new decreased daily amount as soon as possible. However, it can take up to seven days so that your 7-day average reflects the new daily amount (although, most of the time, it will take much less time). ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "budgetId": "101", "amount": 5.00, },{ "budgetId": "102", "amount": 5.00, },{ "budgetId": "103", "amount": 5.00, }] ``` *** ### Changing the Dates of Budgets You can change the `startDate` and `endDate` of a Budget if : * the current and new values of `startDate` and `endDate` are in the future, * the `endDate` is not anterior to the `startDate`  ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "budgetId" : "101", "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "budgetId" : "102", "startDate": "2019-05-01", "endDate": "2019-05-31" },{ "budgetId" : "103", "startDate": "2019-05-01", "endDate": "2019-05-31" }] ``` *** ### Sharing Budgets Between Campaigns A Seller budget can be used within several MPO-Campaign. To set it up, you need to provide several `campaignIds` at the creation of the Budget. After the creation of the budget, you can update the budget and replace the current list of campaigns (containing only 1 campaigns) with a new list of campaigns (containing multiple campaigns): ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "budgetId" : "101", "campaignIds": ["10001","10002"] },{ "budgetId" : "102", "campaignIds": ["10001","10002"] },{ "budgetId" : "103", "campaignIds": ["10001","10002"] }] ``` *** ## Suspending Budgets In case you want to stop using a budget, you can suspend it. After a budget is suspended, we will stop delivering ads for the Seller-Campaigns using this budget. You can also make the bufget active if previously suspended. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets ``` **Sample request** ```json JSON theme={null} [{ "budgetId" : "101", "isSuspended": true },{ "budgetId" : "102", "isSuspended": true },{ "budgetId" : "103", "isSuspended": false }] ``` # Managing Campaigns Source: https://developers.criteo.com/marketing-solutions/docs/multiseller-managing-campaigns An MPO-Campaign is a course of action to advertise the products of your sellers. ## Adding Campaigns Campaigns are not added with the API. Instead, they are created, started and stopped by your Technical Solution engineer. *** ## Managing Seller-Campaigns A Seller-Campaign contains all the information relative to the advertisement for the products of a Seller in a Campaign. In particular, it contains information about bid and status: **`bid`**\ Bid specified for this Seller in this Campaign **`suspendedSince`**\ Date and time since we stopped delivering ads for this Seller in this Campaign. **`suspensionReasons`**\ List of reasons why the campaign is suspended (possible values are: `NoMoreBudget`, `ManuallyStopped`, `NoBudgetDefined`, `NoCpcDefined`, `RemovedFromCatalog`) Every Seller-Campaign is identified by: **`sellerId`**\ `SellerId` of the seller associated to this Seller-Campaign **`campaignId`**\ `CampaignId` of the MPO-campaign associated to this Seller-Campaign *** ## Adding Seller-Campaigns Seller-Campaigns get automatically created for every Campaign and every Seller in your feed. * New Seller-Campaigns are created inactive by default (`suspendedSince` flag is set to the moment of creation)  *** ## Getting Seller-Campaigns To see what Seller-Campaigns are available, can make the following query: ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns ``` **Sample response** ```json JSON theme={null} [{ "id": "1.10001", "suspendedSince": "2018-07-30T18:00:13.333", "suspensionReasons": ["NoMoreBudget"], "sellerId": "1", "campaignId": 10001, "bid": null },{ "id": "2.10001", "suspendedSince": "2018-09-03T09:00:23.8", "suspensionReasons": ["ManuallyStopped"], "sellerId": "2", "campaignId": 10001, "bid": null },{ "id": "3.10001", "suspendedSince": "2018-09-03T09:00:23.8", "suspensionReasons": ["NoCpcDefined"], "sellerId": "3", "campaignId": 10001, "bid": null }] ``` *** ## Get Specific Seller-campaign You can also fetch the details of a single Seller-campaign using the following request: ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId} ``` **Sample response** ```json theme={null} { "id": "543210.123456", "sellerId": "543210", "campaignId": 123456, "bid": 1.55, "suspendedSince": "2018-07-30T15:15:24.813", "suspensionReasons": [ "NoMoreBudget" ] } ``` An active seller campaign meets these conditions: * The `suspendedSince` field is `null`. * The `bid` value is greater than zero. * The bid currency matches the `bidCurrency` of the related campaign. Additionally, an active seller campaign must have an active total budget (capped or uncapped). It may also have an active daily budget to further restrict spending. **Suspension reasons** * `ManuallyStopped`: The campaign has been manually paused, independent of other suspension causes. * `NoBudgetDefined`: No valid budget is linked to the campaign. * `NoCpcDefined`: No cost-per-click (CPC) has been set for the campaign. * `NoMoreBudget`: The current budget of the campaign has been fully used. * `RemovedFromCatalog`: All products in the campaign have been removed from the catalog. * `NotYetStarted`: The campaign is newly created and has not yet been processed. *** ## Get a Collection of Budgets for Selected Seller-Campaign The following endpoint retrieves a list of budgets for the specified seller campaign, applying any optional filters provided. If no filters are set, it returns all accessible budgets except those with an `endDate` in the past.\ When multiple filters are applied, only budgets meeting all criteria are included. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId}/budgets ``` **Sample response** ```json theme={null} [ { "id": "6907877", "sellerId": "10624700", "campaignIds": [ 225662 ], "budgetType": "Daily", "amount": 12.0000, "startDate": "2021-02-25", "endDate": "Never", "spend": null, "status": "Current", "isSuspended": false } ] ``` You can apply the following query parameters to the endpoint to specify filters:

Parameter

Definition

Type

Required?

sellerCampaignId

Filters budgets belonging to the specified seller campaign.

string

Yes

endAfterDate

Returns budgets ending after the specified date ( yyyy-MM-DD ). Defaults to only active (not ended) budgets if omitted.

string

No

startBeforeDate

Returns budgets starting on or before the specified date ( yyyy-MM-DD ).

string

No

status

Filters budgets by their status. Possible values: Archived , \*\*

Current ,

Scheduled\*\*.

string

No

type

Filters budgets by the specified budget type.

string

No

withBalance

Returns only budgets with a positive balance.

boolean

No

withSpend

Returns budgets with a positive spend amount.

boolean

No

*** ## Starting Seller-Campaigns In order to start delivering ads for a Seller in a Campaign, the Seller-Campaign needs to: * be part of a running Campaign, * have a bid (see "[Setting the Bid for a given Seller-Campaign](/marketing-solutions/docs/managing-campaigns#setting-the-bids-of-seller-campaigns)" section), * have an active budget (see "[Managing Budgets](/marketing-solutions/docs/managing-budgets)" section), When a Seller-Campaign becomes inactive, the `suspendedSince` flag is null. *** ## Stopping Seller-Campaigns In order to stop delivering ads for a Seller in a Campaign, you can do one of the following actions: * set the bid of the Seller-Campaign to null (see "[Setting the Bid for a given Seller-Campaign](/marketing-solutions/docs/managing-campaigns#setting-the-bids-of-seller-campaigns)" section), * suspend the current budget (see "[Suspend a Budget](/marketing-solutions/docs/managing-budgets#suspending-budgets)" section), * remove products of this Seller from the feed (if you have several MPO-Campaigns, this will also stop the Seller in the other MPO-Campaigns). When a Seller-Campaign becomes inactive, the `suspendedSince` flag is set to the current date. *** ## Setting the Bids of Seller-Campaigns In order to have a Sellers active in the campaign, you have to specify the bids that will be used for these Sellers in the given Campaign. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns ``` **Sample response** ```json JSON theme={null} [{ "id": "1.10001", "bid": 0.3 },{ "id": "2.10001", "bid": 0.6 },{ "id": "3.10001", "bid": 0.5 }] ``` Note that the ID is defined by `{sellerId}.{campaignId}` (e.g 1.10001 for seller ID 1 and campaign 10001). # Managing Sellers Source: https://developers.criteo.com/marketing-solutions/docs/multiseller-managing-sellers ## Introduction The seller represents the legal person selling products on your platform. The MPO API enables you to manage the advertisement of your Sellers. *** ## Adding Sellers Sellers are not added with the API. Instead, they are automatically added from the Catalog you provided us. In your catalog, you should provide the `sellerName` field on the Sellers' products. Products that don't have these fields provided will not be advertised. `sellerName` is case-sensitive. If your seller has different case, it will be considered as a different Seller. You can use your internal ID of the seller as SellerName. The catalog can be updated from the [Criteo Product Catalog API](/retail-media/v2026-preview/docs/product-importer-api) or directly from [Commerce Growth Dashboard](https://help.criteo.com/kb/guide/en/introducing-product-catalog-HuVC8b4c4e/Steps/3316715). *** ## Removing Sellers A Seller can be removed by removing its products from the Feed. If you want to stop an advertising a Seller immediately, you can suspend the budgets of its Seller-Campaigns (see "[Suspend a budget](/marketing-solutions/docs/managing-budgets#suspending-budgets)" section). *** ## Getting Sellers This endpoint returns the list of sellers that was extracted. ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/sellers ``` **Sample response** ```json JSON theme={null} [{ "id" : "1", "sellerName": "AHepburn", },{ "id" : "2", "sellerName": "HBogart" },{ "id" : "3", "sellerName": "NewTech" }] ``` A seller is defined by the following: **`sellerName`**\ This corresponds to the `sellerId` that was specified in the product catalog you provided. **`sellerId`**\ This `sellerId` identifies your seller. It is attributed by our Seller ingestion system.

Parameter

Definition

Type

Required?

advertiserId

Return sellers for the given advertiser Id. Default is to not filter on advertiser

integer

No

campaignId

Return sellers for the given campaign Id. Default is to not filter on campaign

integer

No

sellerName

Returns only sellers with the given sellerName value.

string

No

sellerStatus

Return only sellers with a specific status. Possible values: Inactive , \*\*

Active\*\*.

string

No

withBudgetStatus

Return sellers with any budget having the given state. Default is to not filter on the budget state. Possible values: Archived , \*\*

Current ,

Scheduled\*\*

string

No

withProducts

Return sellers with or without products in the catalog. The default is not to filter on products in the catalog.

boolean

No

There is an enrichment delay of 24 to 48 hours from when a product is placed in the catalog and becomes available. *** ## Get Specific Seller You can also fetch the details of a single Seller using the following endpoint: ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId} ``` **Sample response** ```json theme={null} { "id": "123456", "sellerName": "HBogart" } ``` *** ## Get a Collection of Budgets for Selected Seller The following endpoint retrieves a list of budgets for a specific seller, applying any optional filters provided as a query parameters.\ If no filters are given, return all budgets the user can access, excluding those with an `endDate` in the past.\ When multiple filters are used, only budgets that meet all the specified criteria are returned.\ For more information, refer to the [budgets endpoint documentation](/marketing-solutions/docs/managing-budgets). ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/budgets ``` **Sample response** ```json theme={null} [ { "id": "123456", "sellerId": "123456", "campaignIds": [ 123532 ], "budgetType": "Daily", "amount": 12.0000, "startDate": "2021-02-25", "endDate": "Never", "spend": null, "status": "Current", "isSuspended": false } ] ``` You can apply the following query parameters to the endpoint to specify filters:

Parameter

Definition

Type

Required?

sellerId

Filters budgets to those owned by the specified seller.

string

Yes

campaignId

Filters budgets to those funding the specified campaign.

integer

No

endAfterDate

Returns budgets ending after the given date ( yyyy-MM-DD ). If omitted, only budgets still active are returned.

string

No

startBeforeDate

Returns budgets starting on or before the given date ( yyyy-MM-DD ).

string

No

status

Filters budgets by the specified status. Possible values: Archived , \*\*

Current ,

Scheduled\*\*.

string

No

type

Filters budgets by the specified budget type.

string

No

withBalance

Returns only budgets that currently have a remaining balance.

boolean

No

withSpend

Returns budgets that have a positive spend amount.

boolean

No

*** ## Get a Collection of Campaigns for Selected Seller The following endpoint returns a list of seller campaigns for the specified seller, applying any optional filters provided. If no filters are given, it returns the full collection accessible to the user.\ When multiple filters are used, only campaigns meeting all filter criteria are included.\ For more information, see the [seller campaigns endpoint documentation](/marketing-solutions/docs/managing-campaigns). ```http theme={null} https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/seller-campaigns ``` **Sample response** ```json theme={null} [ { "id": "10624700.225662", "sellerId": "10624700", "campaignId": 225662, "bid": null, "suspendedSince": "2021-03-07T23:06:15.17", "suspensionReasons": [ "NoBudgetDefined" ] } ] ``` You can apply the following query parameters to the endpoint to specify filters:

Parameter

Definition

Type

Required?

sellerId

Limits results to campaigns belonging to the specified seller.

string

Yes

budgetStatus

Filters campaigns by the budget status. Possible values: Archived , \*\*

Current ,

Scheduled\*\*.

string

No

campaignId

Filters campaigns linked to the specified campaign ID.

integer

No

sellerStatus

Filters campaigns by the seller's status. Possible values: Inactive , \*\*

Active\*\*.

string

No

# Onboarding to MPO Source: https://developers.criteo.com/marketing-solutions/docs/onboarding-to-mpo Marketplace Performance Outcomes (MPO) is API-first, but the API is only one part of the integration. Before a marketplace can activate sellers, set budgets, or pull statistics, it needs two core data foundations in place: event collection and catalog integration with seller data. This article explains what needs to be in place before MPO can work reliably, why these inputs matter, and where to go next for implementation details. *** ## What this article is for This page is intended for: * Technical leads and architects planning an MPO integration * Developers preparing the marketplace-side implementation * Marketplace teams aligning with Criteo on onboarding scope Use this page as the entry point to the Integration section. It gives the high-level onboarding picture before you move into detailed event and catalog guides. *** ## The two pillars of MPO onboarding MPO depends on two types of data being set up correctly: 1. **Events** — so Criteo can understand user behavior, build audiences, measure conversions, and optimize delivery 2. **Catalog data** — so Criteo can identify products, sellers, and the seller-to-product relationships used by MPO **Note:** If either pillar is missing or inconsistent, MPO can still appear partially configured, but seller activation, delivery, attribution, and reporting may fail or become unreliable. *** ## Why MPO collects events MPO is designed to help marketplaces advertise sellers offsite using Criteo's performance advertising stack. To do that, Criteo needs event signals from the marketplace site or app. At a minimum, MPO onboarding expects: * Product page events * Transaction / conversion events * Consistent user identifiers across the supported integration surfaces These events support three critical MPO functions: ### 1. Audience building MPO audience eligibility is determined at the seller level. When user events are received, MPO updates the seller-level audience state used for targeting and recommendation logic. ### 2. Performance optimization MPO needs behavioral signals to decide which sellers and products are relevant for a given user, and to support recommendation-driven delivery and seller-level optimization. ### 3. Attribution and reporting Conversions used for MPO attribution can come from OneTag, app integrations, MMP integrations, and other supported event sources. Those conversion signals feed into Criteo's reporting and optimization pipeline. *** ## Event collection options The right event setup depends on whether the marketplace is integrating web, app, or both. ### Web For web onboarding, use OneTag to capture on-site user behavior, including product page views and transactions. For offsite web integrations, the main shared references are: * [Introduction to the Criteo OneTag](https://help.criteo.com/kb/guide/en/intro-to-the-criteo-onetag-8fjCDwCENw/Steps/775595) ### MMP-based app integrations > **Important:** All in-app events should be forwarded — not only the subset attributed to Criteo by the MMP. Forwarding only attributed events can break offsite measurement and reduce performance. Common MMP references used by Criteo teams include: * AppsFlyer * Adjust * Branch * Singular * Kochava * Tealium * Segment * AB180 Airbridge *** ## Catalog integration for MPO MPO sellers are not usually created manually through MPO onboarding flows. Instead, sellers are inferred from the marketplace product catalog, and MPO relies on that catalog to expose sellers and products correctly through the API and delivery systems. ### MPO-specific seller mapping Your product feed must include `seller_id` and `seller_name` for each product. Criteo uses these fields to identify and ingest sellers from your catalog. Once your catalog is processed, Criteo generates an internal `sellerId` for each seller. You can retrieve this through the MPO Sellers endpoints and use it to map back to your own seller records. ### Important rules for seller data When preparing seller fields for MPO: * Treat `seller_id` as case-sensitive * Keep seller values stable over time * Use your own internal seller identifier consistently if possible ### What happens after seller data is ingested Once the catalog is processed correctly, sellers become available through the MPO Sellers endpoints within 1–2 days and can then be linked to campaign operations such as seller-campaigns, bids, budgets, and reporting. **Relevant API endpoints:** ```http theme={null} GET /marketplace-performance-outcomes/sellers GET /marketplace-performance-outcomes/sellers/{sellerId} GET /marketplace-performance-outcomes/sellers/{sellerId}/budgets GET /marketplace-performance-outcomes/sellers/{sellerId}/seller-campaigns ``` **Note:** Because ingestion is asynchronous, allow processing time between catalog updates and MPO seller availability. Build your onboarding and validation flows with that delay in mind. *** ## What Criteo sets up vs what the marketplace sets up MPO onboarding is shared between Criteo and the marketplace.

Responsibility

Tasks

Criteo

MPO enablement on the account; campaign / template configuration; core advertiser and campaign readiness for MPO use

Marketplace

Event collection on web and/or app; product catalog integration; seller data mapping in the feed; OAuth / API integration for ongoing operations; seller activation, budgets, bids, and statistics retrieval once onboarding is complete

*** ## Recommended onboarding checklist Before moving into campaign launch or API operations, confirm all of the following are in place: * [ ] OneTag or the relevant app event integration is set up * [ ] Product page and transaction events are being collected * [ ] The catalog includes MPO seller fields * [ ] `seller_id` and `seller_name` values are consistent in casing and format across all catalog updates * [ ] The marketplace can retrieve sellers through the MPO Sellers endpoints * [ ] API authentication is ready for ongoing operations *** ## Related documentation The detailed implementation guidance lives in the child pages of this Integration section. ### Event collection Use the dedicated Event collection article for: * Why MPO needs site and app events * Web tagging with [Introduction to the Criteo OneTag](https://help.criteo.com/kb/guide/en/intro-to-the-criteo-onetag-8fjCDwCENw/Steps/775595) and [OneTag for Offsite](/retailer-integration/docs/onetag-for-offsite) * Hybrid app event capture with [OneTag for Offsite – Hybrid Apps](/retailer-integration/docs/onetag-offsite-for-hybrid-apps) * Native app event capture with [API Parameters – In-app events](/retailer-integration/docs/api-parameters-1#in-app-events) * MMP integration references * Validation and prelaunch checks ### Product taxonomy Use the dedicated Product taxonomy article for: * MPO-specific feed requirements with [Product feed parameters](/retailer-integration/docs/product-feed-parameters) * Seller field mapping * Seller ID and seller name rules * Feed validation expectations, sync behavior, and other catalog requirements via the Product Feed Upload Guide, Feed Best Practices, and Product Importer API Guide * Troubleshooting seller ingestion issues # Placement Source: https://developers.criteo.com/marketing-solutions/docs/placement ## **Introduction** The **Placement Report API** endpoint allows for customized reporting containing placement level data from a campaign's delivery. This new endpoint offers the ability to pull reports with data that was previously only available through the Criteo Platform UI. There are several dimensions and metrics that can be combined for different insights to show how inventory is playing a role in campaign delivery. A set of filters applied as parameters in the `POST` request can also be used to limit the data in the report so it only contains relevant details. The metrics are similar to the ones provided in the [Statistics endpoint](/marketing-solutions/docs/campaign-statistics), but the dimensions allow for seeing performance across the different placements available in a campaign's inventory. Please note the data in this endpoint for the current day can only be accessed after midnight that day and can take up to 4 hours to become available (so the sum of today's data will be available tomorrow between midnight and 4am). Placement data is retained for up to 3 months and queries to this endpoint return a maximum of 20000 rows. These limitations are in place to ensure optimal report performance and stability. *** ## **Endpoint** *** ## **Retrieving Placements** The Placement Report API endpoint offers reporting on the performance of inventory based on the available criteria provided in a POST request. Keep in mind the following are required fields for queries on this endpoint: `startDate`, `endDate`, `advertiserIds`, `timezone`, `currency`, and `disclosed`. Examples and definitions for each of the fields are provided in the following pages. **Request example:** ```json JSON theme={null} { "data": [{ "type": "ReportOrder", "attributes": { "advertiserIds": "22, 4949", "startDate": "2020-11-04", "endDate": "2020-11-04", "format": "json", "timezone": "Asia/Tokyo", "currency": "JPY", "dimensions": ["advertiserId", "adSetId", "placement"], "metrics": ["displays", "cost"] } }] } ``` The report generated from the POST request is returned in the response. The report is generated in the format specified in the request. **Response example:** ```json JSON theme={null} { "data": [{ "type": "Report", "attributes": { "rows": [{ "advertiserId": "22", "adSetId": "200094", "placement": "My android app", "displays": "5577", "cost": "0.0200", }] } }] } ``` *** ## **Dimensions** Dimensions requested in the API call will return data detailing delivery. The dimensions requested in the POST call will be returned for each row of data returned in the report. There are no restrictions on the number of dimensions or the order of dimensions. Dimensions are provided as an array of strings in the POST request. The full list is below:

Field

Description

advertiserId

ID of the advertiser

adsetId

ID of the ad set

adsetName

Name of the ad set

environment

Web/Android/iOS

placement

The name of the ad placement

The `dimensions` array of the request should contain all requested dimensions as strings in an array. For example: `['placement','adsetId','environment']` *** ## **Metrics** The metrics requested in the POST call will be returned for each available row of data. Metrics are provided as an array of strings in the data payload of the POST request to the API endpoint. The full list of metrics is below:

Field

Description

clicks

The number of clicks driven by the add.

displays

The number of displays/impressions of ads served on sites through the Criteo Publisher Network.

cost

The amount of money spent on Criteo advertising.

salesPc30d

The number of completed e-commerce transactions or purchases. Attribution model pc30d

salesPv1d

The number of completed e-commerce transactions or purchases. Attribution model pv1d

revenuePc30d

The amount of money generated by the online sales. Attribution model pc30d

revenuePv1d

The amount of money generated by the online sales. Attribution model pv1d

cosPc30d

Cost Of Sales - the ratio between the cost generated by the campaign(s) vs. the revenue generated by the sales, figured as a percentage. Attribution model pc30d

cosPv1d

Cost Of Sales - the ratio between the cost generated by the campaign(s) vs. the revenue generated by the sales, figured as a percentage. Attribution model pv1d

roasPc30d

Return On Ad Spend - the ratio between the revenue generated and the cost. Attribution model pc30d

roasPv1d

Return On Ad Spend - the ratio between the revenue generated and the cost. Attribution model pv1d

cpoPc30d

Cost Per Order - the amount of money that needs to be spent to get one order or transaction. Attribution model pc30d

cpoPv1d

Cost Per Order - the amount of money that needs to be spent to get one order or transaction. Attribution model pv1d

cvrPc30d

ConVersion Rate - the percentage of completed purchases compared to the clicks that occurred. Attribution model pc30d

cvrPv1d

ConVersion Rate - the percentage of completed purchases compared to the clicks that occurred. Attribution model pv1d

The `metrics` array of the request uses the same format as the `dimensions` array. For example: `['clicks','displays','roasPc30d']` *** ## Filters Filters can be used to be more selective about the data returned in the response and produce a more focused report. A number of filters are required to make a query to the Placement Report endpoint. Filters are provided as properties to the "attributes" object in the data payload of the POST request to the API.

Field

Description

Optional/Required

Type

Default Value

startDate

start of the period

required

DateTime

endDate

end of the period

required

DateTime

advertiserIds

List of Advertiser Ids separated by commas

required

string of ID's separated by commas

adsetIds

List of Ad Set Ids separated by commas

optional

string of ID's separated by commas

adsetName

Filter for Ad Set names

optional

string

environment

Web/Android/iOS

optional

string

timezone

Time zone used for dates

required

Timezone

currency

Currency used for amounts

required

ISO 4217 Currency Code

placement

Filter the value of the placement

optional

string

format

Format of the report provided in the response (json, xml, csv, xls)

optional

string

CSV

disclosed

undisclosed exchanges for which we don't have the domain

required

string

true


## What's next * [Placement Category](/marketing-solutions/docs/placement-category) # Placement Category Source: https://developers.criteo.com/marketing-solutions/docs/placement-category ## **Introduction** The placement category endpoint provides transparency on which **categories** of domains your ads are being displayed on, as well provides visibility into the number of displays, clicks, and sales that have occurred via a given publisher. *** ## **How It Works** A single domain can have several categories associated with it because the single page categorization is grouped at the domain level. Also, each individual page can hold several categories. For example, a news website could have pages linked to business, sports, and entertainment. **How Hits are Normalized Into Displays** On examplenewssite.com there are 50 hits on the following categories: * News 10 * Travel 15 * Entertainment 25 Then take the ratio of each category compared to the total number of hits on examplesnewssite.com. * News 0.2 * Travel 0.3 * Entertainment 0.5 Suppose there are 20 displays on examplenewssite.com and users clicked through 10 times, apply those ratios to both displays and clicks to get accurate category level data. * News 4 displays / 2 clicks * Travel 6 displays / 3 clicks * Entertainment 10 displays / 5 clicks *** ## **Endpoint** A `POST` request returns a report on categories based on the query. The query returns a predefined data set that includes displays, clicks, 30 day post click sales, and 1 day post view sales. ```http theme={null} https://api.criteo.com/2026-01/categories/report ``` **Required Attributes** There are 4 required attributes when making a call.\ For additional fields see the **Attributes** table below. * `startDate` * `endDate` * `advertiserIds` * `format` **Request example:** ```json JSON theme={null} { "data": { "startDate": "2020-01-01", "endDate": "2020-01-02", "advertiserIds": [ "123", "456", "789" ], "category": "News" "domain": "example.com", "timezone": "UTC", "format": "json", } } ``` The response is a file dictated by the "format" field in the request. This could be returned in JSON, XML, CSV, or XLS. **Response example:** ```json JSON theme={null} [ { "advertiserId": 123, "category": "News", "domain": "example.com", "displays": 42, "clicks": 12, "salesPc30d":5, "salesPv1d": 1 }, { "advertiserId": 456, "category": "News", "domain": "example.com", "displays": 42, "clicks": 12, "salesPc30d":5, "salesPv1d": 1 }, { "advertiserId": 789, "category": "News", "domain": "example.com", "displays": 42,, "clicks": 12, "salesPc30d":5, "salesPv1d": 1 } ] ``` **Limitations** * This reporting is on publisher categories only. * This display data is for the **web environment only** and does not support app display data. * URL domains that fall under the category "Unknown" do not fall into any category. * URL domains "Undisclosed" are not permitted to be displayed, and will appear as empty strings. * If a domain has no category, then number of displays will be reported in the "Unknown" category. Additionally, if a domain has less category hits than displays, we do not correct the number of hits, and report the missing displays in the "Unknown" category. ### Attributes

Field

Type

Required

Default Value

Description

startDate

DateTime

Yes

Start of the report in YY-MM-DD format

endDate

DateTime

Yes

End of the report in YY-MM-DD format

advertiserIds

string

Yes

Comma separated list of Advertiser IDs in an array

adsetId

string

No

null

Report only on the specified adset Id

category

string

No

Report only on the specified category

domain

string

No

Report only on the specified domain

shoudlDisplayDomainDimension

boolean

No

true

Specify if the domain dimension is displayed in the report

timezone

Timezone

No

UTC

Timezone used for dates

format

string

Yes

CSV

Format of the report: JSON, XML, CSV, XLS

*** ## **Errors and Warnings** API users must be authenticated in order to make calls to the category endpoint.\ For more information on authentication, see [our Authentication guide](/marketing-solutions/docs/authentication). ### Insufficient Permission ```json JSON theme={null} "errors": [{ "traceId": "56ed4096-f96a-4944-8881-05468efe0ec9", "type": "access-control", "code": "insufficient-advertiser-permissions", "instance": "/advertisers/placements/report", "title": "Insufficient advertisers permissions", "detail": "You do not have the rights to report on these advertisers.", }] ``` ### Missing Required Fields There are 4 required fields when making a call: `startDate`, `endDate`, `advertiserIds`, and `format`. ```json JSON theme={null} "errors": [{ "traceId": "56ed4096-f96a-4944-8881-05468efe0ec9", "type": "validation", "code": "required-field", "instance": "/advertisers/placements/report", "title": " is required.", }] ``` ### Invalid Format Format must be in CSV, XML, XLS, or JSON. ```json JSON theme={null} "errors": [{ "traceId": "56ed4096-f96a-4944-8881-05468efe0ec9", "type": "validation", "code": "invalid-format", "instance": "/advertisers/placements/report", "title": " must be in list of required values", "detail": " must be one of 'csv', 'xml', 'excel' or 'json'. Value: ''." , }] ``` ### Invalid Date Range  Date ranges are required and must have a valid start and end date. ```json JSON theme={null} "errors": [{ "traceId": "56ed4096-f96a-4944-8881-05468efe0ec9", "type": "validation", "code": "invalid-date-range", "instance": "/advertisers/placements/report", "title": "Invalid date range", "detail": "The 'startDate' can not be after 'endDate'.", }] ``` ### Invalid Time Zone  The default time zone for requests is UTC. See [this page](/marketing-solutions/docs/campaign-statistics#timezones) for more information on supported time zones. ```json JSON theme={null} "errors": [{ "traceId": "56ed4096-f96a-4944-8881-05468efe0ec9", "type": "validation", "code": "invalid-timezone", "instance": "/advertisers/placements/report", "title": "Invalid time zone", "detail": "Time zone '' is not valid.", }] ``` # Product Boost Source: https://developers.criteo.com/marketing-solutions/docs/product-boost ## Introduction Product Boost allows advertisers to amplify the visibility of specific product sets within an ad by applying a **boosting factor**. When configured, products belonging to the specified product set are weighted more heavily in the ad's delivery logic relative to unboosted products. Advertisers managing large catalogs can use Product Boost to surface priority products (e.g. seasonal items, high-margin SKUs, promoted lines) without creating separate ads. It provides a lightweight configuration layer on top of an existing ad, scoped to a product set. **Prerequisites:** * A valid Marketing Solutions ad ID (`ad-id`) — the ad must already exist * A valid product set ID (`product-set-id`) linked to a dataset associated with the ad * OAuth 2.0 Bearer token with scope `MarketingSolutions_Reco_Read` (read endpoints) or `MarketingSolutions_Reco_Manage` (POST and DELETE) **Key concepts:** * **Product set** — a curated subset of products from a catalog dataset, identified by `productSetId` * **Boosting factor** — a numeric multiplier applied to products in the set during ad serving; a value of `1` means no boost, values above `1` increase priority * **Dataset** — the catalog data source referenced by the ad; the dataset-level GET endpoint lets you inspect all boost configurations across a dataset regardless of which ad they belong to **Upsert behavior** The POST endpoint creates the boosting configuration if none exists for the given `(ad-id, product-set-id)` pair, or replaces it entirely if one already exists. There is no PATCH — send the full desired configuration each time. *** ## Endpoints Overview | Verb | Endpoint | Description | | :--------- | :---------------------------------------------------------------- | :------------------------------------------------------------- | | **GET** | `/marketing-solutions/ads/{ad-id}/product-boost` | List all product boost configurations for an ad | | **GET** | `/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id}` | Get the product boost configuration for a specific product set | | **POST** | `/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id}` | Create or replace a product boost configuration | | **DELETE** | `/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id}` | Delete a product boost configuration | | **GET** | `/marketing-solutions/dataset/{dataset-id}/product-boost` | List all product boost configurations for a dataset | *** ## Attributes Resource type: `BoostedAdProductSet` | Attribute | Data Type | Description | | ------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `adId` | string | ID of the Marketing Solutions ad this configuration belongs to.

**Accepted values:** string of int64 / **Writeable?** N / **Nullable?** N | | `productSetId` | string | ID of the product set being boosted within the ad.

**Accepted values:** string of int64 / **Writeable?** N / **Nullable?** N | | `boostingFactor`\* | number (double) | Multiplier applied to products in the set during ad serving. A value of `1` means no boost.

**Accepted values:** positive float / **Writeable?** Y / **Nullable?** N | | `modificationDate` | string | Datetime of the last modification to this configuration.

**Accepted values:** datetime string / **Writeable?** N / **Nullable?** N | *\*Required at create/update operation* *** ## List all product boost configurations for an ad Returns all `BoostedAdProductSet` entries associated with the given ad. ```http theme={null} https://api.criteo.com/2026-07/marketing-solutions/ads/{ad-id}/product-boost ``` **Sample request** ```curl theme={null} curl -L -X GET 'https://api.criteo.com/2026-07/marketing-solutions/ads/1234567890/product-boost' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample response** ```json theme={null} { "data": [ { "type": "BoostedAdProductSet", "attributes": { "adId": "1234567890", "productSetId": "9876543210", "boostingFactor": 1.5, "modificationDate": "2026-07-21T10:30:00Z" } }, { "type": "BoostedAdProductSet", "attributes": { "adId": "1234567890", "productSetId": "1122334455", "boostingFactor": 2.0, "modificationDate": "2026-07-15T08:00:00Z" } } ] } ``` *** ## Get a product boost configuration Returns the `BoostedAdProductSet` for the given `(ad-id, product-set-id)` pair. ```http theme={null} https://api.criteo.com/2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} ``` **Sample request** ```curl theme={null} curl -L -X GET 'https://api.criteo.com/2026-07/marketing-solutions/ads/1234567890/product-boost/9876543210' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample response** ```json theme={null} { "data": { "type": "BoostedAdProductSet", "attributes": { "adId": "1234567890", "productSetId": "9876543210", "boostingFactor": 1.5, "modificationDate": "2026-07-21T10:30:00Z" } } } ``` *** ## Create or replace a product boost configuration Creates a new boosting configuration for the given `(ad-id, product-set-id)` pair. If a configuration already exists, it is fully replaced. Returns `201` on creation, `200` on update. ```http theme={null} https://api.criteo.com/2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} ``` **Sample request** ```curl theme={null} curl -L -X POST 'https://api.criteo.com/2026-07/marketing-solutions/ads/1234567890/product-boost/9876543210' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' \ -d '{ "data": { "type": "BoostingConfigurationRequest", "attributes": { "boostingFactor": 1.5 } } }' ``` **Sample response** ```json theme={null} { "data": { "type": "BoostedAdProductSet", "attributes": { "adId": "1234567890", "productSetId": "9876543210", "boostingFactor": 1.5, "modificationDate": "2026-08-01T14:22:00Z" } } } ``` *** ## Delete a product boost configuration Removes the boosting configuration for the given `(ad-id, product-set-id)` pair. Products in the set will no longer receive any boost. The ad itself and the product set remain unaffected. Returns the deleted resource in the response body. ```http theme={null} https://api.criteo.com/2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} ``` **Sample request** ```curl theme={null} curl -L -X DELETE 'https://api.criteo.com/2026-07/marketing-solutions/ads/1234567890/product-boost/9876543210' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample response** ```json theme={null} { "data": { "type": "BoostedAdProductSet", "attributes": { "adId": "1234567890", "productSetId": "9876543210", "boostingFactor": 1.5, "modificationDate": "2026-08-01T14:22:00Z" } } } ``` *** ## List product boost configurations for a dataset Returns all `BoostedAdProductSet` configurations associated with the given dataset, across all ads. Optionally filter by `client-type`. ```http theme={null} https://api.criteo.com/2026-07/marketing-solutions/dataset/{dataset-id}/product-boost ``` **Query parameters** | Parameter | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------- | | `client-type` | string | No | Filter results by client type. Accepted values: `Unknown`, `CGrowth`, `CMax`. Returns all configurations if omitted. | **Sample request** ```curl theme={null} curl -L -X GET 'https://api.criteo.com/2026-07/marketing-solutions/dataset/5544332211/product-boost?client-type=CMax' \ -H 'Accept: application/json' \ -H 'Authorization: Bearer ' ``` **Sample response** ```json theme={null} { "data": [ { "type": "BoostedAdProductSet", "attributes": { "adId": "1234567890", "productSetId": "9876543210", "boostingFactor": 1.5, "modificationDate": "2026-07-21T10:30:00Z" } }, { "type": "BoostedAdProductSet", "attributes": { "adId": "1234567891", "productSetId": "9876543211", "boostingFactor": 3.0, "modificationDate": "2026-07-28T09:15:00Z" } } ] } ``` *** ## Responses | Response | Title | Detail | Troubleshooting | | -------- | ------------ | -------------------------------------------- | ----------------------------------------------------------------------------------- | | 🟢 `200` | OK | | Request executed successfully; response body contains the resource | | 🟢 `201` | Created | | POST executed successfully — new boosting configuration created | | 🔴 `400` | Bad Request | `boostingFactor` must be greater than 0 | Review the value of `boostingFactor` in the request body | | 🔴 `401` | Unauthorized | Missing or invalid Bearer token | Verify that the Authorization header contains a valid, non-expired access token | | 🔴 `403` | Forbidden | Caller does not have access to this resource | Check that the token scope is `MarketingSolutions_Reco_Manage` for write operations | | 🔴 `404` | Not Found | Ad or product set ID does not exist | Verify that `ad-id` and `product-set-id` exist and are accessible to the caller | # Product Sets Source: https://developers.criteo.com/marketing-solutions/docs/product-sets ## Introduction A Product Set is a subset of the product catalog that can be featured in dynamic ads. Product Sets are created with a combination of rules using conditions on product attributes available in the Catalog. These conditions are additive (similar to the `AND` operator). Once created, you can apply a Product Set to an Ad as a filter. After doing this, the Ads will display only the products that belong to that Product Set. *** ## Product Set Properties  \ **`datasetId`**\ The ID of the Data Set to which the Product Set belongs **`name`**\ The name of the Product Set **`rules`**\ It's an array that encapsulates product rules. A **`Product rule`** is an object containing the following parameters: * **`operator`**: Operator to be used, from the table below. * **`field`**: Field to be filtered. * **`values`**: The values on which you want to apply the rule. *** ### Fields and Operators Not all Catalog fields can be used to create rules.\ If you need a specific field, you can map it in the Catalog to one of the Custom Label fields and later use it to create the rule.

Catalog Field Name

API Field Name

Operators Available

Category 1, Category 2, Category 3

category1 , category2 , category3

IsIn , IsNotIn

Brand

brand

IsIn , IsNotIn

Product ID

ExternalproductID

IsIn , IsNotIn

Custom Label 0, Custom Label 1, Custom Label 2 , Custom Label 3, Custom Label 4

CustomLabel0 , CustomLabel1 , CustomLabel2 , CustomLabel3 , CustomLabel4

IsIn , IsNotIn

Sale Price

SalePrice

Between , NotBetween , LessThan , GreaterThan

*** ## Create a Product Set A Product Set can be created for a specific advertiser by making a `POST` call to the Product-Set endpoint.\ The request body should specify the **Data Set Id**, the name of the Product Set, if it's a draft (optional), and the product rules. ```http theme={null} https://api.criteo.com/preview/product-sets ``` **Sample request** ```json JSON expandable theme={null} { "data": { "type": "CreateProductSetRequest", "attributes": { "datasetId": "782", "name": "Product set name", "isDraft": True, "rules": [ { "operator": "IsIn", "field": "Category1", "values": [ "Decoration", "Home", "Furniture" ] }, { "operator": "IsNotIn", "field": "Category2", "values": [ "Games", "Gastronomy" ] }, { "operator": "IsIn", "field": "Brand", "values": [ "ADIDAS PERFORMANCE", "TEDDY SMITH", "REDSKINS", "NATACHA B", "GALERIES LAFAYETTE" ] }, { "operator": "Between", "field": "SalePrice", "values": ["1.2", "645531.56"] }, { "operator": "LessThan", "field": "SalePrice", "values": ["645531.56"] }, { "operator": "GreaterThan", "field": "RetailPrice", "values": ["1.2"] }, { "operator": "IsNotIn", "field": "ExternalItemId", "values": ["552751852", "550853326"] }, { "operator": "IsNotIn", "field": "CustomLabel0", "values": ["552751852", "550853326"] } ] } } } ``` **Sample response** ```json JSON theme={null} { "data": { "attributes": { "datasetId": "string", "name": "string", "status": "Unknown", "isEnabled": true, "numberOfProducts": 0, "creationDate": "string", "rules": [ { "operator": "IsIn", "field": "Category1", "values": [ "string" ] } ], "id": "string" }, "id": "string", "type": "string" }, "warnings": [], "errors": [] } ``` *** ## Delete a Product Set  ```http theme={null} https://api.criteo.com/preview/product-sets/{productSetId} ``` A Product Set can be deleted for a specific advertiser by making a DELETE call to the product-sets endpoint. You need to specify the **`productSetId`** to delete in the request URL. ```json theme={null} { "warnings": [], "errors": [] } ``` *** ## Retrieve Product Set Data ### Retrieve Data for a specific Product Set You can get the information of a specific Product Set by making a GET call to the product-sets endpoint. You need to specify the **`productSetId`** to retrieve in the request URL. ```http theme={null} https://api.criteo.com/preview/product-sets/{productSetId} ``` **Sample response** ```json JSON theme={null} { "data": { "attributes": { "datasetId": "string", "name": "string", "status": "Unknown", "isEnabled": true, "numberOfProducts": 0, "creationDate": "string", "rules": [ { "operator": "IsIn", "field": "Category1", "values": [ "string" ] } ], "id": "string" }, "id": "string", "type": "string" }, "warnings": [], "errors": [] } ``` *** ### Retrieve Data for a Specific Data Set If you need to get all the Product Sets for a specific Data Set, you can make a GET call to the endpoint specifying the relevant **`datasetId`** ```http theme={null} https://api.criteo.com/preview/product-sets/dataset/{datasetId} ``` **Sample response** ```json JSON theme={null} { "data": [ { "attributes": { "datasetId": "string", "name": "string", "status": "Unknown", "isEnabled": true, "numberOfProducts": 0, "creationDate": "string", "rules": [ { "operator": "IsIn", "field": "Category1", "values": [ "string" ] } ], "id": "string" }, "id": "string", "type": "string" } ], "warnings": [], "errors": [] } ``` *** ## Test Product Set rules Before creating a Product Set, you can check how many products would be part of a Product Set with a particular set of rules. Use this endpoint to get the number of products belonging to the Product Set and a small sample of the products. ```http theme={null} https://api.criteo.com/preview/product-sets/preview ``` **Sample request** ```json JSON theme={null} { "productSet": { "datasetId": "782", "rules": [ { "operator": "IsIn", "field": "Category1", "values": [ "Decoration", "Home", "Furniture" ] }, { "operator": "IsNotIn", "field": "Category2", "values": [ "Games", "Gastronomy" ] } ] }, "productSampleCount": 5 } ``` **Sample response** ```json JSON theme={null} { "data": { "productCount": 3940, "totalProductCount": 404202, "sampleProducts": [ "-9063027279849067663", "927588690310362953", "667545005484734956", "-6270815052645770065", "-9213562868104252217" ] }, "warnings": [] } ``` *** ## Associate a Product Set and an Ad Once a Product Set is created, it can be applied to an Ad as a filter. As a result, only products that belong to that Product Set are displayed in the Ad. ```http theme={null} https://api.criteo.com/preview/ads/{adId}/product-filter ``` **`adId`**\ Id of the Ad to that you want to link to the specified Product Set. An Ad can only have **one** Product Set assigned to it.\ A Product Set can be associated with zero or more Ads. **Sample request** ```json JSON theme={null} { "data": { "type": "CreateProductFilterRequest", "attributes": { "productSetId": product_set_id } } } ``` **Sample response** ```json JSON theme={null} { "data": { "type": "string", "attributes": { "adId": "string", "productSetId": "string" } }, "warnings": [], "errors": [] } ``` *** ## Remove a Product Set and Ad association  ```http theme={null} https://api.criteo.com/preview/ads/{adId}/product-filter ``` **`adId`**\ Id of the Ad you want to unlink from the Product Set. **Sample response** ```json JSON theme={null} { "warnings": [], "errors": [] } ``` *** ## Retrieve Associations Between Ads and Product Sets ### Retrieve Filtering Association Data for a Specific Ad Get the Product Set assigned to an Ad ```http theme={null} https://api.criteo.com/preview/ads/{adId}/product-filter ``` **`adId`**\ Id of the ad you want to look for. **Sample response** ```json JSON theme={null} { "data": { "type": "string", "attributes": { "adId": "string", "productSetId": "string" } }, "warnings": [], "errors": [] } ``` *** ### Retrieve Associations of a Specific Product Set By doing a `GET` call to this endpoint, you get the association information (ad id + product set id). ```http theme={null} https://api.criteo.com/preview/product-sets/{productSetId}/product-filters ``` **`productSetId`**\ Id of the Product Set **Sample response** ```json JSON theme={null} { "data": [ { "type": "string", "attributes": { "adId": "string", "productSetId": "string" } } ], "warnings": [], "errors": [] } ``` *** ## Validation errors **`invalid-productset-request`**\ The request contains an invalid Product Set ID **`invalid-productset-request`**\ Missing authorization to get Product Set for the specified Data Set, or if the Product Set does not exist. **`JSON_FORMAT`**\ There's a constraint not satisfied by the provided JSON. For example: “productSet.rules: The operator Between isn't compatible with the provided field" **`REQUIRED_FIELD`**\ The required field is missing. # Quick Start – Launch a Multi-Seller Campaign via MPO Source: https://developers.criteo.com/marketing-solutions/docs/quick-start-launch-a-multi-seller-campaign-via-mpo ## What you’ll accomplish In this guide, you will: * Take a set of existing marketplace sellers and activate them in an MPO Multi-Seller campaign. * Create seller-campaigns that link each seller to the shared campaign. * Set per-seller campaign bids (CPC) to control delivery. * Verify that the campaign is live by checking Multi-Seller statistics. This flow assumes you are using MPO in **Multi-Seller** mode (shared campaign for many sellers). If you need one dedicated campaign per seller, use the **Single-Seller Quick Start** instead. ## Who this recipe is for This recipe is intended for: * Marketplace integrators and technical leads wiring MPO into their own tools. * Developers who want a concrete, end-to-end example of enabling Multi-Seller via API. * Teams onboarding many long-tail or small-budget sellers into a shared MPO campaign. ## Prerequisites Before starting, make sure all of the following are true. ### Feature enablement & account setup * Your marketplace is onboarded to **Marketplace Performance Outcomes (MPO)**. * MPO in **Multi-Seller** mode is enabled for your partner / advertiser by Criteo (at the partner level). Work with your Criteo contact to confirm that: * **Marketplace Performance Outcomes (MPO)** is active for your partner, and * At least one **Multi-Seller MPO campaign** is configured for your advertiser, including: * Optimization goal and bidding strategy. * Targeting and creatives. ### API access & permissions * Your application is onboarded to **Criteo Marketing Solutions**. * You can obtain an **OAuth2 access token**. * For Multi-Seller usage, the application has at least: * **Campaign – Manage** permission on the relevant advertiser. Refer to the general **Onboarding Checklist** on the Developer Portal for full scope and token setup. ### Catalog & sellers * Your product catalog is integrated and includes **seller information** (for example a `seller_id` or equivalent field on products). * On the Criteo side, this seller field is **mapped and activated for MPO** so that: * Sellers can be ingested from the catalog, and * Exposed via the Sellers endpoints: ```http HTTP theme={null} GET /marketplace-performance-outcomes/sellers ``` * Sellers have already been ingested by MPO and exposed via the Sellers endpoint: ```http HTTP theme={null} GET /marketplace-performance-outcomes/sellers ``` You should be able to list sellers and see `sellerId` values for the merchants you want to activate. ## Step 1 – Discover sellers and confirm they’re available First, retrieve the list of sellers available to your MPO advertiser and confirm the sellers you want to activate in Multi-Seller are present. ### 1.1 List sellers **Endpoint** ```http HTTP theme={null} GET /marketplace-performance-outcomes/sellers ``` You can filter by `sellerName`, which typically corresponds to the seller identifier from your product data (for example, the `seller_id` you send in the catalog), or by advertiser if needed. ### Example – filter by sellerName ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/sellers? sellerName=YourSellerName Authorization: Bearer Accept: application/json ``` ### Sample response (simplified) ```json JSON theme={null} [ { "id": "42171358", "sellerName": "YourSellerName" } ] ``` * `id` is the `sellerId` you will use in the rest of the flow. * `sellerName` typically corresponds to the seller identifier coming from your product data (for example the `seller_id` or merchant ID you send in the catalog), so you can match MPO `sellerId` back to your own seller records. Repeat this for each seller you plan to include in the Multi-Seller campaign and store the mapping between your internal seller identifier and MPO `sellerId`. ## Step 2 – Link sellers to your Multi-Seller campaign (create seller-campaigns) A seller-campaign represents the relationship between: * A seller (`sellerId`), and * A Multi-Seller campaign (`campaignId`), including the bid and status for that seller in that campaign. In most setups: * The Multi-Seller campaign already exists (configured by Criteo). * Your job is to create or confirm the seller-campaigns for the sellers you want active. ### 2.1 Get the campaign ID Your Criteo contact will provide the Multi-Seller `campaignId` to use with MPO.\ Keep this value as `campaignId` in the following examples. ### 2.2 Create a seller-campaign for a seller You can create seller-campaigns for a seller via: ```http HTTP theme={null} POST https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/seller-campaigns Authorization: Bearer Content-Type: application/json Accept: application/json ``` ### Example request ```json JSON theme={null} { "campaignId": 123456, "bid": 1.20 } ```
* `campaignId` – the ID of your Multi-Seller MPO campaign. * `bid` – initial CPC bid for this seller in the campaign (in the campaign’s currency). ### Example response (simplified) ```json JSON theme={null} { "id": "42171358.123456", "sellerId": "42171358", "campaignId": 123456, "bid": 1.20, "suspendedSince": null, "suspensionReasons": [] } ```
* `id` is the `sellerCampaignId` (often a composite of seller and campaign). * A seller-campaign is active when: * `bid` is positive, and * `suspendedSince` is `null` (no active suspension reason). If your account already has seller-campaigns for a given seller and campaign, you can skip creation and move directly to updating bids (next step). ## Step 3 – Set or adjust bids for each seller-campaign Once the seller-campaign exists, you can update the CPC bid to control how aggressively that seller participates in the Multi-Seller campaign. ### 3.1 Retrieve the seller-campaign (optional) To confirm current configuration: ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId} Authorization: Bearer Accept: application/json ``` **Sample response:** ```json JSON theme={null} { "id": "42171358.123456", "sellerId": "42171358", "campaignId": 123456, "bid": 1.20, "suspendedSince": null, "suspensionReasons": [] } ``` ### 3.2 Update the bid To change the bid (for example, from `1.20` to `1.55`): ```http HTTP theme={null} PATCH https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId} Authorization: Bearer Content-Type: application/json Accept: application/json ``` **Request body** ```json JSON theme={null} { "bid": 1.55 } ``` **Guidelines:** * **Positive bid** → seller-campaign can be active (subject to budgets and other constraints). * **Bid = 0** → effectively pauses this seller in the campaign (no delivery for this seller). You can repeat this per seller-campaign to: * Boost high-value sellers. * Reduce exposure for low-performing sellers. * Pause a seller temporarily by setting `bid` to `0`. ## Step 4 – Ensure budgets are in place Multi-Seller campaigns require sufficient budget to deliver for all active sellers. There are two budget surfaces in MPO: 1. **Campaign-level or advertiser-level budgets** * Usually managed with your Criteo team or via generic Marketing Solutions budget APIs. * Ensure at least one active budget is configured for the MPO campaign. 2. **Seller-campaign budgets** (optional, for finer control) * Accessible via: ```http HTTP theme={null} GET /marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId}/budgets GET /marketplace-performance-outcomes/budgets POST /marketplace-performance-outcomes/budgets ``` * These can be used to set per-seller caps or schedule specific time windows. For a first Multi-Seller launch, it is often enough that: * The parent campaign budget is in place. * Your seller-campaign bids are positive. Work with your Criteo contact to decide whether you also need per-seller budgets at launch. ## Step 5 – Verify delivery with statistics Once: * Sellers are correctly ingested, * Seller-campaigns exist with positive bids, * Budgets are active, you can verify delivery via the **Standard Reporting API**. ### 5.1 Check campaign-level stats ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/campaigns?campaignId=123456&startDate=2026-03-01&endDate=2026-03-01 Authorization: Bearer Accept: application/json ``` **Typical response (simplified):** ```json JSON expandable theme={null} { "columns": [ "campaignId", "day", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [ "123456", "2026-03-01", 3969032, 13410, 1111.295, 985, 190758099, 0.073, 1.128, 0.0, 171653.88 ] ], "rows": 1 } ``` ### 5.2 Check per-seller performance Use seller or seller-campaign stats to confirm each seller is delivering: ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/sellers?campaignId=123456&startDate=2026-03-01&endDate=2026-03-01 Authorization: Bearer Accept: application/json ``` Or, for the most granular view: ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/seller-campaigns?campaignId=123456&sellerId=42171358&startDate=2026-03-01&endDate=2026-03-01 Authorization: Bearer Accept: application/json ``` These endpoints return impressions, clicks, cost, and conversion metrics that you can surface in your own BI tools or seller portal.


# Quick Start – Launch a Single-Seller Campaign via MPO Source: https://developers.criteo.com/marketing-solutions/docs/quick-start-launch-a-single-seller-campaign-via-mpo ## What you’ll accomplish In this recipe, you will: * Take a single seller from having **no Single-Seller campaign** to having a **live, dedicated Single-Seller campaign**. * Create the first **Single-Seller budget**, which: * Automatically creates the per-seller campaign for that seller and template (if it doesn’t exist yet). * Controls how much that seller can spend and over which dates. * Restrict products for that seller’s campaign using **`productSet`** (this is optional). * Verify the setup using both: * **Budgets** endpoints, to confirm configuration. * **Statistics** endpoints, to confirm the seller is delivering. This recipe assumes you already understand the high-level concepts in the
[Single-Seller Campaigns – Concept Guide](https://criteo.atlassian.net/wiki/display/~g.handley/Single-Seller+Campaigns+%E2%80%93+Concept+Guide). ## Who this recipe is for This flow is intended for sellers who are a good fit for Single-Seller, typically: * **Top or strategic sellers** who can meet the minimum Single-Seller budgets, and * Sellers with **enough eligible products** in their catalog to support stable delivery. Very small or long-tail sellers with very low daily budgets are usually better handled via **Multi-Seller campaigns**, not Single-Seller. ## Prerequisites Before you start, make sure all of the following are true. ### Feature enablement #### API access Marketplace Performance Outcomes uses the same Marketing Solutions Performance Media / Campaign endpoints as your other campaigns – there is no separate “MPO API” to activate. To call `/marketplace-performance-outcomes`, your application must: * Be onboarded to Marketing Solutions with the **Campaign** domain in its scope. * Have the **Campaign Manage** permission, as described in the [onboarding checklist](/marketing-solutions/docs/onboarding-checklist#3-define-your-app-scope). #### Single-Seller feature enablement Single-Seller campaigns must be enabled on your account. Confirm with your Criteo representative that: * Your advertiser is allowed to use **Single-Seller**. * At least one **Single-Seller template campaign** exists for you. If Single-Seller is not enabled, the calls in this recipe may return authorization or validation errors. ### Template configuration * You have a **Single-Seller template campaign ID** from Criteo: * This is often referred to as `templateCampaignId`. * You must use this ID as `campaignId` in **budget calls**. * You know the **minimum per-seller budget** for this template: * For example: a minimum total budget per period, or a minimum “equivalent daily” spend. ### Seller eligibility Single-Seller is designed for sellers who can sustain **meaningful, continuous delivery**. Before using this recipe for a seller, check that: * The seller can meet the **minimum daily budget** guidelines for Single-Seller. As a rule of thumb: * **Recommended**: around **US\$20/day** for ROAS/sales goals, or **US\$10/day** for click goals. * **Hard minimums**: **US\$10/day** (ROAS/sales) and **US\$5/day** (click). * The seller is **not** a pure long-tail seller with very small or sporadic budgets. * Long-tail sellers are usually better suited to **Multi-Seller pooled campaigns**. * If you plan to use `productSet` for this seller: * The seller has at least **\~20 in-stock products** mapped correctly in the catalog. * This helps avoid **under-delivery** and `productSet` **validation errors**. ### Catalog and sellers * Your product catalog is integrated and includes `sellerName` on relevant products. * The MPO Sellers endpoints return sellers: * You can call `/marketplace-performance-outcomes/sellers` and see your sellers. * Each seller you want to onboard to Single-Seller has a corresponding `sellerId`. ### API access & permissions You have valid OAuth 2.0 client credentials and can obtain a Bearer token. Unlike Multi-Seller (which only requires Campaign Manage), Single-Seller requires broader access because creating a seller's first budget triggers an automatic sync of audience, creative, and product-set configuration from the parent template ad set to the newly created child (seller) ad set. Your OAuth token must include the following permissions for the advertiser portfolios used in this recipe: * **Campaigns: Manage** * **Audiences: Manage** * **Creatives: Manage** * **Catalog: Manage** * **Product Recommendation: Manage** * **Analytics: Read** With these permissions, your app can read the required entities (including sellers), create and update budgets, and call the reporting endpoints used in this workflow. If any of the Manage permissions above are missing, the first budget-creation call for a seller can fail because the API cannot read the parent ad set's audience/creative/productSet configuration to apply it to the new child ad set. This can currently return a `500` error even though the request itself is valid. Missing permissions won't necessarily fail every call: once a seller's child ad set already exists, subsequent budget calls for that seller reuse it and do not require re-syncing this configuration. You will need (for this recipe): * `advertiserId` * `templateCampaignId` (Single-Seller template campaign ID) * `sellerId` (you will retrieve this in Step 1) * Minimum per-seller budget for this template (from Criteo) **Estimated time:** \~30–60 minutes if all of the above are ready. ## Step 1 – Get the `sellerId` Use the MPO Sellers endpoint to find the internal `sellerId` for the seller. Example (filter by `sellerName`): **Endpoint** ```http theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/sellers?sellerName={YourSellerName} Authorization: Bearer Accept: application/json ``` **Sample response (simplified):** ```json JSON theme={null} [ { "id": "123", "sellerName": "YourSellerName" } ] ``` * `id` is the `sellerId` to use in later calls. * Store `sellerId` in your own system. ## Step 2 – Create the first Single-Seller budget The first valid budget for (`sellerId`, `templateCampaignId`): * Creates the underlying **Single-Seller campaign** (if it doesn’t exist). * Defines **how much** the seller can spend and **over which period**. ### Build the budget request **Endpoint** ```http HTTP theme={null} POST https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets Authorization: Bearer Content-Type: application/json Accept: application/json ``` **Request body** ```json JSON theme={null} { "campaignIds": ["456"], "sellerId": "123", "startDate": "2026-04-16", "endDate": "2026-04-30", "budgetType": "Capped", "amount": "1200" } ] ``` **Guidelines:** * `campaignIds` must contain **exactly one ID**: your Single-Seller `templateCampaignId`. * `amount` must be more: the per-seller minimum by the number of days. * `startDate` and `endDate`: * Must form a valid range (`startDate <= endDate`). * Must not overlap any other budget for the same (`sellerId`, `templateCampaignId`). ### Interpret the response A successful response returns: * A generated `budgetId`. * The budget fields (dates, `amount`, `isSuspended`, status). Once accepted: * Criteo creates the **Single-Seller campaign** for (`sellerId`, `templateCampaignId`) if needed. * Expect a short **provisioning delay** before impressions appear. Store: * `budgetId` for future updates and troubleshooting. * Mapping between `sellerId`, `templateCampaignId`, and budget(s). ## Step 3 – Restrict products with `productSet` (Optional) If you want this seller’s campaign to only advertise specific SKUs, attach a `productSet`. ### Get the seller-campaign ID **Endpoint** ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns?sellerId=123&campaignId=456 Authorization: Bearer Accept: application/json ``` **Sample response (fragment):** ```json JSON theme={null} [ { "id": "SELLER_123.TEMPLATE_CAMPAIGN_456", "sellerId": "123", "campaignId": "456", "productSet": null } ] ``` * `id` is the **seller-campaign identifier** you’ll use when updating `productSet`. ### Attach a `productSet` **Endpoint** ```http HTTP theme={null} PATCH https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/seller-campaigns Authorization: Bearer Content-Type: application/json Accept: application/json ``` **Example request body** ```json JSON theme={null} [ { "id": "SELLER_123.TEMPLATE_CAMPAIGN_456", "productSet": { "value": [ { "operator": "IsIn", "field": "ExternalItemId", "values": [ "SKU_001", "SKU_002", "SKU_003", "SKU_004" ] } ] } } ] ``` **Behavior:** * Creates a `productSet` if none exists. * Replaces the existing rule if one exists. * Only products with `ExternalItemId` in `values` are eligible. **Constraints:** * `operator`: `IsIn` or `IsNotIn`. * `field`: `ExternalItemId`. * Advertiser-specific **minimum number of product IDs** may apply. ### Remove the filter later **Request body** ```json JSON theme={null} { "productSet": { "value": null } } ``` ## Step 4 – Verify budgets and monitor performance ### List budgets for this seller/template **Endpoint** ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets?sellerId=123&campaignId=456 Authorization: Bearer Accept: application/json ``` ### Get a specific budget **Endpoint** ```http HTTP theme={null} GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Authorization: Bearer Accept: application/json ``` **Check:** * Dates and `amount` match expectations. * `isSuspended` is `false` for active budgets. * No overlapping periods for the same (`sellerId`, `templateCampaignId`). ### Monitor performance Use stats endpoints such as: ```http HTTP theme={null} GET /marketplace-performance-outcomes/stats/campaigns GET /marketplace-performance-outcomes/stats/sellers GET /marketplace-performance-outcomes/stats/seller-campaigns ``` Combine: * `sellerId` * `templateCampaignId` * `sellerCampaignId` to build dashboards and automated checks. ## Step 5 – Common next actions **Scale to more sellers:** * Repeat Steps 1–2 for each new seller. * Optionally configure `productSet` per seller. **Adjust spend mid-flight:** * `PATCH` budgets to change `amount` or `endDate`. * Always avoid **overlapping periods**. **Pause or resume a seller:** * **Pause**: set `isSuspended = true` on the active budget. * **Resume**: set `isSuspended = false` on a valid active/future budget. For more details, refer to: * [Single-Seller Campaigns – Concept Guide](https://criteo.atlassian.net/wiki/display/~g.handley/Single-Seller+Campaigns+%E2%80%93+Concept+Guide) * [Single-Seller API Reference](/marketing-solutions/docs/single-seller-campaigns#/versions) # Reporting Source: https://developers.criteo.com/marketing-solutions/docs/reporting ## Introduction This article is the entry point for MPO reporting. It explains: * What types of reporting MPO supports. * When to use the [Standard Reporting API](/marketing-solutions/docs/mpo-standard-reporting-api) vs. the [Real-Time Asynchronous API](/marketing-solutions/docs/getting-realtime-mpo-statistics). * How to think about **identifiers** (`seller`, `campaign`, `seller-campaign`) and **time grains**. * Typical integration patterns for marketplaces. You can find more information about each API in the following pages: * [**MPO Standard Reporting API**](/marketing-solutions/docs/mpo-standard-reporting-api) for aggregated, historical statistics. * [**MPO Real-Time Asynchronous API**](/marketing-solutions/docs/getting-realtime-mpo-statistics) for low-latency, asynchronous exports for operational monitoring. *** ## 1. Reporting Building Blocks MPO exposes a consistent set of concepts across both **Multi-Seller** and **Single-Seller** setups. ### 1.1 Core identifiers You will mainly work with: * `sellerId` – marketplace seller (independent of campaign model). * `campaignId` – MPO campaign (shared Multi-Seller campaign or Single-Seller template campaign). * (`sellerId`, `campaignId`) pairs – the **seller-campaign** view. These map to three standard stats endpoints: * `/stats/sellers` – one row per seller per interval. * `/stats/campaigns` – one row per campaign per interval. * `/stats/seller-campaigns` – one row per (campaign, seller) per interval. ### 1.2 Core metrics All MPO stats endpoints share the same metric vocabulary: * **Volume:** `impressions`, `clicks` * **Spend & revenue:** `cost`, `saleUnits`, `revenue` * **Efficiency:** `cr`, `cpo`, `cos`, `roas` Metrics are defined identically for **Multi-Seller** and **Single-Seller**; only the **aggregation key** (seller, campaign, seller-campaign) changes. ### 1.3 Aggregation interval Both reporting APIs let you choose the **time grain**, for example: * `Hour` – for short-window analysis. * `Day` – standard granularity for dashboards and exports. * `Month` / `Year` – long-term trend and finance views. Exact options and range limits depend on the endpoint and environment (see individual API pages). *** ## 2. Choosing between Standard and Real-Time reporting MPO offers two complementary reporting paths: * **Standard Reporting API** – aggregated, post-processed statistics. * **Real-Time Asynchronous API** – near real-time, asynchronous exports. ### 2.1 High-level comparison ### 2.2 When to use which Use the **Standard Reporting API** when you need: * Aggregated metrics over longer periods (for example, **last 30 days**, **last quarter**). * Stable data for **billing**, **margin analysis**, and **long-term trends**. * Scheduled **batch exports** into your own reporting stack. Use the **Real-Time Asynchronous API** when you need: * Short-window metrics for **live monitoring** (for example, last 60–120 minutes). * Visibility right after **budget changes**, **campaign launches**, or **template updates**. * Near real-time dashboards and alerts for operations teams. Most integrations rely on both data types: * **Real-Time** endpoints for monitoring current system behavior, * **Standard** endpoints for aggregated reporting and revenue analysis over defined time periods. *** ## 3. How Multi-Seller and Single-Seller reporting fit together The **reporting surface is shared** across Multi-Seller and Single-Seller: * **Same endpoints** – `/stats/sellers`, `/stats/campaigns`, `/stats/seller-campaigns`. * **Same metrics** – `impressions`, `clicks`, `cost`, `saleUnits`, `revenue`, `cr`, `cpo`, `cos`, `roas`. * **Different interpretation of IDs:** * **Multi-Seller:** * `campaignId` → shared MPO campaign across many sellers. * `sellerId` → marketplace seller within that pooled campaign. * **Single-Seller:** * `campaignId` → usually the template campaign ID. * `sellerId` → remains the primary key for seller-level performance. * In some APIs you also see a dedicated `sellerCampaignId` that identifies the per-seller instance. From a reporting perspective: * Use **Seller Stats** when your question is *“How is this seller performing overall?”* * Use **Campaign Stats** when your question is *“How is this MPO campaign or template performing?”* * Use **Seller-Campaign Stats** when your question is *“How is this seller performing inside this campaign?”* *** ## 4. Click Attribution Policy For derived metrics (`saleUnits`, `revenue`, `cr`, `cpo`, `cos`, `roas`), you can control how sales are attributed to clicks using `clickAttributionPolicy`: * `SameSeller` – only count sales where the purchased product’s seller matches the seller that was clicked. * `AnySeller` – count sales that follow a click on **any** seller’s product (cross-seller attribution). * `Both` – return both perspectives where supported. This policy is available across the **Standard Reporting API** endpoints. Use it to align MPO reporting with your internal business rules for marketplace attribution. *** ## 5. Typical integration patterns ### 5.1 Daily batch export for BI and finance * Once per day (or more), call **Seller Stats** and **Campaign Stats** from the **Standard Reporting API** for the previous day. * Load results into your **data warehouse** and join with internal catalog and seller metadata. * Use this layer for: * Finance and invoicing. * Marketplace P\&L and margin analysis. * Executive dashboards and long-term trend analysis. ### 5.2 Seller-facing reporting * Use **Seller Stats** and, when needed, **Seller-Campaign Stats** (Standard Reporting). * Filter by `sellerId` and aggregate over windows such as **last 7 days** or **last 30 days**. * Surface these metrics in your **seller portal**, aligned with internal KPIs (GMV, ROAS, spend caps, etc.). ### 5.3 Operational monitoring and diagnostics Combine both reporting paths: * Use the **Real-Time Asynchronous API** to: * Confirm **today’s** changes (new budgets, `productSet` updates, activations) start generating clicks and spend within minutes. * Power live **NOC-style dashboards** and alerts. * Use **Seller-Campaign Stats** (Standard Reporting) to: * Drill into **under-performing sellers** within a campaign. * Compare sellers before and after configuration changes. * Understand whether issues are campaign-wide or isolated to specific sellers.
## What's next * [MPO Real-Time Asynchronous API](/marketing-solutions/docs/getting-realtime-mpo-statistics) * [MPO Standard Reporting API](/marketing-solutions/docs/mpo-standard-reporting-api) # Single-Seller Source: https://developers.criteo.com/marketing-solutions/docs/singleseller Start by exploring the campaign-related concepts. Learn how to quick start by launching a Single-Seller Campaign via MPO. Explore the endpoints for seller management via API. Explore the endpoints allowing to manage campaigns. Explore the programmatic ways to manage budgets. Learn more about MPO Singleseller statistics. # Transaction IDs Source: https://developers.criteo.com/marketing-solutions/docs/transaction-ids The transaction ID report lets you retrieve the same transaction-level data available in Criteo's Marketing UI — across a given time period, for selected or all advertisers in your portfolio, or for specific transaction IDs. The `startDate`, `endDate`, `timezone`, and `currency` fields are required. One or more `advertiserIds` can be requested; if none are specified, all advertisers in your portfolio are included. If `format` is not specified, the report defaults to CSV. ## Report metrics The following metrics and dimensions are returned in the report: | Field | Type | Description | | ------------------------ | -------- | --------------------------------------------------------------- | | `AdvertiserId` | ID | ID of the advertiser | | `TransactionId` | ID | ID of the transaction | | `TransactionDate` | DateTime | Date of the transaction | | `AdsetName` | string | Name of the adset | | `AdvertiserName` | string | Name of the advertiser | | `EventType` | string | Type of event associated to the transactions (click or display) | | `EventDate` | DateTime | Date of the event | | `AttributedTransaction` | boolean | Transaction attributed to the click or display or not | | `Currency` | string | Transaction currency | | `Amount` | double | Transaction amount | | `CrossDeviceTransaction` | string | X-device or same device transaction | # Troubleshooting & FAQ Source: https://developers.criteo.com/marketing-solutions/docs/troubleshooting-faq ## General As a general rule: * `4xx` errors indicate an input or business logic issue. Read the error payload carefully — it will contain field-level detail to help you correct the request before retrying. * `500` and `503` errors are typically caused by a temporary network or service issue. Implement an exponential backoff policy: wait 10 seconds before the first retry, 20 seconds before the second, 40 seconds before the third, and so on. The API accepts up to **2,000 budget objects per call** with no defined maximum payload size. Partial failure is not supported at the request level. However, if a call fails, the error response will include detail records identifying which items caused the failure, so you can correct and resubmit. Check the `suspendedSince` and `suspensionReasons` fields on the seller-campaign: * If `suspendedSince` is `null` and `suspensionReasons` is empty, the campaign appears active to the API. If it is still not delivering, check that the template campaign is active and the budget meets the minimum per-seller threshold. * If `suspensionReasons` contains a value, see the table below.

Reason

Meaning

Action

ManuallyStopped

Budget manually suspended

Resume via budget PATCH

NoBudgetDefined

No active budget exists

Create a valid budget

NoCpcDefined

No CPC set

Set a CPC bid

NoMoreBudget

Budget fully spent

Create a new budget for a future period

RemovedFromCatalog

All products removed

Restore products in the catalog

NotYetStarted

Newly created, not yet processed

Wait for provisioning

NoMoreDailyBudget

Daily spend limit reached

No action needed; resets the next day

Other

Internal error

Contact Criteo Product or R\&D

Note that bulk endpoints do not always return HTTP `200`. Authorization and validation errors are returned with their appropriate status codes. For example, an invalid seller-campaign mapping returns a `403`: ```json JSON theme={null} [ { "detail": "Seller-campaign mappings are invalid. Invalid seller-campaigns: (campaign: 562108, seller: 1111)", "status": 403, "source": { "body": "" } } ] ```
In the most common scenario, sellers are added automatically from the catalog you have provided to Criteo. You must include the seller identifier in the `seller_id` field of each product in your catalog feed. The value is case-sensitive. Once the catalog is imported, it typically takes **3–4 hours** for sellers to appear in the system.
## Sellers Use the sellers endpoint with a name filter: ```http HTTP theme={null} GET /marketplace-performance-outcomes/sellers?sellerName=YourSellerName ``` ## Campaigns A campaign (also referred to as an ad set in Commerce Growth) is the top-level configuration managed by Criteo. You do not create or modify it directly via the MPO API. A seller-campaign is automatically created for each seller when the seller is set up. For example, if there are two MPO campaigns (one for web and one for app), two seller-campaigns will be created per seller by default. Seller-campaigns are the entities you manage via the API bids, and run state. Campaign IDs are assigned and managed by Criteo. You can obtain the campaign ID: * Directly from your Criteo point of contact. * Via the `GET /marketplace-performance-outcomes/campaigns` endpoint. There is no single flag that starts or stops a seller-campaign. A seller-campaign becomes active when it meets a set of conditions — including having a valid budget, a CPC bid, and active products in the catalog. See [Managing Campaigns](/marketing-solutions/docs/multiseller-managing-campaigns) for the full list of conditions. :llmCitationRef\[0] To stop a seller-campaign, set the budget to `isSuspended: true` via: ```http HTTP theme={null} PATCH /marketplace-performance-outcomes/budgets ``` This can happen when the suspension reason is not yet surfaced by the API. Common causes include: * The daily budget has been exhausted (`NoMoreDailyBudget`). * An internal system issue is preventing delivery (`Other`). Check the `suspendedSince` and `suspensionReasons` fields when retrieving a seller-campaign. If both are `null`, the campaign appears active. If `suspendedSince` is set, the campaign is inactive — check `suspensionReasons` for details. :llmCitationRef\[1] ## Budgets There is no dedicated endpoint for remaining budget. Calculate it usin ```text theme={null} remaining budget = amount − spend ``` Both `amount` and `spend` are available from: * `GET /marketplace-performance-outcomes/budgets` * `GET /marketplace-performance-outcomes/budgets/{budgetId}` No. For a given (`sellerId`, `campaignId`) pair, budget periods must not overlap. If you need to extend a period, update the existing budget. If you need to replace it, create a new one with non-overlapping dates. **Important distinction:** * Past or expired budgets do not block new budgets for the same date range. * Suspended budgets are not treated as canceled; they can be reactivated. A suspended budget still occupies its date range and will block a new budget for overlapping dates. If you need to free up a date range currently held by a suspended budget, you must delete or expire the suspended budget before creating a new one for that period. Yes. You can create budgets with future `startDate` values as long as their date ranges do not overlap with any existing active budgets for the same (`sellerId`, `campaignId`) pair. ## Statistics Yes. While statistics data defaults to UTC, the Stats API supports a `timezone` parameter so you can retrieve data in your preferred local time zone directly. Statistics are typically available with a latency of a few hours. Exact latency may vary; refer to the [Getting Statistics](/marketing-solutions/docs/multiseller-getting-statistics) page for current SLA guidance. :llmCitationRef\[2]
# Troubleshooting & FAQ Source: https://developers.criteo.com/marketing-solutions/docs/troubleshooting-faq-1 For common questions between Single-seller and Multi-seller documentation, refer to the [shared documentation](/marketing-solutions/docs/troubleshooting-faq). ## Campaigns A Single-Seller campaign (identified by `sellerCampaignId`) is a per-seller campaign derived from a template campaign configured by Criteo. You do not create it directly via the API. Instead, Criteo automatically creates the campaign when the first valid budget is submitted for a (`sellerId`, `templateCampaignId`). After the first budget is accepted, allow for a short asynchronous provisioning delay before impressions begin. A template campaign is a non-delivering campaign configuration managed by Criteo. It acts as the blueprint used to generate Single-Seller campaigns. The template defines settings such as: * optimization goal * bidding strategy * audiences * creatives * delivery configuration Template campaigns cannot be created via the API. The `templateCampaignId` is provided to you directly by Criteo when your Single-Seller template is configured. It is not retrievable via a self-serve API endpoint. | Entity | Who creates it | What it does | | -------- | -------------- | --------------------------------------------------------------------------------- | | Campaign | Criteo | Top-level ad configuration; not managed via MPO API | | | Criteo | Single-Seller blueprint; defines shared settings for all derived seller-campaigns | | | | | You do not pause seller-campaigns directly. Instead, suspend or resume the associated budget. **Pause:** ```http HTTP theme={null} PATCH /marketplace-performance-outcomes/budgets { "budgetId": "789", "isSuspended": true } ``` **Resume:** ```http HTTP theme={null} PATCH /marketplace-performance-outcomes/budgets { "budgetId": "789", "isSuspended": false } ``` If the budget's `endDate` is in the past, resuming will not restart delivery. Create a new budget with a future period instead. Check the `suspendedSince` and `suspensionReasons` fields on the seller-campaign. If `suspendedSince` is `null` and `suspensionReasons` is null, the campaign appears active to the API but may still not be delivering. Check that the template campaign is active and the budget meets the minimum per-seller threshold. If `suspensionReasons` contains a value, refer to the table below: | Reason | Meaning | Action | | ------ | -------------------------------- | --------------------------------------- | | | Budget manually suspended | | | | No active budget exists | Create a valid budget | | | Budget fully spent | Create a new budget for a future period | | | All products removed | Restore products in the catalog | | | Newly created, not yet processed | Wait for provisioning | | | Daily spend limit reached | No action needed; resets the next day | | | Internal error | Contact Criteo Product or R\&D | `Other` indicates that an internal issue is preventing the campaign from delivering, for example, a click spike prevention mechanism. This is not a client-side configuration error and cannot be resolved through API calls alone. Surface this to your operations team and notify your Criteo Product or R\&D contact for investigation. Yes. Use the `productSet` feature to attach a whitelist of product IDs (by `ExternalItemId`) to a seller-campaign: ```http theme={null} PATCH /marketplace-performance-outcomes/seller-campaigns [{ "id": "SELLER_123.TEMPLATE_CAMPAIGN_456", "productSet": { "value": [{ "operator": "IsIn", "field": "ExternalItemId", "values": ["SKU_1", "SKU_2"] }] } }] ``` **Notes:** * `productSet` is optional; without one, all eligible products from the seller's catalog are used. * A minimum number of product IDs is required per `productSet` (default: 20). Providing fewer will return a `4xx` error. * `productSet` is only supported on Single-Seller campaigns. It cannot be used on multi-seller campaigns. * To remove the `productSet` and revert to all eligible products, set `productSet.value` to `null`. This is usually a permissions issue, not a server bug. Creating a seller's first budget triggers an automatic sync of the parent template ad set's audience, creative, and productSet configuration to the newly created child (seller-specific) ad set. If your app's OAuth token is missing **Manage** rights on **Audiences**, **Creatives**, **Catalog**, or **Product Recommendation**, this sync fails. Check that your app has been granted: * Campaigns: Manage * Audiences: Manage * Creatives: Manage * Catalog: Manage * Product Recommendation: Manage * Analytics: Read If a seller's child ad set already exists, calls can succeed even with missing permissions, since no new sync is needed. This is why the error can appear intermittent across an organization with multiple apps/AppIds that have different permission grants. ## Budgets Only capped total budgets over a fixed date range are supported. Daily and uncapped budget types are not available in Single-Seller mode. If your use case requires always-on or short-duration delivery, the following patterns are supported as workarounds: **Always-on delivery**
Schedule a sequence of consecutive, non-overlapping capped budgets — for example, monthly budgets submitted in advance. Each budget covers a fixed period and the next begins where the previous ends. **Short-duration budgets**
Submit individual capped budgets for the desired interval (daily, weekly, or monthly). Each must be a separate non-overlapping request for the same (`sellerId`, `templateCampaignId`) pair.
Daily pacing is automatic. The system distributes the total budget evenly across the budget period, computing a daily target. Under-delivery or over-delivery on a given day is compensated across the remaining days, as long as the budget period is active. There is no dedicated endpoint for remaining budget. Calculate it using: ```text theme={null} remaining budget = amount − spend ``` Both `amount` and `spend` are available from: * `GET /marketplace-performance-outcomes/budgets` * `GET /marketplace-performance-outcomes/budgets/{budgetId}` No. For a given (`sellerId`, `templateCampaignId`) pair, budget periods must not overlap. Suspended budgets are treated as logically canceled and do not block new budgets for the same dates. Yes. You can create budgets with future `startDate` values as long as their date ranges do not overlap with any existing active budgets for the same (`sellerId`, `templateCampaignId`) pair. The minimum budget amount for a given period is: ```text theme={null} minimum amount = minimum daily budget per seller (provided by Criteo) × number of days in the period ``` If the amount is below this threshold, the API will return a `4xx` error. Check that your app has Manage rights for Audiences, Creatives, and Catalog (covers Product Set), not just Campaigns. The first budget for a seller syncs the parent template's audience/creative/productSet config to the new child ad set, so missing rights can cause a 500 even on a valid request.
## Statistics Single-Seller performance uses the same stats APIs as multi-seller. Choose the endpoint based on the granularity you need: | Endpoint | Use case | | -------- | -------------------------------------------- | | | Aggregated across all sellers for a template | | | Per-seller aggregation | | | Per seller-campaign (most granular) | Statistics data defaults to UTC. However, a timezone parameter is available in the Stats API request to retrieve data in a specific time zone. Statistics are typically available with a latency of a few hours. Refer to the [Getting Statistics](/marketing-solutions/docs/getting-statistics) page for current SLA guidance. This is expected immediately after the first budget creation. Criteo creates the underlying seller-campaign synchronously when the first budget is accepted, but there is a short asynchronous provisioning delay before delivery begins. If impressions do not appear after a reasonable wait, check: * The template campaign is active (not paused or archived). * The budget amount meets the minimum per-seller threshold. * The budget `isSuspended` is `false`. * The seller has eligible products in the catalog (no `RemovedFromCatalog` suspension reason). * If a `productSet` is configured, the product IDs are valid and active in the seller's catalog.
# Welcome to Criteo Source: https://developers.criteo.com/marketing-solutions/docs/welcome-to-criteo **New to the Criteo API?** Start with [API Resources](/criteo-apis/docs/overview) — authentication, OAuth setup, rate limits, error codes, versioning policy, and troubleshooting are documented there and apply to all Criteo APIs. ## Criteo API Version Tiers Overview Criteo API versions follow a three-stage lifecycle. Choose the tier that fits your needs — or keep reading to learn what this version offers. **You are here.** Fully supported for 12 months with no breaking changes. The right choice for all production integrations. Production-ready preview of the next stable version. Integrate early and you're already on the right version the moment it goes stable. Early access to brand-new features before they're finalized. Contracts may change — not for production use. For the full version lifecycle — deprecation windows, release schedule, fall-forward — see the [Versioning policy](/criteo-apis/docs/versioning-policy). The Criteo API empowers developers to build on the world’s largest advertising network programmatically. We have two distinct API products: the Marketing Solutions API for Commerce Growth users and the Retail Media API for Commerce Max and Commerce Yield Users. With our API, you can unlock the power of Criteo’s industry-leading innovations. Leverage Criteo's powerful targeting solutions to create flexible apps customized to your needs, then automate and scale them.     ## Common use cases for Marketing Solutions API * **[Build custom reports](/marketing-solutions/docs/analytics):** Get granular insights into campaigns with the ability to compare performance across 100+ metrics * **Automated campaign management:** Retrieve and update [ad sets](/marketing-solutions/docs/campaigns) * **Create and update [audiences](/marketing-solutions/docs/audiences):** Easily create and manage specific audience segments, using your own CRM or data from your CDP, DMP, and other sources * **Automated creative management:** Setup and manage creatives and ads For advertisers managing large, complex, or many accounts, the Criteo API can help by providing fine-tuned controls, customization, and automation capabilities. Through the API, you can also integrate Criteo campaigns with your internal or third-party tools. # Retail Media API Changelog Source: https://developers.criteo.com/retail-media/changelog/changelog Release notes and announcements for the Criteo Retail Media API. Versions are released twice a year, in January and July. ## Type-Agnostic Campaign and Line Item Workflow A new end-to-end workflow is now available in Experimental, covering campaign creation, line item management, and product assignment through a single unified contract — replacing the previous pattern of separate endpoints per campaign type. **Create a campaign** — `POST /accounts/{account-id}/campaigns` Set `campaignType` to select the type. Type-specific settings such as `scheduleDetails` and `budgetDetails` are carried in a matching details object alongside the common attributes. * **[Create a campaign](/retail-media/experimental/docs/campaigns-endpoints#create-a-campaign)** **Manage line items** — type-agnostic endpoints that infer the line item type from the campaign * **[Create a line item](/retail-media/experimental/docs/line-items-core#create-a-line-item-core)** — `POST /line-items` * **[Update a line item](/retail-media/experimental/docs/line-items-core#update-a-line-item-core)** — `PATCH /line-items/{line-item-id}` * **[Search line items — demand](/retail-media/experimental/docs/line-items-search#search-line-items-demand)** — `POST /line-items/demand-search` * **[Search line items — supply](/retail-media/experimental/docs/line-items-search#search-line-items-supply)** — `POST /line-items/supply-search` **Add products to a line item** — `POST /line-items/{lineItemId}/products/add` Adds products to the product pool of an existing line item. The operation is all-or-nothing: if any product ID is invalid, no products are added. Adding a product already in the pool is a no-op. * **[Add products to a line item](/retail-media/experimental/docs/line-item-products#add-products-to-a-line-item)** **Read display auction line item settings** — new read endpoints for display line items * **[Bid Strategy Settings](/retail-media/experimental/docs/bidding-strategy-settings)** — `GET /retail-media/line-items/{line-item-id}/bidding-strategy` — Retrieve the current CPM bidding configuration for a line item, including the active strategy (`Standard` or `Adaptive`) and preserved settings for the inactive strategy. * **[Targets](/retail-media/experimental/docs/line-item-targets)** — `GET /retail-media/line-items/{line-item-id}/targets` — Retrieve the `ManualKeyword`, `PageType`, and `Category` targets configured for a line item. Supports partial success: if one target type is unavailable, other types are still returned. ## AI Assistant Bid Multiplier — Now in Stable The `aiAssistant` bid multiplier field is now available in stable (`2026-07`) on the `GET` and `PUT /retail-media/line-items/{line-item-id}/bid-multipliers` endpoints, allowing advertisers to adjust bids for AI Assistant placements. See the [Bid Multipliers](/retail-media/docs/bid-multipliers) guide for details. ## API Versioning Policy Update Starting with this release, the Criteo Retail Media API moves to a cadence of **two versions per year**, released in January and July. We are also introducing a new **three-tier release model** — Experimental, Release Candidate, and Stable — replacing the previous two-tier system (Preview and Stable). Find out what this means for your integration in our [Versioning Policy](/criteo-apis/docs/versioning-policy) guide. ## Breaking Changes * **Retailer Search** — Targeting eligibility is now reported per budget model. `isAvailable` has been removed; use `budgetModelAvailabilities` to see which combinations of budget model, page type, and environment are available for each retailer. For full details, see the [Retailer Search](/retail-media/docs/retailer-search) guide.
* **AI Assistant Page Type** — You can now target AI Assistant placements by including `aiAssistant` as a value in the `pageTypes` field when creating or updating line items. Read more in the [Retailer Search](/retail-media/docs/retailer-search) guide.
* **Real-Time Performance — Metric Renaming** — `billableImpressions` and `billableClicks` have been renamed to `impressions` and `clicks`. Update your integration to use the new names before upgrading to `2026.07`. More information in our dedicated [Real-Time Performance Report](/retail-media/docs/real-time-performance-api) guide.
* **DSP Analytics Reporting Redesign** — The three legacy endpoints (`/reports/campaigns`, `/reports/line-items`, `/reports/accounts`) and the `reportType` field have been replaced by a unified set of purpose-built endpoints where you explicitly declare `metrics` and `dimensions`. Learn more on the following pages: [Analytics Overview](/retail-media/docs/demand-side-analytics-overview), [Performance Report](/retail-media/docs/performance-report), [Missed Opportunities](/retail-media/docs/missed-opportunities-report), [Attributed Transactions](/retail-media/docs/attributed-transactions-report).
* **Balance Endpoints — Path Parameters Renamed** — The `account-id` and `balance-id` path parameters have been renamed to `accountId` and `balanceId` across all balance endpoints. Update your request URLs accordingly: `GET /accounts/{accountId}/balances`, `POST /balances/{balanceId}/campaigns/append`, `POST /balances/{balanceId}/campaigns/delete`.
* **Balance Endpoints — Pagination Fields Renamed** — The pagination metadata fields returned by `GET /accounts/{accountId}/balances` have been renamed. Replace `totalItemsAcrossAllPages`, `currentPageSize`, `currentPageIndex`, and `totalPages` with `count`, `offset`, and `limit`.
* **Balance Endpoints — Campaign Append/Delete Request Body Restructured** — The request body for `POST /balances/{balanceId}/campaigns/append` and `POST /balances/{balanceId}/campaigns/delete` has changed from an array (`data[]`) to a single object (`data`). Update your payloads to pass campaign IDs under `data.attributes.ids`.
* **Balance Endpoints — `spendType` Enum Values Recased** — The `spendType` enum values returned by `GET /accounts/{accountId}/balances` and `PATCH /accounts/{accountId}/balances/{balanceId}` are now lowercase. Replace `Offsite` → `offsite`, `OffsiteAwareness` → `offsiteAwareness`, `Onsite` → `onsite`. Two new values have also been added: `lockout` and `unknown`.
* **Balance Endpoints — History `changeType` Values** — `changeType` values returned by `GET /balances/{balanceId}/history` are now camelCase (e.g. `balanceCreated`, `endDate`, `retailerPoNumber`). Several new values have also been added: `balanceAdded`, `balanceRemoved`, `balanceName`, `criteoPoNumber`, `retailerId`, and `unknown`. Update any string matching logic in your integration. See the [Balance Management](/retail-media/docs/balances-endpoints) guide for the full list of all balance endpoint changes above.
* **Creatives & Templates — New `creativeFormatType` Values** — Eight new values have been added to the `creativeFormatType` enum on creative endpoints (`POST`/`PUT /accounts/{accountId}/creatives`) and the `creativeFormat` enum on template endpoints (`GET /retailers/{retailerId}/templates`): `BrandingDisplayGridSolo`, `BrandingDisplaySpotlightSolo`, `BrandingVideoStandout`, `CommerceDisplayGridDuet`, `CommerceDisplayGridShelf`, `CommerceDisplaySpotlight`, `CommerceVideoGridDuet`, `CommerceVideoSpotlight`. Ensure your integration handles unknown enum values gracefully. See the [Creative Builder](/retail-media/docs/creative-builder) guide for the full list. ## New in Stable * **Commerce Max — Retailer Budgets Expansion** — Retailer budget management is now fully supported in stable, covering budget visibility, field naming, and eligibility rules across campaigns, line items, and balances. Explore the [Retailer Budgets](/retail-media/docs/retailer-budgets) guide for more information. * **Commerce Max — New Balance Endpoint** — A new `GET /balances/{balanceId}` endpoint lets you fetch a single balance directly by ID without needing the `accountId`. See the [API reference](https://developers.criteo.com/retail-media/v2026.07/reference/balance/2026-07retail-mediabalances) for details. * **Real-Time Performance Report** — The synchronous real-time performance report is now available in stable, returning live campaign data immediately without polling. See our dedicated [Real-Time Performance Report](/retail-media/docs/real-time-performance-api) guide. * **Store Inventory** — You can now programmatically upsert and delete store inventory records, enabling automated inventory management workflows. Full details in the [Store Inventory](/retail-media/docs/store-inventory) guide. * **Balance Management — PATCH Endpoint** — A new `PATCH` endpoint lets you partially update existing balances without replacing the full record. `retailerPoNumber` replaces `poNumber`, and `endDate` now accepts a Nillable wrapper so you can explicitly set, clear, or leave a date unchanged. Head to our [Balance Management](/retail-media/docs/balance-management) guide to learn more. ## Enhancements * **SSP Revenue Report** — Three new fields added: `authorizedBuyer` as a new value in the `soldBy` enum, and `budgetModels` and `activationPlatforms` arrays to identify how inventory was monetized. Learn more on the [Revenue Report (SSP)](/retail-media/docs/revenue-report-ssp) page.
## New Features * **API Authorization — PKCE Support** — Proof Key for Code Exchange (`PKCE`) is now supported as a security enhancement to the OAuth 2.0 Authorization Code flow. When enabled, requests must include a `code_challenge` derived from a `code_verifier`, preventing intercepted authorization codes from being misused. See the [OAuth PKCE setup guide](/retail-media/docs/oauth-app-authorization-code-pkce-setup) for more information. * **Sponsored Product Line Item Updates** — Four new capabilities added to sponsored product line item endpoints: **Conquesting** for targeting competitor search queries, **Ad Scheduling** for day-of-week and time-of-day delivery controls, **Adaptive CPC** for real-time bid optimization based on predicted conversion probability, and **Flexible Start/End Date Timestamps** supporting `dateTimeOffset` values for timezone-aware scheduling. Full details in the [Sponsored Products Line Items](/retail-media/docs/onsite-sponsored-products-line-items) guide. * **Retailer Search** — New endpoint to programmatically determine targeting eligibility across available retailers, campaign types, buy types, page types, and environments before creating or updating campaigns. Read more in the [Retailer Search](/retail-media/docs/retailer-search) guide. * **Account Level Reporting** — New asynchronous reporting endpoint aggregating performance data at the account level across up to five `accountIds` in a single request, with a maximum 31-day date range. More information in the [Account Level Report](/retail-media/docs/account-level-report) guide. * **Fill Rate Reporting** — Two new reporting endpoints for retailers: a **fill rate report** measuring how effectively ad placements are monetized, and an **unfilled placements report** breaking down the specific reasons inventory went unfilled. Explore the [Fill Rate Report](/retail-media/docs/fill-rate-report) guide. ## New Features * **API Troubleshooting Guides** — Three new documentation pages introduced: a [Troubleshooting Guide](/retail-media/v2025.10/docs/api-troubleshooting-guide) for diagnosing common API issues, [Escalation Guidelines](/retail-media/v2025.10/docs/escalation-guidelines) defining when and how to escalate to Criteo support, and an [API Error Codes](/retail-media/v2025.10/docs/api-error-codes) reference for interpreting error responses. * **Retailer Configuration Updates** — New governance logic for Commerce Max demand opt-out: if a retailer opts out of receiving Commerce Max demand, create and edit operations on affected campaigns and line items will return a validation error, while read and reporting operations remain fully accessible. * **Recommended Keywords** — New endpoint that analyzes your product IDs and returns the top 100 keywords your line items would serve on, letting you preview targeting before adding products to a campaign. See the [Recommended Keywords](/retail-media/v2025.10/docs/recommended-keywords) guide. * **Recommended Categories** — New endpoint that returns up to 50 recommended product categories for targeting based on your specified products and the retailer's taxonomy. Read more in the [Recommended Categories](/retail-media/v2025.10/docs/recommended-categories) guide. * **Category Search** — New endpoint to explore and discover available product categories within a retailer's hierarchical taxonomy, helping you understand targeting options before campaign setup. Full details in the [Category Search](/retail-media/v2025.10/docs/category-search) guide. * **Account Fees** — New endpoints enabling Private Marketplace retailers to search and manage fees across one or more accounts. More information in the [Account Fees](/retail-media/v2025.10/docs/account-fees) guide. * **Keyword Bid Override on Auto-Targeted Keywords** — Keyword bid overrides can now be applied to automatically targeted keywords (derived from the keyword relevancy model), in addition to manually targeted ones. Head to the [Keywords](/retail-media/v2025.10/docs/keywords) guide for details. * **Authorization Code Rate Limiting — Auto Scaling** — Rate limits for Authorization Code apps now scale automatically with the number of consented accounts (10 calls/minute per account). Learn more on the [Rate Limits](/retail-media/v2025.10/docs/rate-limits) page. * **Reporting Updates** — Reporting cache behavior improved (1-hour cache for same-day reports, 24-hour for prior dates). New `productCategory` dimension for advertised product category reporting, updated `capoutMissedTraffic` calculation, and new dimensions on the Attributed Transactions report. More information in our dedicated [Analytics Overview](/retail-media/v2025.10/docs/demand-side-analytics-overview) guide. ## New Features * **Keyword Review & Approval** — New endpoints enabling retailers to review and approve keywords proposed by advertisers for targeting on retailer inventory, based on relevance, accuracy, and retailer guidelines. See the [Keyword Review](/retail-media/v2025.07/docs/keyword-review) guide. * **Catalog Export Enhancements** — New `includeFields` filter to scope catalog responses to only relevant fields, and a `modifiedAfter` parameter to fetch only SKUs updated after a given timestamp. Available on both seller and brand catalog export endpoints. Full details in the [Catalog Endpoints](/retail-media/v2025.07/docs/catalog-endpoints) guide. * **Brand Search** — New endpoint to search for brands by name across the universal catalog and retailer-specific brands, replacing the account-scoped brand lookup workflow. Read more in the [Brands](/retail-media/v2025.07/docs/brands) guide. * **Partner Billing Report** — New reporting endpoints enabling retailers to bill retailer-contracted advertisers, manage invoicing, and track payments — including fee and media cost verification for campaigns managed through Commerce Max and CYield. More information in the [Partner Billing Report](/retail-media/v2025.07/docs/partner-billing-report) guide. * **Reporting — Media Type & Attribution Dimensions** — New `mediaType` dimension available as both a dimension and a filter across DSP and SSP reporting endpoints, enabling performance breakdowns by Display or Video. New `clickMatchLevel` and `viewMatchLevel` filters added for SSP attribution reporting. Explore the [Analytics Overview](/retail-media/v2025.07/docs/demand-side-analytics-overview) for more. ## Breaking Changes * **Keyword Endpoint Cleanup** — Older keyword endpoints supporting only negative keyword targeting have been removed from `2025.04`. Use the unified keyword endpoints that support both negative and positive keyword targeting going forward. See the [Keywords](/retail-media/v2025.04/docs/keywords) guide. ## New Features * **Private Market Child Accounts** — New endpoint enabling Private Marketplace retailers to retrieve all child accounts associated with their `accountId`. Read more in the [Accounts](/retail-media/v2025.04/docs/accounts-endpoints) guide. * **Seller Search** — New marketplace seller search endpoint providing a programmatic way to identify all marketplace sellers and associated retailers for a given account, supporting campaign activation workflows. More information in our [Accounts](/retail-media/v2025.04/docs/accounts-endpoints) guide. * **CPC Minimum Bid** — New endpoint to look up the minimum CPC bid required for a set of sponsored products before adding them to a line item. Full details in the [Sponsored Products Line Items](/retail-media/v2025.04/docs/onsite-sponsored-products-line-items) guide. * **New Reporting Metrics — Win Rate & Video** — `winRate` metric added for Sponsored Products (bids won / bids participated). New video metrics added for flexible line-item reporting via the DSP API and SSP API. Explore the [Analytics Overview](/retail-media/v2025.04/docs/demand-side-analytics-overview) for the full list. * **Updated Terms & Conditions** — The API Terms & Conditions have been updated to clarify agreement scope, acceptance requirements, and compliance obligations. Find them on the [Terms & Conditions](/retail-media/v2025.04/docs/criteo-api-terms-and-conditions) page. # /2026-07/advertisers/me Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/advertiser/2026-07advertisersme https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/advertisers/me Fetch the portfolio of Advertisers for this account # /2026-07/log-level/advertisers/{advertiser-id}/report Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/analytics/2026-07log-leveladvertisers-report https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/log-level/advertisers/{advertiser-id}/report This Statistics endpoint provides publisher data. # /2026-07/placements/report Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/analytics/2026-07placementsreport https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/placements/report Your ads are placed in different domains (publishers) and environments (websites and apps). Thanks to the placements endpoint, you can analyse the performances for each publisher, comparing displays, clicks and sales generated.

This endpoint supports data retrieval for up to three months in the past. # /2026-07/statistics/report Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/analytics/2026-07statisticsreport https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/statistics/report This Statistics endpoint provides ad set related data. It is an upgrade of our previous Statistics endpoint, and includes new metrics and customization capabilities.

This endpoint supports data retrieval for up to two years in the past. # /2026-07/transactions/report Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/analytics/2026-07transactionsreport https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/transactions/report This Transactions endpoint provides transactions id related data.

This endpoint supports data retrieval for up to two years in the past. # /2026-07/marketing-solutions/ad-sets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/ad-sets Create an ad set with the provided parameters # /2026-07/marketing-solutions/ad-sets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/ad-sets Patch a list of AdSets. # /2026-07/marketing-solutions/ad-sets/{ad-set-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/ad-sets/{ad-set-id} Get the data for the specified ad set # /2026-07/marketing-solutions/ad-sets/{ad-set-id}/audience Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets-audience https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json put /2026-07/marketing-solutions/ad-sets/{ad-set-id}/audience Link or unlink an audience with an ad set # /2026-07/marketing-solutions/ad-sets/{ad-set-id}/category-bids Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets-category-bids https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/ad-sets/{ad-set-id}/category-bids Get the Category Bids for all valid Categories associated to an Ad Set # /2026-07/marketing-solutions/ad-sets/{ad-set-id}/category-bids Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets-category-bids-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/ad-sets/{ad-set-id}/category-bids Update the Category Bids for given Categories associated to an Ad Set Patch Category Bids for one or more Categories in a single request. Partial success policy is followed. # /2026-07/marketing-solutions/ad-sets/{ad-set-id}/display-multipliers Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets-display-multipliers https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/ad-sets/{ad-set-id}/display-multipliers Get the Display Multipliers for all valid Categories associated to an Ad Set # /2026-07/marketing-solutions/ad-sets/{ad-set-id}/display-multipliers Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-sets-display-multipliers-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/ad-sets/{ad-set-id}/display-multipliers Update the Display Multipliers for given Categories associated to an Ad Set Patch Display Multipliers for one or more Categories in a single request. Partial success policy is followed. # /2026-07/marketing-solutions/ad-sets/search Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-setssearch https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/ad-sets/search Search for ad sets based on provided criteria. This returns the full configuration of ad sets matching those criteria. Field projection can be used if only a subset of fields is required, instead of the full configuration. If specific fields are precised in the user prompt, use meta.fields field projection in order to query only the value of these fields, else, provide every field. # /2026-07/marketing-solutions/ad-sets/start Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-setsstart https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/ad-sets/start Start the specified list of ad sets # /2026-07/marketing-solutions/ad-sets/stop Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsad-setsstop https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/ad-sets/stop Stop the specified list of ad sets # /2026-07/marketing-solutions/campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionscampaigns https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/campaigns Create the specified campaign A campaign, or in other words a marketing campaign, is an entity that defines advertising objectives and success criteria. # /2026-07/marketing-solutions/campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionscampaigns-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/campaigns Patch a list of Campaigns. A campaign, or in other words a marketing campaign, is an entity that defines advertising objectives and success criteria. # /2026-07/marketing-solutions/campaigns/{campaign-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionscampaigns-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/campaigns/{campaign-id} Get the data for the specified campaign. A campaign, or in other words a marketing campaign, is an entity that defines advertising objectives and success criteria. # /2026-07/marketing-solutions/campaigns/search Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionscampaignssearch https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/campaigns/search Search endpoint for campaigns A campaign, or in other words a marketing campaign, is an entity that defines advertising objectives and success criteria. # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers Get the collection of advertisers associated with the user. # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId} Get an advertiser. # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/ad-preview Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers-ad-preview https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/ad-preview Get a preview of an HTML ad with products belonging to the provided seller • advertiserId: Valid crp advertiserId, seller belongs to provided advertiser
sellerId: Products from given SellerId will fill the ad preview, must be existing crp sellerId
height: height may be supplied to request a specific ad preview height. Default height: 250
width: width may be supplied to request a specific ad preview width. Default width: 300
Ad preview api calls are capped to 1000 per day per advertiser by default. Current usage, limit, and period can be found using v2/crp/advertisers/preview-limit # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/adsets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers-adsets https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/adsets Get the collection of adsets associated with the advertiserId. # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/budgets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers-budgets https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/budgets Get CRP budgets for a specific advertiser # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers-campaigns https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/campaigns Get the collection of CRP campaigns associated with the advertiserId. # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/seller-campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers-seller-campaigns https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/seller-campaigns Get CRP seller campaigns for a specific advertiser # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/sellers Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertisers-sellers https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/{advertiserId}/sellers Create new sellers for an advertiser # /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/preview-limit Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesadvertiserspreview-limit https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/advertisers/preview-limit Get the collection of advertisers preview limits associated with the authorized user. # /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesbudgets https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets Return a collection of budgets filtered by optional filter parameters, **including archived budgets**. This is the endpoint to use when investigating past budget history. By default, budgets whose endDate is in the past are excluded. Use `endAfterDate` to retrieve archived budgets (e.g. `endAfterDate=2025-01-01` returns all budgets ending after that date). Use `sellerId` to filter to a specific seller — omitting it on large advertisers causes timeouts. Date filter. To find budgets that were active on a specific date, set both `startBeforeDate` and `endAfterDate` to that day. Spend. If `endAfterDate` is supplied, the spend excludes spend that happened after that date. For daily budgets, only the spend for the final day is displayed. # /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesbudgets-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets Create one or more new budgets to enable spending with the given limitations. All three types of budgets can be created this way. The following constraints apply when creating a new budget. • sellerId: the seller MUST be supplied
campaignIds: a non-empty array of campaign ids MUST be supplied
budgetType: a budget type MUST be supplied
amount: an amount MAY be supplied only if the type is not Uncapped and if supplied it MUST be non-negative
startDate: a future start date MUST be supplied
endDate: an end date MAY be supplied and if supplied MUST be greater than the start date
Other attributes MUST NOT be supplied. # /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesbudgets-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets Modify one or more existing active budgets to change their limitations or status. All three types of budgets can be modified. The following constraints apply when modifying an existing budget. • campaignIds: a non-empty subset of the original campaign ids MAY be supplied
amount: an amount MAY be supplied only if the type is not Uncapped and if supplied it MUST be non-negative
startDate: a future start date MAY be supplied for budgets that have not yet started
endDate: an end date MAY be supplied and if supplied MUST be a future date greater than the start date
Other attributes MUST NOT be supplied. Adding new campaigns to a budget is not allowed. In addition, reducing the amount for a Capped budget to a value less than the current spend not allowed. # /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesbudgets-3 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Return a budget. For example, { "id": "1759183", "sellerId": "321392", "campaignIds": [ 143962 ], "budgetType": "Capped", "amount": 1000, "startDate": "2021-01-11", "endDate": "2021-01-12", "spend": null, "status": "Active" } A budget limits the spend of a seller for one or more campaigns. There are three types of budget:
Uncapped budgets put no limit on the total amount of spend.
Capped budgets limit the total spend to a fixed amount.
Daily budgets limit daily spend to a fixed amount.
In addition, budgets can limit the spend to a specific range of dates using the start and end date attributes. Finally a budget must be active to be used. Spend approximates the current spend against this budget. There may be a lag between when an ad is clicked and the time it accrues to the spend. Daily budgets show spend against the most recent day only. # /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesbudgets-4 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/marketplace-performance-outcomes/budgets/{budgetId} Modify an existing active budget to change its limitations or status. All three types of budgets can be modified. See the additional restrictions listed in the PATCH budgets endpoint. # /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesseller-campaigns https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns Return a collection of seller campaigns filtered by optional filter parameters. If all parameters are omitted the entire collection to which the user has access is returned. Returned sellers must satisfy all supplied filter criteria if multiple parameters are used. # /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesseller-campaigns-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns Patching a collection of seller campaigns allows their bids to be modified. Each bid must be a non-negative value. Setting the bid to zero will make a seller campaign inactive. The currency used for bids will be the default currency of the campaign. # /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesseller-campaigns-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId} Return details for a seller campaign. For example, { "id": "543210.123456", "sellerId": "543210", "campaignId": 123456, "bid": 1.55, "suspendedSince": "2018-07-30T15:15:24.813", "suspensionReasons": [ "NoMoreBudget" ] } An active seller campaign is one for which the value of suspendedSince is null and the bid is positive. The currency of the bid is the bidCurrency of the associated campaign. Any active seller campaign must also have an active total (capped or uncapped) budget. It may optionally have an active daily budget as well to further limit spending. Suspension reasons: - ManuallyStopped: The Seller-Campaign has been manually paused. This is not related to the other suspension reasons. - NoBudgetDefined: No valid budget has been linked to the Seller-Campaign. - NoCpcDefined: No CPC has been set for the Seller-Campaign. - NoMoreBudget: The current budget of the Seller-Campaign has been exhausted. - RemovedFromCatalog: All the products of the Seller-Campaign have been deleted from the catalog. - NotYetStarted: The Seller-Campaign has just been created and has not yet been processed. # /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesseller-campaigns-3 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId} Patching a seller campaign allows the bid to be modified. The bid must be a non-negative value. Setting the bid to zero will make a seller campaign inactive. The currency used for bids will be the default currency of the campaign. # /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId}/budgets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesseller-campaigns-budgets https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/seller-campaigns/{sellerCampaignId}/budgets Return a collection of budgets for this seller campaign filtered by optional filter parameters. If all parameters are omitted the entire collection to which the user has access is returned, except those whose endDate is in the past. Returned budgets must satisfy all supplied filter criteria if multiple parameters are used. See the budgets endpoint for additional details. # /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomessellers https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers Return a collection of sellers filtered by optional filter parameters. If all parameters are omitted the entire collection to which the user has access is returned. Returned sellers must satisfy all supplied filter criteria if multiple parameters are used. # /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomessellers-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId} Return details for the selected seller. For example, { "id" : "123456" "sellerName": "HBogart", } # /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/budgets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomessellers-budgets https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/budgets Return current (non-archived) budgets for this seller. Budgets whose endDate is in the past are excluded by default. To retrieve archived or past budgets, use the `/budgets` endpoint (GetMarketplaceSellerBudgets) with the `endAfterDate` filter instead. # /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/seller-campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomessellers-seller-campaigns https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/seller-campaigns Return a collection of seller campaigns for this seller filtered by optional filter parameters. If all parameters are omitted the entire collection to which the user has access is returned. Returned sellers must satisfy all supplied filter criteria if multiple parameters are used. See the seller campaigns endpoint for additional details. # /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/seller-campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomessellers-seller-campaigns-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/marketplace-performance-outcomes/sellers/{sellerId}/seller-campaigns Associate an existing Seller with an existing Campaign allowing for budget creation # /2026-07/marketing-solutions/marketplace-performance-outcomes/stats/campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesstatscampaigns https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/stats/campaigns ## Dimensions Get performance statistics aggregated for _campaigns_. The campaign id appears in the output as the first column. Aggregation can be done by `hour`, `day`, `month`, or `year` aligned with the user timezone if provided. The aggregation interval size is controlled by `intervalSize`. The time interval appears in the output as the second column. ## Metrics The metrics reported by this endpoint are . | Metric Group | Description ---|--------------|------------ A | impressions | Number of times product is shown in a banner B | clicks | Number of clicks on product C | cost | Amount spent for clicks on products D | saleUnits | Number of products sold attributed to clicks E | revenue | Revenue generated by sales F | CR = Conversion Rate | salesUnits / clicks G | CPO = Cost Per Order | cost / salesUnits H | COS = Cost of Sale | cost / revenue I | ROAS = Return On Add Spend | revenue / cost The last six metrics can be computed in two ways depending on the policy to count only the sales that result from clicks on the same sellers product in a banner (same-seller) or not (any-seller). Reporting can be controlled by `clickAttributionPolicy`. The 9 (or 15) metric values appear in the output as the final 9 (or 15) columns. ## Filtering The results can be filtered by campaign, date or count. Filtering the results to events associated with a specific campaign is done by setting the `campaignId` filter parameter to the desired value. Filtering the results to events that happened in a time interval is done by setting the `startDate` and `endDate` filter parameters using the `yyyy-MM-DD` format. The start date includes all events timestamped since the beginning of that day while the end date includes events until the end of day. The maximum duration of the date range is 1 year. If the aggregation interval is `hour`, then the maximum duration of the date range is 31 days. Note that month and year aggregate values may contain partial data for the interval if filtering by date. Filtering the results to a maximum number of data rows is done by setting the `count` filter parameter. When combined with startDate this can be used to perform simple pagination. ## Response Format The representation format can be specified by MIME values in the Accept header. For now the only supported values for the accept header is `application/json` and `text/csv`. ```json { "columns": [ "campaignId", "month", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [168423, "2019-05-01", 3969032, 13410, 1111.295, 985, 190758099, 0.073, 1.128, 0.000, 171653.880 ], [168423, "2019-06-01", 8479603, 25619, 2190.705, 740, 152783656, 0.028, 2.960, 0.000, 69741.775 ] ], "rows": 2 } ``` The JSON result is an object with three fields (`columns`, `data`, and `rows`). The “columns” array acts as the header for the data rows. The categorical dimension column comes first and consists of the campaign id. The interval column comes next and defines the aggregation period. The interval size is determined by the `intervalSize` parameter. This is followed by either nine or fifteen metrics columns. The first three metrics (impressions, clicks, and cost) always appear. The remaining depend on the `clickAttributionPolicy` parameter. The “data” array contains data rows whose values match the entries in the “columns” array. Id dimensions are numbers while name and date dimensions are strings. The metrics are JSON objects whose type is number. Some of these are natural numbers (e.g. clicks and impressions) whereas others are decimal values. A divide by zero yields null. The currency is assumed to be the local currency established by the advertiser. The “row” value is a count of the number of rows in the data array, and can be used to check the integrity of the data. Further information on the campaign or seller (e.g. the seller name) can be obtained from the existing V1 or V2 endpoints using the campaign and/or seller ID values. # /2026-07/marketing-solutions/marketplace-performance-outcomes/stats/seller-campaigns Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesstatsseller-campaigns https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/stats/seller-campaigns ## Dimensions Get performance statistics aggregated for _seller campaigns_.The campaign id, seller id, and seller name appear in the first three columns of the output. These are followed by the interval size column. Aggregation can be done by `hour`, `day`, `month`, or `year` aligned with the user timezone if provided. The aggregation interval size is controlled by `intervalSize`. The remaining columns are metrics. ## Metrics The metrics reported by this endpoint are . | Metric Group | Description ---|--------------|------------ A | impressions | Number of times product is shown in a banner B | clicks | Number of clicks on product C | cost | Amount spent for clicks on products D | saleUnits | Number of products sold attributed to clicks E | revenue | Revenue generated by sales F | CR = Conversion Rate | salesUnits / clicks G | CPO = Cost Per Order | cost / salesUnits H | COS = Cost of Sale | cost / revenue I | ROAS = Return On Add Spend | revenue / cost The last six metrics can be computed in two ways depending on the policy to count only the sales that result from clicks on the same sellers product in a banner (same-seller) or not (any-seller). Reporting can be controlled by `clickAttributionPolicy`. The 9 (or 15) metric values appear in the output as the final 9 (or 15) columns. ## Filtering The results can be filtered by date or count. Filtering the results to events associated with a specific campaign is done by setting the `campaignId` filter parameter to the desired value. Filtering the results to events associated with a specific seller is done by setting the `sellerId` filter parameter to the desired value. Filtering the results to events that happened in a time interval is done by setting the `startDate` and `endDate` filter parameters using the `yyyy-MM-DD` format. The start date includes all events timestamped since the beginning of that day while the end date includes events until the end of day. The maximum duration of the date range is 1 year. If the aggregation interval is `hour`, then the maximum duration of the date range is 31 days. Note that month and year aggregate values may contain partial data for the interval if filtering by date. Filtering the results to a maximum number of data rows is done by setting the `count` filter parameter. When combined with startDate this can be used to perform simple pagination. ## Response Format The representation format can be specified by MIME values in the Accept header. For now the only supported values for the accept header is `application/json` and `text/csv`. ```json { "columns": [ "campaignId", "sellerId", "sellerName", "month", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas" ], "data": [ [168423, 1110222, "118883955", "2019-05-01", 14542, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0], [168423, 1110222, "118883955", "2019-06-01", 16619, 53, 3.71, 0, 0.0, 0.0, null, null, 0.0], [168423, 1110225, "117980027", "2019-05-01", 12502, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0], [168423, 1110225, "117980027", "2019-06-01", 20266, 53, 3.71, 0, 0.0, 0.0, null, null, 0.0] ], "rows": 4 } ``` The JSON result is an object with three fields (`columns`, `data`, and `rows`). The “columns” array acts as the header for the data rows. The categorical dimension columns come first and include the campaign id, seller id, and seller name. The interval column comes next and defines the aggregation period. The interval size is determined by the `intervalSize` parameter. This is followed by either nine or fifteen metrics columns. The first three metrics (impressions, clicks, and cost) always appear. The remaining depend on the `clickAttributionPolicy` parameter. The “data” array contains data rows whose values match the entries in the “columns” array. Id dimensions are numbers while name and date dimensions are strings. The metrics are JSON objects whose type is number. Some of these are natural numbers (e.g. clicks and impressions) whereas others are decimal values. A divide by zero yields null. The currency is assumed to be the local currency established by the advertiser. The “row” value is a count of the number of rows in the data array, and can be used to check the integrity of the data. Further information on the campaign or seller (e.g. the seller name) can be obtained from the existing V1 or V2 endpoints using the campaign and/or seller ID values. # /2026-07/marketing-solutions/audience-segments Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segments https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/audience-segments Updates the properties of all segments with a valid configuration, and returns their IDs. For those that cannot be updated, one or multiple errors are returned. # /2026-07/marketing-solutions/audience-segments/{audience-segment-id}/contact-list Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segments-contact-list https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json delete /2026-07/marketing-solutions/audience-segments/{audience-segment-id}/contact-list Delete all identifiers from a contact list audience-segment. # /2026-07/marketing-solutions/audience-segments/{audience-segment-id}/contact-list Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segments-contact-list-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/audience-segments/{audience-segment-id}/contact-list Add/remove identifiers to or from a contact list audience-segment. # /2026-07/marketing-solutions/audience-segments/{audience-segment-id}/contact-list/statistics Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segments-contact-liststatistics https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/audience-segments/{audience-segment-id}/contact-list/statistics Returns the statistics of a contact list segment. # /2026-07/marketing-solutions/audience-segments/compute-sizes Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segmentscompute-sizes https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audience-segments/compute-sizes Gets the size of all segments. An error is returned for those whose size calculation is not supported. # /2026-07/marketing-solutions/audience-segments/create Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segmentscreate https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audience-segments/create Creates all segments with a valid configuration, and returns their IDs. For those that cannot be created, one or multiple errors are returned. # /2026-07/marketing-solutions/audience-segments/delete Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segmentsdelete https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audience-segments/delete Delete the segments associated to the given audience IDs. # /2026-07/marketing-solutions/audience-segments/estimate-size Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segmentsestimate-size https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audience-segments/estimate-size Gets the size estimation of a non existent segment. An error is returned when size calculation is not supported. # /2026-07/marketing-solutions/audience-segments/in-market-brands Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segmentsin-market-brands https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/audience-segments/in-market-brands Returns a list with all available in-market brands that can be used to define an in-market segment. # /2026-07/marketing-solutions/audience-segments/in-market-interests Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segmentsin-market-interests https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/audience-segments/in-market-interests Returns a list with all available in-market interests that can be used to define an in-market segment. These in-market interests correspond to the Google product taxonomy. # /2026-07/marketing-solutions/audience-segments/search Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudience-segmentssearch https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audience-segments/search Returns a list of segments that match the provided filters. If present, the filters are AND'ed together when applied. # /2026-07/marketing-solutions/audiences Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudiences https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/audiences Updates the properties of all audiences with a valid configuration, and returns their IDs. For those that cannot be updated, one or multiple errors are returned. # /2026-07/marketing-solutions/audiences/compute-sizes Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudiencescompute-sizes https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audiences/compute-sizes Gets the size of all audiences. An error is returned for those whose size calculation is not supported. # /2026-07/marketing-solutions/audiences/create Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudiencescreate https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audiences/create Creates all audiences with a valid configuration, and returns their IDs. For those that cannot be created, one or multiple errors are returned. # /2026-07/marketing-solutions/audiences/delete Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudiencesdelete https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audiences/delete Deletes the audiences associated to the given audience IDs. # /2026-07/marketing-solutions/audiences/estimate-size Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudiencesestimate-size https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audiences/estimate-size Gets the size estimation of a non existent audience. An error is returned when size calculation is not supported. # /2026-07/marketing-solutions/audiences/search Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/audience/2026-07marketing-solutionsaudiencessearch https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/audiences/search Returns a list of audiences that match the provided filters. If present, the filters are AND'ed together when applied. # /2026-07/marketing-solutions/marketplace-performance-outcomes/stats/sellers Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/campaign/2026-07marketing-solutionsmarketplace-performance-outcomesstatssellers https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/marketplace-performance-outcomes/stats/sellers ## Dimensions Get performance statistics aggregated for _sellers_. The seller id appears in the output in the first column and the seller name appears in the second. Aggregation can be done by `hour`, `day`, `month`, or `year` aligned with the user timezone if provided. The aggregation interval size is controlled by `intervalSize`. The time interval appears in the output as the second column. ## Metrics The metrics reported by this endpoint are . | Metric Group | Description ---|--------------|------------ A | impressions | Number of times product is shown in a banner B | clicks | Number of clicks on product C | cost | Amount spent for clicks on products D | saleUnits | Number of products sold attributed to clicks E | revenue | Revenue generated by sales F | CR = Conversion Rate | salesUnits / clicks G | CPO = Cost Per Order | cost / salesUnits H | COS = Cost of Sale | cost / revenue I | ROAS = Return On Add Spend | revenue / cost The last six metrics can be computed in two ways depending on the policy to count only the sales that result from clicks on the same sellers product in a banner (same-seller) or not (any-seller). Reporting can be controlled by `clickAttributionPolicy`. The 9 (or 15) metric values appear in the output as the final 9 (or 15) columns. ## Filtering The results can be filtered by seller id, date or count. Filtering the results to events associated with a specific seller is done by setting the `sellerId` filter parameter to the desired value. Filtering the results to events that happened in a time interval is done by setting the `startDate` and `endDate` filter parameters using the `yyyy-MM-DD` format. The start date includes all events timestamped since the beginning of that day while the end date includes events until the end of day. The maximum duration of the date range is 1 year. If the aggregation interval is `hour`, then the maximum duration of the date range is 31 days. Note that month and year aggregate values may contain partial data for the interval if filtering by date. Filtering the results to a maximum number of data rows is done by setting the `count` filter parameter. When combined with startDate this can be used to perform simple pagination. ## Response Format The representation format can be specified by MIME values in the Accept header. For now the only supported values for the accept header is `application/json` and `text/csv`. ```json { "columns": ["sellerId", "sellerName", "month", "impressions", "clicks", "cost", "saleUnits", "revenue", "cr", "cpo", "cos", "roas"], "data": [ [1200972, "sellerA", "2019-05-01", 14542, 48, 3.36, 0, 0.0, 0.0, null, null, 0.0], [1200972, "sellerA", "2019-06-01", 16619, 53, 3.71, 0, 0.0, 0.0, null, null, 0.0], [1200974, "sellerB", "2019-05-01", 10102, 47, 3.29, 3, 396000.0, 0.063, 1.096, 8.308E-6, 120364.741], [1200974, "sellerB", "2019-06-01", 11576, 54, 3.78, 1, 132000.0, 0.018, 3.78, 2.863E-5, 34920.634] ], "rows": 4 } ``` The JSON result is an object with three fields (`columns`, `data`, and `rows`). The “columns” array acts as the header for the data rows. The categorical dimension columns come first and include the seller id and seller name. The interval column comes next and defines the aggregation period. The interval size is determined by the `intervalSize` parameter. This is followed by either nine or fifteen metrics columns. The first three metrics (impressions, clicks, and cost) always appear. The remaining metrics depend on the `clickAttributionPolicy` parameter. The “data” array contains data rows whose values match the entries in the “columns” array. Id dimensions are numbers while name and date dimensions are strings. The metrics are JSON objects whose type is number. Some of these are natural numbers (e.g. clicks and impressions) whereas others are decimal values. A divide by zero yields null. The currency is assumed to be the local currency established by the advertiser. The “row” value is a count of the number of rows in the data array, and can be used to check the integrity of the data. Further information on the campaign or seller (e.g. the seller name) can be obtained from the existing V1 or V2 endpoints using the campaign and/or seller ID values. # /2026-07/commerce-grid/me Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/gateway/2026-07commerce-gridme https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json get /2026-07/commerce-grid/me Get information about the currently logged application # /2026-07/commerce-grid/audience-segments Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/segment/2026-07commerce-gridaudience-segments https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json patch /2026-07/commerce-grid/audience-segments Updates the properties of all segments with a valid configuration, and returns the full segments. For those that cannot be updated, one or multiple errors are returned. # /2026-07/commerce-grid/audience-segments/{audience-segment-id}/contact-list/add-remove Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/segment/2026-07commerce-gridaudience-segments-contact-listadd-remove https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json post /2026-07/commerce-grid/audience-segments/{audience-segment-id}/contact-list/add-remove Add/remove identifiers to or from a Commerce Grid audience segment of type Contact List. # /2026-07/commerce-grid/audience-segments/{audience-segment-id}/contact-list/clear Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/segment/2026-07commerce-gridaudience-segments-contact-listclear https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json post /2026-07/commerce-grid/audience-segments/{audience-segment-id}/contact-list/clear Delete all identifiers from a Commerce Grid audience segment of type Contact List. # /2026-07/commerce-grid/audience-segments/{audience-segment-id}/contact-list/statistics Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/segment/2026-07commerce-gridaudience-segments-contact-liststatistics https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json get /2026-07/commerce-grid/audience-segments/{audience-segment-id}/contact-list/statistics Returns the statistics of a contact list segment. # /2026-07/commerce-grid/audience-segments/create Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/segment/2026-07commerce-gridaudience-segmentscreate https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json post /2026-07/commerce-grid/audience-segments/create Creates all segments with a valid configuration, and returns the full segments. For those that cannot be created, one or multiple errors are returned. # /2026-07/commerce-grid/audience-segments/delete Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/segment/2026-07commerce-gridaudience-segmentsdelete https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json post /2026-07/commerce-grid/audience-segments/delete Delete the segments associated to the given IDs. # /2026-07/commerce-grid/audience-segments/search Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/commerce-grid/segment/2026-07commerce-gridaudience-segmentssearch https://api.criteo.com/2026-07/commercegrid/open-api-specifications.json post /2026-07/commerce-grid/audience-segments/search Returns a list of segments that match the provided filters. If present, the filters are AND'ed together when applied. # /2026-07/marketing-solutions/ads/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsads https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/ads/{id} Get an Ad with its id # /2026-07/marketing-solutions/ads/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsads-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json delete /2026-07/marketing-solutions/ads/{id} Delete an Ad # /2026-07/marketing-solutions/advertisers/{advertiser-id}/ads Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-ads https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/advertisers/{advertiser-id}/ads Get the list of self-services Ads for a given advertiser # /2026-07/marketing-solutions/advertisers/{advertiser-id}/ads Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-ads-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/advertisers/{advertiser-id}/ads Create an Ad # /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-coupons https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons Get the list of self-services Coupons for a given advertiser # /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-coupons-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons Create a Coupon # /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-coupons-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id} Get a Coupon with its id # /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-coupons-3 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json put /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id} Edit a specific Coupon # /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-coupons-4 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json delete /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id} Delete a Coupon # /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id}/preview Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-coupons-preview https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons/{id}/preview Get the preview of a specific Coupon # /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons-supported-sizes Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-coupons-supported-sizes https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/advertisers/{advertiser-id}/coupons-supported-sizes Get the list of Coupon supported sizes # /2026-07/marketing-solutions/advertisers/{advertiser-id}/creatives Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-creatives https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/advertisers/{advertiser-id}/creatives Get the list of self-services Creatives for a given advertiser # /2026-07/marketing-solutions/advertisers/{advertiser-id}/creatives Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionsadvertisers-creatives-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/advertisers/{advertiser-id}/creatives Create a Creative # /2026-07/marketing-solutions/creatives/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionscreatives https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/creatives/{id} Get a Creative with its id # /2026-07/marketing-solutions/creatives/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionscreatives-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json put /2026-07/marketing-solutions/creatives/{id} Edit a specific Creative # /2026-07/marketing-solutions/creatives/{id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionscreatives-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json delete /2026-07/marketing-solutions/creatives/{id} Delete a Creative if there are no ads binded to it # /2026-07/marketing-solutions/creatives/{id}/preview Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/creative/2026-07marketing-solutionscreatives-preview https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/creatives/{id}/preview Get the preview of a specific Creative # /2026-07/marketing-solutions/me Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/gateway/2026-07marketing-solutionsme https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/me Get information about the currently logged application # /2026-07/marketing-solutions/ads/{ad-id}/product-boost Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsads-product-boost https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/ads/{ad-id}/product-boost Fetch all boosting associations and configurations # /2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsads-product-boost-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} Fetch boosting association and configuration # /2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsads-product-boost-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} Create or update product boosting configuration # /2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsads-product-boost-3 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json delete /2026-07/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id} Delete association and configuration. # /2026-07/marketing-solutions/ads/{ad-id}/product-filter Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsads-product-filter https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/ads/{ad-id}/product-filter Fetch product filtering configuration for a given ad # /2026-07/marketing-solutions/ads/{ad-id}/product-filter Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsads-product-filter-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/ads/{ad-id}/product-filter Enable product filtering for a given ad # /2026-07/marketing-solutions/ads/{ad-id}/product-filter Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsads-product-filter-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json delete /2026-07/marketing-solutions/ads/{ad-id}/product-filter Disable product filtering for a given ad # /2026-07/marketing-solutions/dataset/{dataset-id}/product-boost Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsdataset-product-boost https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/dataset/{dataset-id}/product-boost Fetch boosting association and configuration for a given partner # /2026-07/marketing-solutions/product-sets Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsproduct-sets https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json post /2026-07/marketing-solutions/product-sets Create a new product set # /2026-07/marketing-solutions/product-sets/{product-set-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsproduct-sets-1 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/product-sets/{product-set-id} Fetch an existing product set # /2026-07/marketing-solutions/product-sets/{product-set-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsproduct-sets-2 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json delete /2026-07/marketing-solutions/product-sets/{product-set-id} Remove a product set # /2026-07/marketing-solutions/product-sets/{product-set-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsproduct-sets-3 https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json patch /2026-07/marketing-solutions/product-sets/{product-set-id} Patch an existing product set # /2026-07/marketing-solutions/product-sets/{product-set-id}/product-filters Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsproduct-sets-product-filters https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/product-sets/{product-set-id}/product-filters Fetch product filtering usages for a given product set # /2026-07/marketing-solutions/product-sets/dataset/{dataset-id} Source: https://developers.criteo.com/marketing-solutions/v2026.07/reference/reco/2026-07marketing-solutionsproduct-setsdataset https://api.criteo.com/2026-07/marketingsolutions/open-api-specifications.json get /2026-07/marketing-solutions/product-sets/dataset/{dataset-id} Fetch product sets of a given dataset # Marketing Solutions API Changelog Source: https://developers.criteo.com/marketing-solutions/changelog/changelog Release notes and announcements for the Criteo Marketing Solutions API. Versions are released twice a year, in January and July. ## API Versioning Policy Update Starting with this release, the Criteo Marketing Solutions API moves to a cadence of **two versions per year**, released in January and July. We are also introducing a new **three-tier release model** — Experimental, Release Candidate, and Stable — replacing the previous two-tier system (Preview and Stable). Find out what this means for your integration in our [Versioning Policy](/criteo-apis/docs/versioning-policy) guide. ## Product Boost Five new endpoints are available to manage Product Boost configurations, letting you control which products are featured in your ads at the ad and dataset level. See the [API Reference](/marketing-solutions/reference/fetch-boosted-ad-associations) for full details. | Verb | Endpoint | Description | | -------- | ----------------------------------------------------------------- | ----------------------------------------------- | | `GET` | `/marketing-solutions/ads/{ad-id}/product-boost` | List Product Boost configurations for an ad | | `GET` | `/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id}` | Get a specific Product Boost configuration | | `POST` | `/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id}` | Create a Product Boost configuration | | `DELETE` | `/marketing-solutions/ads/{ad-id}/product-boost/{product-set-id}` | Delete a Product Boost configuration | | `GET` | `/marketing-solutions/dataset/{dataset-id}/product-boost` | List Product Boost configurations for a dataset | ## Ad-Sets — New Fields and Attribution Methods Two additions to all ad-set endpoints (`PATCH`, `POST`, search, and `GET`): * `budget.pacingBehavior` — controls how the budget is paced over the campaign flight. * Two new values for `attributionConfiguration.attributionMethod`: `googleAnalytics` and `sftp`. See the [API Reference](/marketing-solutions/reference/patch-ad-sets) for full details. ## Commerce Grid Audience Segments New endpoints to manage audience segments programmatically — create, update, delete, and search segments, as well as manage contact list membership. See the [Commerce Grid Audience Segments](/marketing-solutions/docs/commerce-grid-audience-segments-endpoints) guide for full details. ## Authorization Code Rate Limiting — Auto Scaling Rate limits for Authorization Code apps now scale automatically with the number of consented accounts (10 calls/minute per account per consent granter). Learn more on the [Rate Limits](/marketing-solutions/docs/rate-limits) page. ## Product Sets — Now in Stable The Product Sets endpoint has moved from Preview to Stable. Product Sets let you create subsets of your product catalog using rule-based conditions to control which products appear in dynamic ads. See the [Product Sets](/marketing-solutions/docs/product-sets) guide. ## Real-Time Statistics (Preview) A new preview endpoint enables real-time MPO statistics retrieval, returning live performance data immediately without polling. See the [Real-Time Statistics](/marketing-solutions/docs/getting-realtime-mpo-statistics) guide. ## Ad-Sets — Attribution Configuration A new `attributionConfiguration` field has been added to [Ad-Set](/marketing-solutions/docs/ad-set) endpoints, letting advertisers choose which attribution method to use for their sales campaigns. ## Updated Terms & Conditions The API Terms & Conditions have been updated to clarify agreement scope, acceptance requirements, and compliance obligations. Find them on the [Terms & Conditions](/marketing-solutions/docs/criteo-api-terms-and-conditions) page. # AI Assistant Source: https://developers.criteo.com/retailer-integration/docs/ai-assistant # Definition Use the AI Assistant type to **show products that are relevant to the conversation happening on site between a shopper and an AI**. Make an ad request for each predicted keyword sent by the LLM. *** # Parameters ## `event-type` **Value**: `aiAssistant` **Description**: Indicates to the Delivery API that this is an AI Assistant event. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `aiAssistant_API_desktop`, `aiAssistant_API_iOS` * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `aiAssistantApiMobile`, `aiAssistantApiAndroid` **Required**: Yes *** ## `keywords` **Description**: The search query predicted by the LLM. Should be URL encoded. **Examples**: * `black%20laptops` * `black-laptops` **Required**: Yes *** ## `page-uid` **Description**: This value is returned within the response of the **initial call made on page load**. By storing this value and including it in subsequent `aiAssistant` event calls, Criteo is able to link the events to the initial ad request. **Example**: `545d9a70-f096-4568-b4b9-8f2f32a452d4` **Required**: Recommended. If not used, might inflate page views. *** ## `item` **Description**: The list of SKUs that are organically shown on the page in the grid or list. Must match the parameter `id` in the feed (See details [here](/retailer-integration/docs/product-feed-parameters#id)). Multiple items should be separated by a pipe `|` or `%7C` (URL encoded). Used for reporting and for organic deduplication, if enabled. **Examples**: * `123|456|789` * `123%7C456%7C789` **Required**: Recommended, but not required *** ## `parent-item` **Description**: Only use this if parent SKUs are being passed. Must match the parameter `item_group_id` in the feed (See details [here](/retailer-integration/docs/product-feed-parameters#item_group_id)). Multiple parent items should be separated by a pipe `|` or `%7C` (URL encoded). For SKUs that do not have parent SKUs, `NULL` should be sent instead. Used for reporting and for organic deduplication, if enabled. **Examples**: * `12345P|NULL|456789P` * `12345P%7CNULL%7C456789P` **Required**: Recommended if the eCommerce platform uses parent items *** ## `list-size` **Description**: The total number of organic items on the page. Preferably, it should match the number of item IDs sent in the `item` parameter. **Required**: Recommended *** ## `page-number` **Description**: Represents the page number for either paginated results or scroll fold if products are loaded dynamically. This parameter can be used for result deduplication, by limiting the number of products shown on each page. Please note that a valid `page-number` starts at 1 and not 0. **Example**: `3` **Required**: Recommended *** ## `filters` **Description**: Corresponds to the filters applied by the shopper on the results. See the filter section for details on how to use this parameter. **Examples**: * `(price,le,100)` * `(color,eq,blue)` **Required**: Recommended. If not used, the ads will not follow the selected filters and might result in a poor user experience. *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## AI Assistant Page Example ### AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=aiAssistant_API_desktop" \ --data-urlencode "event-type=aiAssistant" \ --data-urlencode "keywords=fast laptops" \ --data-urlencode "item=123|456|789" \ --data-urlencode "page-number=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` ### EMEA ```bash cURL theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailervisitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=aiAssistantApiAios" \ --data-urlencode "event-type=aiAssistant" \ --data-urlencode "keywords=black laptops" \ --data-urlencode "item=123|456|789" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` *** ## What's next * [Category pages](/retailer-integration/docs/category-page) * [Category flyout](/retailer-integration/docs/category-flyout) * [Product details page](/retailer-integration/docs/product-details-page) * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Ad Server API Calls Source: https://developers.criteo.com/retailer-integration/docs/api-calls Use Criteo's ad server to get all information needed to render and track ads Ad server API calls integration process # Where to Make API Calls Our API recognizes the following page types: * **Search**: Pages where users perform a keyword search, including the search bar dropdown. * **Category**: Includes category pages, category menu fly outs, and deals/promotional pages. * **Product detail (PDP)**: Individual product pages. * **Homepage**: The main landing page of your site. * **Checkout/Cart/Basket**: Pages where users review their cart or initiate checkout. * **Order confirmation**: Pages confirming a transaction or purchase. There is also a special "page type" called **add-to-cart**. In practice, this is not a dedicated page, but an event used to build our keyword model. More information about the keyword model can be found [here](https://help.retailmedia.criteo.com/kb/guide/en/about-the-cmax-keyword-model-zOGYygtwb1/Steps/975322). Each page type is linked to valid values of the `event-type` parameter in the API call. More details can be found at [API Parameters](/retailer-integration/docs/api-parameters-1). **General Ad Server Requirements** You can find the general ad server requirements [here](/retailer-integration/docs/integration-process#general-ad-server-requirements). *** ## Recommended API Call Practices ### Make Ad Calls on Every Page Load Whenever possible, implement API calls on every page load to ensure comprehensive data collection, accurate attribution, and optimal ad delivery. This documentation does not distinguish between `mandatory` and `recommended` events. Each event contributes differently to performance, attribution, and data completeness. While some events are described below as **recommended**, many of them are critical for correct performance, attribution, and model accuracy. Not implementing these events may lead to: * degraded campaign performance * incomplete attribution * incorrect product recommendations ### Understanding the Value of Each Page Type If calling the API on all page types is not feasible, the descriptions below explain the role of each page type and the impact of not implementing it. #### Search pages Capture strong intent signals based on user-entered keywords. Search pages significantly contribute to building and optimizing the keyword model for Sponsored Products. Even if you do not plan to show ads on search pages, integrating them (along with PDP and Add-to-cart events) is recommended. #### Category pages Provide mid-funnel browsing signals and help Criteo understand product discovery behavior across your catalog. When used together with Search pages, Category integrations give the algorithm a fuller view of the user journey, even if ads are not displayed on these pages. #### Add-to-cart events Essential when your e-commerce platform allows users to add products directly to the cart without first visiting the product detail page. These events supply strong purchase-intent signals, improve the keyword model, and allow you to build audiences based on cart activity. #### Product detail pages Provide detailed product-level engagement signals and enable real-time updates on product availability and pricing. Without this event, there is a risk of outdated product information appearing in ad responses, including out-of-stock products. Implement this event even if ads are not displayed on product detail pages. #### Transaction pages Enable accurate attribution and are required for a functioning integration. Missing transaction events will prevent conversion tracking and significantly impact optimization and reporting. #### Homepage Often has the highest traffic volume and can support campaigns relying on broad audience reach and post-view attribution. #### Checkout pages Provide visibility into cart contents and help improve product recommendation logic for users nearing purchase. *** # API Endpoints Criteo’s Retail Media ad delivery system offers **three distinct endpoints**, each tailored to specific regions. These endpoints ensure that the closest data center is utilized based on the location of your servers. ## Endpoint Structure 1. **Host**: `d.[region].criteo.com` * Supported regions: * **EMEA**: `eu` * **AMERICAS**: `us` * **APAC**: `as` 2. **Path**: `/delivery/retailmedia` 3. **Scheme**: Always `https` 4. **Query Parameters**: Described in \[API Parameters]\(doc:api-parameters-1 *** ## Possible Endpoints * **EMEA**: `https://d.eu.criteo.com/delivery/retailmedia?[parameters]` * **AMERICAS**: `https://d.us.criteo.com/delivery/retailmedia?[parameters]` * **APAC**: `https://d.as.criteo.com/delivery/retailmedia?[parameters]` *** ## Usage Guidelines * Use the endpoint based on where your API calls will originate, not where your users or your frontend are located. * If you are unsure of which endpoint to use, please ask your technical account manager for guidance. ***
## What's next * [API responses](/retailer-integration/docs/api-responses) * [API parameters](/retailer-integration/docs/api-parameters-1) # API Parameters Source: https://developers.criteo.com/retailer-integration/docs/api-parameters-1 These parameters are valid for all event types and should be included in all ad requests wherever applicable # Global Criteo Parameters ## `criteo-partner-id` **Example**: `12345` **Description**: The key that corresponds with your specific partner ID within Criteo. This ID will be provided by your technical account manager. **Required**: Yes *** ## `retailer-visitor-id` **Example**: `39573958738533503` **Description**: A unique unauthenticated UserID that is persistent across sessions on the same device. For Android apps, we recommend using the [AdvertisingIdClient API](https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient.Info), and for iOS, the [advertisingIdentifier](https://developer.apple.com/documentation/adsupport/asidentifiermanager/advertisingidentifier). If it is set as a first party cookie, it should be set as a cookie with an expiration date (maximum 13 months) and not as a session cookie. The lifetime of the cookie must be at least 30 days with longer lifetimes being more effective for attribution. **Required**: Yes **Why it matters?** This identifier represents the Retailer's first party ID which helps Criteo in mapping user activities across sessions, on same device, even when users are not logged in. It should have a certain minimum lifetime and it is used for tracking and targeting purposes on the Retailer's website - it doesn't bring value on the open Internet. *** ## `customer-id` **Example**: `9445678` **Description**: The ID of the authenticated user that is consistent in all logged sessions. It is important that the ID is the same across sessions and devices. The customer ID allows for cross-device attribution by connecting sessions on different devices. You must continue to include a `retailer-visitor-id` when adding this parameter. **Required**: Yes, if the user is logged in. If the user is not logged in, this parameter should be left empty. **Why it matters?** Compared to the Retailer Visitor ID for guest users, the Customer ID is used to identify authenticated/logged-in users. This identifier represents a unique user in a client's CRM and it helps us track activities on different devices and to create links between same domain identifiers. *** ## `email` **Example**: `eb2ddfd95044b8da411dda8828ce123d52ccbc223a75e4f7e550f7188a758ae6` **Description**: The user’s email address, in SHA256 hash format. Before hashing, email addresses should be trimmed (i.e. removal of all spaces before and after the email address), cleaned (i.e. removal of comas, semicolons, quotes or double quotes), and converted to lowercase. **Required**: Yes, if discussed with your Criteo team. **Why it matters?** The `email` parameter provides a stable and persistent identifier that can improve user recognition across sessions. Unlike other identifiers that may change frequently (such as cookies or device-based identifiers), email-based identifiers can remain consistent over time, helping improve data continuity and attribution quality. Providing this parameter improves user matching and measurement accuracy, particularly in environments where other identifiers are limited or unavailable. *** ## `page-id` **Example**: `viewCategory_API_desktop` **Description**: The ID of the page provided by your Criteo team. **Required**: Yes *** ## `placement-id` **Example**: `Carousel|In-Grid` **Description**: A pipe-separated list of placements that are tied to the above page ID **Required**: No, only leverage this if you do not intend to render all the associated placements. *** ## `nocall` **Example**: `oa`, `pd`, `both` **Description**: Filter out sponsored products, commerce display, or both in the Delivery API response. * `oa`: Filter out **sponsored products** * `pd`: Filter out **commerce display** * `both`: Return no ads **Required**: No *** ## `regionId` **Example**: `42` **Description**: Store ID selected by the user when browsing the retailer’s site. It should match the store IDs in the product feed. See more details [here](/retailer-integration/docs/product-feed-parameters#additional-attributes). **Required**: Yes, if Store IDs are defined in the product feed. *** ## `implementation` **Example**: `S2SAPI` **Description**: The type of API client used. If you are updating an existing implementation, please check with the Criteo team which value to set. **Required**: No, this string indicates which implementation was used and is useful for debugging and monitoring purposes. *** ## `json` **Example**: `json` **Description**: Specify the type of response sent back by the Web Service. **Required**: No, only if JSONP is needed. *** ## `item-whitelist` **Example**: `123abc|456def|789ghi` **Description**: Provides a pre-determined list of SKUs for Criteo to include in the auction (only for sponsored products - not display formats). Used to power recommendation engine placements. Provided that the specific page has been enabled for rec engine by your Technical Account Manager, this parameter will force Criteo to *only* evaluate this list of SKUs in our auction. If the parameter is left empty or removed, the page will function normally, and Criteo will conduct a standard auction on all eligible products. **Required**: Yes, if discussed with your Criteo team. *** ## `verbosity` **Examples**: * `min` * `full` **Description**: Change the verbosity level of product objects in the API response. See the [API Responses Guide](/retailer-integration/docs/api-responses#product-array-verbosity-levels) for examples of both levels of verbosity. **Required**: No *** # European Parameters These parameters are specifically for users in Europe and are related to GDPR compliance. *** ## `gdpr` **Example**: `1` **Description**: Indicates if GDPR applies to this user. (1: yes, the user is in Europe and GDPR applies; 2: no, the user is outside Europe). **Required**: Yes, if using TCFv2 standard. *** ## `gdpr_consent` **Example**: `CAGgAagBEADEAIQAfoBAwCEAFXALqAYEAwgBtAEegJiAXmAyQAA.IGSQJwABAALAAeEAE6ALgAY4A0AB-gEDAIQIA2gCPQEvAJiAT-AZAZI` **Description**: The encoded TCFv2 consent string. **Required**: Yes, if using TCFv2 standard. *** ## `block` **Example**: `1` **Description**: Value "1" is for opt-out users. (Value "0" can also be passed for opt-in users.) **Required**: No, only when the user is opt-out and not using the TCFv2 standard. *** # In-app Events These parameters are specifically used for in-app events. ## `device-id` **Example**: `e4dd94d1-d048-4ad3-92b5-d97e688f724f` **Description**: A unique, anonymized string of letters and numbers that identifies a mobile device. For in-app traffic, provide either the [Google Advertising ID (GAID)](https://developer.android.com/identity/ad-id) for Android or the [Identifier for Advertisers (IDFA)](https://developer.apple.com/documentation/adsupport/asidentifiermanager/advertisingidentifier) for iOS. **Required**: Yes, if Offsite is activated. *** ## `device-id-type` **Example**: `gaid` **Description**: Indicates the type of identifier passed in the `device-id` parameter. Use the value `gaid` if `device-id` contains a [Google Advertising ID (GAID)](https://developer.android.com/identity/ad-id) for Android, or `idfa` if it contains an [Identifier for Advertisers (IDFA)](https://developer.apple.com/documentation/adsupport/asidentifiermanager/advertisingidentifier) for iOS. **Required**: Yes, if Offsite is activated. ***

## What's next * [Homepage](/retailer-integration/docs/homepage) * [Search pages](/retailer-integration/docs/search-page) * [Search bar dropdown](/retailer-integration/docs/search-bar-dropdown) * [Category pages](/retailer-integration/docs/category-page) * [Category flyout](/retailer-integration/docs/category-flyout) * [Product details page](/retailer-integration/docs/product-details-page) * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # API Responses Source: https://developers.criteo.com/retailer-integration/docs/api-responses ## Response Format * **JSON format**: The API response is in JSON format. * **Response content**: The response will contain: * **placements**: Information about where ads should be placed. * **list of products**: A list of products to be shown. * **beaconURLs** : URLs for tracking events, detailed in [Beacon URLs](/retailer-integration/docs/legacy-universal-beacons). * **Display formats**: For display formats, the response may include extra information such as rendering details and links to image or video files. Refer to [ad formats overview](/retailer-integration/docs/format-overview) for examples for each format. * **API response structure**: For a detailed description of the API response structure with examples, please refer to the specific format pages in our Ad rendering section. *** ## Breaking Down the API Response Let's take a closer look at the structure of the API response, breaking it down into its components: ```json theme={null} { "status": "OK", "placements": [ { "viewHome_API_desktop-InGrid": [ { "format": "sponsored_products", "products": [ { "ProductId": "14567", "ParentSKU": "14567P", "OnLoadBeacon": "//b.us5.us.criteo.com/rm?rm_e=wIGSZXHwMFfCseG77HQd7SOaa5ItlchfEV7FsVRFvOvgCGeZNp4PqqdyMqxupiThhgJKvudYpqpi2qQjLshpQLDUSU91x_Cjx5XcX8nh40S5kaxVRk3hme-iiwO9yA8xoZpGo_6NMh4Hik96Dp6KGLSB7V1peSCN34LwnicW-3lpd6HrCirUltMP6KDMNCASCJAC2QCCoygwvbX34niecaFID9gsFPkj3gV4dZRDGjZM9GtQbWp7U-E-k4aKjRZy4prcGaQZCUcSY_e1F9yjchB_zrZMeGiNbBiA2eJ-UonqowH6CYjLdqBlO7aHpC9igyDOTh4eb1G1PX_8tBeKJFKi5JRXEALqnXns4_OD9XRqPwJY0mHLkgDDVCopXr9ecWAC_X0UyBy_GfJd79U2hVl6WZKdmXgIhNjeh3eanlk&ev=4", "OnViewBeacon": "//b.us5.us.criteo.com/rm?rm_e=bay40713qtFIdj5P3YUhlfmJUf3bROAa3nby5U-aG8oJFEZO97wjWJ636jKfXNwwvPJxrgYvdcz3zEz2evMvaHNA0H4JriwRyTbqtFHXX1LtPCIQBibPujZpj-3s_yU9kP8SK0Th-KP9_nGXZI2b7QljQaSx8O0-xDdchB59AIBWKq3QSWcnF9Vewy-QfXUDio8q-3w1xgNHXWvPk_uhZGkaY9VTVMQINJBCT8bvxW0GMaYu0vAoIlaac1dKEC580Jzfw35iE3-LtX7w5CLlRaThsZxpWkDcmF0gxACGQg9lQCmGYevs5ePQ79dqB3ZuMIpWjXVTSwJTTvDc81hgnui1GoCN-8IjAt3zKKE3YZp7hDyxgV277J2IjQwWOhE8sBnl6B-ctSmPnp3HEzFFnqPiG5-9Iu-jy3Z9aeE5UF8kRAG1OBmfoH79xUPytz_n&ev=4", "OnClickBeacon": "//b.us5.us.criteo.com/rm?rm_e=HvNOO3VNgpKc4t6hdzi5OAX7aDUv4sYuvdcTL5pUPE-XcJvJKB9WA6U8cq-1VS2XYZo86Pcxj3SErB8R0eIwlLCYDIF2CZziNqca05mYyzZS9x4fRJRQgsOP0kbde6nLQ0S6z0Ea5tiL_4IlFcZ5hB6MNE1QCvmQdYS03i8Gku5Z74pxdw02QTywvhNvHZx8kJM4bwxL_KodVHjUQPXdwVzqdmUL2zeR4psWq3sLxym3Ep0ggsC89yD0yaVfZq4TDe1E59aDSszAWF3D7DgLlNJn2lhSSbhKpAJ_CnRWuW85vdtlyKzkAjf4Uqifp5CeGv9ea7B07SmGrR5d_-U7s9nOgphrLbTr91MvhCWSp0kuDEr8x9g3J6LmGzuLcM8Kbhx0LqaQkFDue1O1X-7LY9ducQKiaL7OLmkdIKX9urZBZeqSVyeqyqrs6D8PgcnObN80v6Lyo9xxsBsB5IMFig&ev=4", "OnBasketChangeBeacon": "//b.us5.us.criteo.com/rm?rm_e=wa79g8gomUj1xr_Krt1d4PNDKNe7Z9UMNndzrp1fMOR0zM_mowG2NiTkL6RtRYtcTaTULrRn9Uooy5rgED3l6Pf3X8gQTx2-YkPD3H0j8yvzbR4xg7SUTjSiEf_rebYfDCAHm39wt_WI6Q2yzJ8BxKdeCJBLXqA7nC4j4EqQZMbZbJ8RFSapMc0WrzQQwoPHZOCWN0KBvGTw3xC-cKjFE_7hdThHUlfIpGnuBjoGZxyQEbVjrcKKpIGkgO8gSrY-oR0KF5kvr2KroG1RFjthJtrJmRwL6cSlCk9E0HZb7wB-kjEHkXmHGtshpIOs2TIar4qbO49tGbCvxMezm7aSYEChwxAn1nHzqyDvzQUNvesnD6yymkV8wiqzj_X55uJD5dgB2otncgc-tqClKWjDUTi3g5uWPskEuZsRkcGU8sN3oMsdDhBmYf-rt6nVWUiAGLvlaumN-vcikE-KGurgHg&ev=4", "OnWishlistBeacon": "//b.us5.us.criteo.com/rm?rm_e=yqlwecnAoAcbFsxAXvx18BXQIwjUPEXgk98r3SFucMNY_RgF8izSxEJ34yjJV8EmU6j6IdXvV97At15ctkGsZ2UyUb_B4nBd9V5TTSMLYsleiVAUDa7xZmv4gnpjRBD9AZWaICw0AVOd_uBMVNN_jqenDBVcqeQw6nYARfP3T_C1jt-MkEPjKJx2PXDsWjfUFsMu0DSVoHxp17KMH4BsOOXObYVDTRrle3VogbXiQDaQ84M5Xk0QQC05z2Wp58ntk5Y44eXn7WBlLKor9QbCxSe-ESzzOP2tK5UOCkowZXI2vd2uLdTTuoBMMSkuiYlVjeLqZ7-LxO2hyT6QHJ3kQhhunCPi5t1oVmxASV1UHD94TOCUso4CbPjlT7-TDomzIgnOkXQgvjNxrV4OiSqCEZxltZlM-KUHzlfUAW6ucNNSqmdaaP9dFHNT9Pcziicui79ymAtYSzidQcE3y10xew&ev=4" } ], "rendering": "", "OnLoadBeacon": "//b.us5.us.criteo.com/rm?fid=1205&hl_qs_cmp=5uA4RAAyB4_gprioo3H-TBRN1xWe0MfgzXEjDuXPJRxh43LMFIqbvqmUpWL-X1QaLZsBnjLZmQOO8VDv8AygNKeBIrAOdc3BAt58fPXXmvpZ1X6RIwlB9ABNmCB43n9uUhqdEWeaVl03KA3L6Erk36jfiK4dJH6JwLEeIj5rUmr77DYYcqwDazIQ_-rVIABST9nVzoqvJ4spgBJ1sx0H6r_IrbD2m2GquySbzP5gA1TaSn1ZshWlpVU_N0-VwQYGIVVDlORAMWV-WUV0IBWDciC92ygwabmVl2VQrZirzdEAXDR3Y8mgd8DDtwmEbSdgf0AhF65RIhr06ZfgFMSQtXGJPLhoXibnWaj9UKxnUuCLQtjxeMBaT4Wj_qSTy13Cnzy5b7hU36GPd0nt4O44L2sC4BcoyUlZGwoM-iSCDQekIsiWyQINJERV-mzvx9lnCzThW6g85leDyWRy-ypa19Qykz_jP8lWFgB_QLit5jrW7jNDUZGN3QJwFIsBlur7VQueQ4D4CY_b9WNm4tNT9poaGyfas7X9bALmCGStKFSEcGfyEQsuivryHobe7zhNHYSSew_erOiS_gjRffOUHw&ev=4&criteopartnerid=108341&action=page&origc=A&pid=a0396133-15e5-4d8d-a0d7-7e636a0c9629&rn=96592&rm_e=0sSztFiVbHNTsuwnq1PB8pqDUAnR6K4NdhFvWiYIq46QV070UizTxdway_uMmQbJGIHCAk0ZsvRTcBKEPcv6hGrkQC0PfFdL7rRy-ESWSHrMsZn7-9KuKYThNMCgkbDzP1pKiEBh_MrkPbvTaPZBKm9KqW3zIzVDp4v8DgIiAe0-5fhKlVsNPATbNaBedHtDfZhzNyCRnVisUpFQUifH9NRcIAxn7xfaFM7ZzvDheiI2S3Eq4cfBzRDRAXU_aCA0DLOq9pRvyLuzT-QFDpmI3A", "OnViewBeacon": "//b.us5.us.criteo.com/rm?rm_e=nZujoEOA40DwXsc-kV2o_ygnxWqQwguOzRYIKHC7LJ4Nj1jBk8k5rgTQ3b8GtfylnH6eB7y4ggvPyWft8SlXxwWH08y4GhwC-1rsq0fWbLx9F_LjVF3gdtaa_UQ5PvpjyWCLyPL5kJaj9Mbud8aXX9_7HgVjBlO6lAvEkiElMoTUzfUhRLzlBdSxYePuAOBilAFMtJ3abkHgmowMLKaK1a4tVBoK0YHexHMZ0zONVqOXjwYqx19-hgRcUyFQ6uCulio9LRmFSlflBkEWiNRQ-AHOB2vVwkkE5xOgKcEN8XWRLz1b-hYfn5ECK1Gff0D9JM6eLD1EOOSNB0jt8LPxPSG5u48q4CLAIK59MYDJXIkEJ3nS9b_OYpJ8GoDFfuB5&ev=4", "OnClickBeacon": "" } ] } ] "page-uid": "7f0b8394-f87f-438f-bf4a-b2aeae1e3144" } ``` *** ### Response Components 1. **`status`** * Type: `string` * Values: `OK` (for successful responses) or an error type. * Example: `"status": "OK"` 2. **`placements`** * Type: `array` * Description: An array of placement objects, each representing a specific ad placement on the page. 3. **`page-uid`** * Type: `string` * Description: A GUID value identifier for each ad request. * Example: `"page-uid": "7f0b8394-f87f-438f-bf4a-b2aeae1e3144"` *** ### Placement Object Each placement object contains the placement Name as the single key for the object, e.g., `viewCategory_API_desktop-inGrid`. Inside each placement, we have: * **`Format`** * Type: `string` * Description: The type of ad, e.g., `sponsored_products`. * **`Products`** * Type: `array` * Description: An array of product objects. * **`Rendering`** * Type: `string` * Description: rendering details used for commerce display ads. * **`OnLoadBeacon`** * Type: `string` * Description: URL to be called when the whole placement is loaded. * Example: `"OnLoadBeacon": "//b.us5.us.criteo.com/rm?fid=1205&hl_qs_cmp=&ev=4&criteopartnerid=108341&action=page&origc=A&pid=a0396133-15e5-4d8d-a0d7-7e636a0c9629&rn=96592&rm_e=abc123def4"` * **`OnViewBeacon`** * Type: `string` * Description: URL to be called when the placement is viewed according to IAB guidelines. * Example: `"OnViewBeacon": "//b.us5.us.criteo.com/rm?rm_e=abc123def4&ev=4"` * **`OnClickBeacon`** * Type: `string` * Description: URL to be called when the placement is clicked. This is only used on commerce display ads, and it is typically triggered on clicks on the ad's image as opposed to the product inside the ad. * Example: `"OnClickBeacon": ""` *** ### Product Object Each product object contains: * **`ProductId`** * Type: `string` * Example: `"ProductId": "14567"` * **`ParentSKU`** * Type: `string` * Example: `"ParentSKU": "14567P"` * **`Beacons`** * **`OnLoadBeacon`** * Type: `string` * Description: URL to be called when the product is loaded. * Example: `"OnLoadBeacon": "//b.us5.us.criteo.com/rm?rm_e=abc123def4&ev=4"` * **`OnViewBeacon`** * Type: `string` * Description: URL to be called when the product is viewed according to IAB guidelines. * Example: `"OnViewBeacon": "//b.us5.us.criteo.com/rm?rm_e=abc123def4&ev=4"` * **`OnClickBeacon`** * Type: `string` * Description: URL to be called when the product is clicked. * Example: `"OnClickBeacon": "//b.us5.us.criteo.com/rm?rm_e=abc123def4&ev=4"` * **`OnBasketChangeBeacon`** * Type: `string` * Description: URL to be called when the product is added to the basket. * Example: `"OnBasketChangeBeacon": "//b.us5.us.criteo.com/rm?rm_e=abc123def4&ev=4"` * **`OnWishlistBeacon`** * Type: `string` * Description: URL to be called when the product is added to the wishlist. * Example: `"OnWishlistBeacon": "//b.us5.us.criteo.com/rm?rm_e=abc123def4&ev=4"` *** ## Monitoring the Auction Latency The API response includes a `Server-Timing` header which indicates how many **milliseconds** the auction took to run. This can be used to monitor server latency and break the auction part from the full round trip between ad request and response. #### Sample Request ```shell theme={null} curl -I "https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341&retailer-visitor-id=456&customer-id=789&page-id=viewSearchResultApiDesktop&event-type=viewSearchResult&keywords=drink" ``` #### Response headers ```shell theme={null} HTTP/2 405 date: Mon, 31 Mar 2025 14:19:56 GMT server: Kestrel access-control-expose-headers: Server-Timing allow: GET timing-allow-origin: * server-timing: total;dur=1.2 strict-transport-security: max-age=31536000; preload; ``` In this example, the auction took 1.2 ms to run. *** ## Product Array Verbosity Levels Criteo supports two verbosity levels: * **Minimum verbosity** * Contains: `ProductId`, `ParentSKU`, beacons (`OnLoadBeacon`, `OnViewBeacon`, `OnClickBeacon`, `OnBasketChangeBeacon`, `OnWishlistBeacon`). * **Full verbosity** * Contains: All information from minimum verbosity plus additional details necessary to render the ad. All details are reflected from the [product feed parameters](/retailer-integration/docs/product-feed-parameters). Here is an example of a product object in full verbosity: ```json theme={null} { "ProductName": "Product 16823", "ProductId": "16823", "ProductPage": "//b.us5.us.criteo.com/rm?dest=https%3a%2f%2ftilt-dummy-retailer.preprod.crto.in%2fpdp%2f%3fid%3d16823&sig=1-OxTyYEct2uXeVQw334Q7rhli3hjJSfL-t1eGN0YS-2A&rm_e=uel8HURJNMmUz12YtgzGAeSR-psXmQFLCnVtykXin5b5LlMOlwR9k1w4PnZ93nTwLSLRM8h_OVK_nPLkK84uY4wBFzIx8x9AxzThTINQ0fpTsiJt_tTMuHfyLNG47gWwg5f6dDZons5DMKmZEjVsNAGmsiLF7YpZb8lFAmqaKyx8B9qIZJatI7ApL7VCCO1NAv6bvz6EQ1tvPDcZc6kY7cw5uLT5egrtd3Nupj5vJ6R_PQy-jmS5rEcmViA_Yf5AcP-teeD_wY3x59nlISoZP-sLqIksWuUr0QRfF8Z6DnR3ZQzunCi5PONmLtM1zSgOCHFj4fyf-A3GbbLe1kJdNyQtS7PZAsR04DDYAg5QEMzJoGcZGS7VVH_h5bLnF4dArQuIUamTFePufu7tmYxQvA&ev=4", "Image": "https://static.criteo.net/images/dummyretailer/glob_prod_img.png", "Rating": "-1", "Price": "69.00", "ComparePrice": "69.00", "Shipping": "0", "ParentSKU": "16823", "ClientAdvertiserId": "1205", "AdvertiserId": "17902833", "RenderingAttributes": "{\"brand\":\"retailer brand 1\",\"issellersku\":\"0\",\"mapViolation\":\"0\",\"numberOfReviews\":\"0\",\"promolabel\":\"Promo Badage blackFriday\",\"rating\":\"2\",\"shippingCost\":\"0\",\"taxonomy_text\":\"fresh foods>fruits>bananas\"}", "OnLoadBeacon": "//b.us5.us.criteo.com/rm?rm_e=qfD_DnfhuYEwJlj-_k6q9vq3rdUT2fgm1U5Srs1XDjS_39fWoZiJx37WMTlWfHNA-8GlrIi71W1MM4_cU_3kzxoNYzoPKWR0mFaKYJE-p5owUCOIv4-MBbjlAWCV2SlSN3xE3C7MMhZQ8IX6w1OrYPBowzevmAB0Wx3NvcvhrIILIeDQllspyDbSWlOkR-yCQ4wML_zpcAGS5AK2g-UhJrHp_eSfNK6FE92cd2W7tXnAvOr0S_TJES6-osdVfqAcaGyWFlZ7R9Wj5YJQEQizkbg8KQBBTVpaqyI0VjuQJWGtKve9i525uiAW5DVQqIqnh-M6e7zwbP_A3A8IW3rDBE1mkNoYG6bC3em7viLzrTqMKvxBItREk7tkBvj835iu-7fXjayMkHvGXxwbHLdbwQ&ev=4", "OnViewBeacon": "//b.us5.us.criteo.com/rm?rm_e=09rCkvAHsrPsZb5M3XQAkVv3Eyk5EZgzcBZuD-SQRT12HynrMYmKnN4bcb5cN2xyWxO8SWnn8HiTEyO5m4xtCorqbG137zd8yPbvztI6ZbUwmwoU2injhkF4LDwMMFMSD8Y93F3dU6wwQlSdeaoeorNat4ka1mnNFLfNgHhREArA5cinPg-MExTIFeJ9BDUg6eKUH6dklezn_j-l-46554KUvaGVLWMoryzy-3tuXDDRFNA-JuUUMzwr-P3EvFw3WECVLDd5YqiQQIV3I3_IQhzSbk0g3L7bJP_rOBQv204U_3X_HYsoMyartqLJMSZ4zP4h_7zZB7fpPODoxVS_vGFNvYN71XeIIMxy0jFJDjvstu2CLo-K4aRVXLKaRR0iCm-ET61GpLPhsOsG_zrAhA&ev=4", "OnClickBeacon": "//b.us5.us.criteo.com/rm?rm_e=MZkmRRi7n5KyhcMFLsf13Qbhf0EwjnF4fERMLUS7N12_OCRXcfTXb2oQJxgIbW0UaFzHpiGR-hZ6w7yXToa9F9KnvlQ1RUhpVsVTHx0WgbtM3RVkw-XRheFJQWPqZZlLTpu0wFd_4L75iVhpzLpuCD9ZJKOJ2bawqjexZd2GmejGMtUtOUmZqxPD-SlXNAJ5lHAOi3hQ4Y4i6aDSFjA03pNXw-f9G4Pg9IQqNMzeN7rC4_gU0gTrpwmq3GvVSlp-6CtZEgZ5zGSbiRULe0hJyGcXXtlVb-y2VoDhTRa6tCb5_4XK3H7vZGYhFYBdMIort7ocWJNfL6SxKXrsGVMAfd4uakLn5M7luXowhnKKfGIzDPIw1K1FKp6XmWxd19QBMPFWLFzBladVoAgDmysFJg&ev=4", "OnBasketChangeBeacon": "//b.us5.us.criteo.com/rm?rm_e=iOGO2y360EsftIgtVtiVHh-SDsf3eE54JVltobiLr4M-sHkWrkErFbvMzvfe41lA2thRTR2kWl0mI4boIKb5sV27rUgDUNsKbhhEaDSVlVVRgayPm7M2jqiYW8fP1f7vTDKLqVCamHeHVkqCVoqGdZoQs_9IsoKLeNbjDS0EE-kl3UK8V1i6hD3zvTQJq9_jACnUttSmO6HN2M_i149DacstUZlOt7_U1JJ7W45b88PFQtYJAqkIX8Sq2t6k9qCaYNlPA1Jg3IIMLq5iRs8IaJw9Mk5dGz6mQAo9fiPPKLIQvZF0OJdIQAEiJ-RA4M-6OYRiMiRv8LvzqQPQlrrKyuAyF3ymPOuX_19vkLmWjpcthAmHGV4lbyjTJ0isZMhSP3v5yyBZ0A_zBTvXmJgevA&ev=4", "OnWishlistBeacon": "//b.us5.us.criteo.com/rm?rm_e=HbZtVCkIeMSvyPh6LXzeA9Cm-e1MGxY13Oi40WSQp5B3Qy_w7EmqQO9garQ0gLHdKN99Zr-pfHZXR6TwlupMYeJ5ALP6UoT2hElxZP5dbXPmZqxiyWbap2IP-18rzkSLAeBnF1vey4jsFTqFGj50A2nDUpEmt9XvYgKBdwUrPvzchXZAMW1aLSz9uz6oycliNYR7Ca866dNd8vA9VzFiU-UNHXgWhRyjyhgiwUeVom4GrzzI95e6R--PzF5PURGaJ3CDWKcVQTKrN8_lx4G3DBTSq0WQEiAKhP4b_Z1-QDrFjbWEwaAOzPh3V5OXQLOzF1zkJ21w_LEmjLaywfoDviS0YaPUoHJsOwp0JX489avZEhy11cW5YuhS3D09AudNqmarl2G3Mg6gYpiOqpDqow&ev=4" } ``` The default verbosity level can be set up by your technical account manager, but it can be changed at anytime using the `verbosity` parameter in the API calls with values `min` or `full`. See the [API parameters](/retailer-integration/docs/api-parameters-1) page for more details. *** ## Beacon Endpoints The beacon endpoint will point to different data centers determined by an automatic load balancer. This will typically be reflected on its subdomain. * **Format**: `b.[datacenter].[region].criteo.com/rm` * **Examples**: * Europe: `b.fr3.eu.criteo.com/rm?rm_e=[unique-token]&ev=4` * Americas: `b.us5.us.criteo.com/rm?rm_e=[unique-token]&ev=4` *** # API Error Responses If an API call is malformed or unable to send a valid response, the API will return a 200 HTTP status with an error message. For requests with incorrect or missing parameters, the response will include `'status': 'Error'` with an array of `'errors'`. ## Example Error Response ```json theme={null} { "status": "Error", "placements": [], "errors": [ "Missing required param page-id", "Missing required param event-type", "Missing required param criteo-partner-id", "Could not convert parameter criteo-partner-id to an integer", "Could not determine a valid event type from the event-type parameter" ], "page-uid": null } ``` The following list, while not exhaustive, covers most error messages you may encounter. Tracking those messages is recommended to identify potential implementation errors. *** ## Possible Error Messages ### Expected one or many numerical values greater than \[or equal to] 0 **Sample call:** ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=123" \ --data-urlencode "event-type=trackTransaction" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "page-id=trackTransaction" \ --data-urlencode "item=abc|def|ghi" \ --data-urlencode "price=249.99|200|400" \ --data-urlencode "quantity=a|b|c" \ --data-urlencode "transaction-id=123458abc" \ --data-urlencode "nolog=1" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` **Error:** The parameter `quantity` has non-numeric values. **Sample response:** ```json theme={null} { "status": "Error", "placements": [], "errors": [ "quantity: Expected one or many integer values greater than 0" ], "page-uid": null } ``` *** ### Expected array parameters to contain the same number of items **Sample call:** ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=123" \ --data-urlencode "event-type=trackTransaction" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "page-id=trackTransaction_API_mobile" \ --data-urlencode "item=abc|def|ghi" \ --data-urlencode "price=249.99|200|400" \ --data-urlencode "quantity=3|1" \ --data-urlencode "transaction-id=123458abc" \ --data-urlencode "nolog=1" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` **Error:** The number of elements in `item` and `quantity` do not match. **Sample response:** ```json theme={null} { "status": "Error", "placements": [], "errors": [ "Expected array parameters to contain the same number of items" ], "page-uid": null } ``` *** ### Required parameter `[parameter name]` was not of the expected format: `[error]` **Sample call:** ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=123" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "page-id=viewItem_API_mobile" \ --data-urlencode "item=abc" \ --data-urlencode "price=299,00" \ --data-urlencode "availability=1" \ --data-urlencode "nolog=1" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` **Error:** `price` incorrectly formatted with a comma as a decimal separator. **Sample response:** ```json theme={null} { "status": "Error", "placements": [], "errors": [ "Required param price was not of the expected format: Expected one or many numerical values greater than 0" ], "page-uid": null } ``` *** ### Could not convert parameter `criteo-partner-id` to an integer **Sample call:** ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=abc" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "page-id=viewItem_API_mobile" \ --data-urlencode "item=abc" \ --data-urlencode "price=299.00" \ --data-urlencode "availability=1" \ --data-urlencode "nolog=1" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` **Error:** The parameter `criteo-partner-id` is always an integer. **Sample response:** ```json theme={null} { "status": "Error", "placements": [], "errors": [ "Could not convert parameter criteo-partner-id to an integer" ], "page-uid": null } ``` *** ### Could not determine a valid event type from the `event-type` parameter **Sample call:** ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=123" \ --data-urlencode "page-id=viewItem_API_mobile" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "item=abc" \ --data-urlencode "price=299.00" \ --data-urlencode "availability=1" \ --data-urlencode "nolog=1" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` **Error:** The parameters `event-type` and `page-id` are switched. **Sample response:** ```json theme={null} { "status": "Error", "placements": [], "errors": [ "Could not determine a valid event type from the event-type parameter" ], "page-uid": null } ``` *** ### Missing required parameter `[parameter]` **Sample call:** ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=123" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "page-id=viewItem_API_mobile" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "item=abc" \ --data-urlencode "price=299.00" \ --data-urlencode "nolog=1" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` **Error:** One or many required parameters for this `event-type` are missing. **Sample response:** ```json theme={null} { "status": "Error", "placements": [], "errors": [ "Missing required param availability" ], "page-uid": null } ```
***
## What's next * [Authentication tokens](/retailer-integration/docs/using-tokens) * [API parameters](/retailer-integration/docs/api-parameters-1) * [Ad request best practices](/retailer-integration/docs/requesting-ads-best-practices) # Basket Page Source: https://developers.criteo.com/retailer-integration/docs/cart-page # Definition The basket page displays **the contents of a user’s current shopping cart**, until the order is placed. *** # Parameters ## `event-type` **Value**: `viewBasket` **Description**: Indicates to the API that this is a view basket event. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements (if any) to return for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewBasket_API_desktop`, `viewBasket_API_mobile`, `viewBasket_API_iOS`, `viewBasket_API_android`. * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewBasketApiDesktop`, `viewBasketApiMobile`, `viewBasketApiAios`, `viewBasketApiAa`. **Required**: Yes *** ## `item` **Description**: The list of SKUs in the cart. Must match the parameter ID in the feed. Multiple items should be separated by a pipe `|` or `%7C` (URL encoded). In basket pages, these are used for targeting. Include all item ids in the cart, regardless of whether or not they are sponsored. **Examples**: * `123|456|789` * `123%7C456%7C789` **Required**: Yes *** ## `quantity` **Description**: The pipe-separated quantities of each SKU within the user’s basket. **Examples**: * `4|1|2` * `4%7C1%7C2` **Required**: Yes *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewBasket_API_desktop" \ --data-urlencode "event-type=viewBasket" \ --data-urlencode "item=123|456|789" \ --data-urlencode "quantity=4|1|2" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ## EMEA ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewBasketApiAios" \ --data-urlencode "event-type=viewBasket" \ --data-urlencode "item=123|456|789" \ --data-urlencode "quantity=4|1|2" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` *** ## Mock retailer API response The API call below will return a response for a mock retailer. ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=108341" \ --data-urlencode "retailer-visitor-id=456" \ --data-urlencode "customer-id=789" \ --data-urlencode "page-id=viewBasketApiDesktop" \ --data-urlencode "event-type=viewBasket" \ --data-urlencode "item=19539" \ --data-urlencode "price=1" \ --data-urlencode "quantity=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` You can see an example of the response [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewBasketApiDesktop\&event-type=viewBasket\&item=19539\&price=1\&quantity=1). ***
## What's next * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Category Flyout Source: https://developers.criteo.com/retailer-integration/docs/category-flyout # Definition A category flyout is a window that appears when a user hovers over different category options from the main browse menu. Each change in category shown in the window will require its own API call, as the desired category changes. *** # Parameters ## `event-type` **Value**: `viewCategoryMenu` **Description**: Indicates to the API that this is a category flyout event. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewCategoryMenu_API_desktop`, `viewCategoryMenu_API_mobile`, `viewCategoryMenu_API_android`, `viewCategoryMenu_API_iOS`. * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewCategoryMenuApiDesktop`, `viewCategoryMenuApiMobile`, `viewCategoryMenuApiAios`, `viewCategoryMenuApiAa`. **Required**: Yes *** ## `category` **Description**: The category or taxonomy of the page that the user is browsing. This value should match the `product_type_key` value in the products feed. **Examples**: * Category ID, full breadcrumb style: `123>4567>89012` * Category ID, end-node-only style: `89012` * Category name style: `Computing>Keyboards and Mice>Mice` **Required**: Yes *** ## `page-uid` **Description**: This value is returned within the response of the initial call made on page load. By storing this value and including it in subsequent `viewCategoryMenu` event calls, Criteo is able to link the events to the initial ad request. **Example**: `545d9a70-f096-4568-b4b9-8f2f32a452d4` **Example Workflow for`page-uid`** : 1. User arrives at the homepage, generating a `viewHome` ad request with a unique `page-uid`. 2. User browses/hovers over categories, generating `viewCategoryMenu` calls. 3. Each `viewCategoryMenu` call must include the initial `page-uid` from the first `viewHome` call. **Required**: Yes *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailervisitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewCategoryMenu_API_desktop" \ --data-urlencode "event-type=viewCategoryMenu" \ --data-urlencode "category=123>4567>89012" \ --data-urlencode "page-uid=545d9a70-f096-4568-b4b9-8f2f32a452d4" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ## EMEA ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailervisitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewCategoryMenuApiAios" \ --data-urlencode "event-type=viewCategoryMenu" \ --data-urlencode "category=123>4567>89012" \ --data-urlencode "page-uid=545d9a70-f096-4568-b4b9-8f2f32a452d4" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` ***
## What's next * [Product details page](/retailer-integration/docs/product-details-page) * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Category Pages Source: https://developers.criteo.com/retailer-integration/docs/category-page # Definition Category pages typically display a collection of products that belong to a specific category or group. Category pages are divided into three types: * **Browse/Category**: A category page that displays a product grid. * **Merchandising**: A category landing page *without* a product grid. * **Deals**: A page for dedicated deals/offers, which might include products from several categories. *** # Parameters ## `event-type` **Value**: `viewCategory` **Description**: Indicates to the API that this is a category request. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewCategory_API_desktop`, `viewMerchandising_API_mobile`, `viewDeals_API_android`, `Category_API_iOS`. * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewCategoryApiDesktop`, `viewMerchandisingApiMobile`, `viewDealsApiAios`, `viewCategoryApiAa`. **Required**: Yes *** ## `category` **Description**: The category or taxonomy of the page that the user is browsing. This value should match the `product_type_key` value in the products feed. See more details [here](/retailer-integration/docs/product-feed-parameters#product_type_key). **Examples**: * Category ID, full breadcrumb style: `123>4567>89012` * Category ID, end-node-only style: `89012` * Category name style: `Computing>Keyboards and Mice>Mice` **Best Practices**: * Category ID is preferred over category name to avoid issues with typos, punctuation, and accented letters (especially in non-English languages). * If opting for category name: * The category name is case insensitive. * Spaces between the separator (`>`) are ignored. **Required**: Yes *** ## `item` **Description**: The list of SKUs that are organically shown on the page in the grid or list. Must match the parameter `id` in the feed (See details [here](/retailer-integration/docs/product-feed-parameters#id)). Multiple items should be separated by a pipe `|` or `%7C` (URL encoded). Used for reporting and for organic deduplication, if enabled. **Examples**: * `123|456|789` * `123%7C456%7C789` **Required**: Recommended, but not required. *** ## `parent-item` **Description**: Only use this if parent SKUs are being passed. Must match the parameter `item_group_id` in the feed (See details [here](/retailer-integration/docs/product-feed-parameters#item_group_id)). Multiple parent items should be separated by a pipe `|` or `%7C` (URL encoded). For SKUs that do not have parent SKUs, `NULL` should be sent instead. Used for reporting and for organic deduplication, if enabled. **Examples**: * `12345P|NULL|456789P` * `12345P%7CNULL%7C456789P` **Required**: Recommended if the ecommerce platform uses parent items *** ## `list-size` **Description**: The total number of organic items on the page. Preferably, it should match the number of item IDs sent in the `item` parameter. **Required**: Recommended *** ## `page-number` **Description**: Represents the page number for either paginated results or scroll fold if products are loaded dynamically. This parameter can be used for result deduplication, by limiting the number of products shown on each page. **Example**: `3` **Required**: Recommended *** ## `filters` **Description**: Corresponds to the filters applied by the shopper on the results. See the filter section for details on how to use this parameter. **Examples**: * `(price,le,100)` * `(color,eq,blue)` **Required**: Recommended. If not used, the ads will not follow the selected filters and might result in a poor user experience. *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## Browse/category ### AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewCategory_API_desktop" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "category=cat12345" \ --data-urlencode "item=123|456|789" \ --data-urlencode "page-number=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` ### EMEA ```bash cURL theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewCategoryApiDesktop" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "category=cat12345" \ --data-urlencode "item=123|456|789" \ --data-urlencode "page-number=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ## Deals ### AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewDeals_API_iOS" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "category=Top_Deals" \ --data-urlencode "item=123|456|789" \ --data-urlencode "page-number=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` ### EMEA ```bash cURL theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewDealsApiAios" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "category=Top_Deals" \ --data-urlencode "item=123|456|789" \ --data-urlencode "page-number=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` *** ## Merchandising (EMEA `page-id` style) ### AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewMerchandisingApiAa" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "category=cat12345" \ --data-urlencode "item=123|456|789" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_android 3.2.1" ``` ### EMEA ```bash cURL theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewMerchandisingApiAndroid" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "category=cat12345" \ --data-urlencode "item=123|456|789" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_android 3.2.1" ``` *** ## Mock retailer API response The API call below will return a response for a mock retailer. ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=108341" \ --data-urlencode "retailer-visitor-id=456" \ --data-urlencode "customer-id=789" \ --data-urlencode "page-id=viewCategoryApiDesktop" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "category=Shoes" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` You can see an example of the response [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewCategoryApiDesktop\&event-type=viewCategory\&category=Shoes). ***

## What's next * [Category flyout](/retailer-integration/docs/category-flyout) * [Product details page](/retailer-integration/docs/product-details-page) * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Favorites Page Source: https://developers.criteo.com/retailer-integration/docs/favorites-page # Definition Favorites/wishlist pages are pages where users save their favorite products to be viewed later. *** # Parameters ## `event-type` **Value**: `viewFavorites` **Description**: Indicates to the API that this is a favorites/wishlist event. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return (if any) for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewFavorites_API_desktop`, `viewFavorites_API_mobile`, `viewFavorites_API_android`, `viewFavorites_API_iOS`. * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewFavoritesApiDesktop`, `viewFavoritesApiMobile`, `viewFavoritesApiAios`, `viewFavoritesApiAa`. **Required**: Yes *** ## `item` **Description**: The list of SKUs that are saved as favorites. Must match the parameter ID in the feed. Multiple items should be separated by a pipe `|` or `%7C` (URL encoded). **Examples**: * `123|456|789` * `123%7C456%7C789` **Required**: Yes *** ## `parent-item` **Description**: Only use this if parent SKUs are being passed. Must match the parameter `item_group_id` in the feed (See details [here](/retailer-integration/docs/product-feed-parameters#item_group_id)). Multiple parent items should be separated by a pipe `|` or `%7C` (URL encoded). For SKUs that do not have parent SKUs, `NULL` should be sent instead. Used for reporting and for organic deduplication, if enabled. **Examples**: * `12345P|NULL|456789P` * `12345P%7CNULL%7C456789P` **Required**: Recommended if the eCommerce platform uses parent items *** ## `price` **Description**: The list of prices in the same order as the items. Prices should be separated by a pipe `|` or `%7C` (URL encoded). These need to be the unitary prices (price of an individual item). **Examples**: * `29.99|15.49|9.99` * `29.99%7C15.49%7C9.99` **Required**: Yes *** ## `quantity` **Description**: The pipe-separated quantities of each SKU within the user’s favorites/wishlist. **Examples**: * `4|1|2` * `4%7C1%7C2` **Required**: Yes *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewFavorites_API_desktop" \ --data-urlencode "event-type=viewFavorites" \ --data-urlencode "item=123|456|789" \ --data-urlencode "price=29.99|15.49|9.99" \ --data-urlencode "quantity=4|1|2" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0 ``` *** ## EMEA ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewFavoritesApiAios" \ --data-urlencode "event-type=viewFavorites" \ --data-urlencode "item=123|456|789" \ --data-urlencode "price=29.99|15.49|9.99" \ --data-urlencode "quantity=4|1|2" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` ***
## What's next * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Feed Best Practices Source: https://developers.criteo.com/retailer-integration/docs/feed-best-practices ## Filters Retailers can enhance the user experience by [integrating filters in the product catalog](/retailer-integration/docs/product-feed-parameters#filters) and [applying them dynamically](/retailer-integration/docs/filtering) onsite when selected by users. Almost all modern e-commerce product listings allow the shopper to select filters to narrow down the results to the most relevant products. Criteo can mirror any filters provided by your business, but for that, we need to know which filters apply to which products. In particular, make sure to reflect the filters you business provide in the product catalog you send to Criteo. All available filters that can be applied onsite should be included in the product feed and shared with us. **Benefit** By showing only the most relevant products, we provide the best user experience and campaign performance. *** ## Region-Specific Data For sites that allow users to select a specific store with limited product availability, **retailers should include the local inventory in the product feed per product**. You can send region-specific data as the [`regiondata` parameter](/retailer-integration/docs/product-feed-parameters#regiondata) or as a separate [local inventory feed](https://help.criteo.com/kb/guide/en/using-a-local-inventory-feed-zYwi3Leylx/Steps/775588). **Benefit** Ads will only showcase products available at the selected store, improving **relevance.** *** ## Multiple Categories Make sure that the parameters [`product_type`](/retailer-integration/docs/product-feed-parameters#product_type) and [`product_type_key`](/retailer-integration/docs/product-feed-parameters#product_type_key) reflect **all** categories of each product in your ecommerce. If a product is eligible to multiple categories, you can separate multiple values for these parameters separated by a comma (`,`). The values on [`product_type_key`](/retailer-integration/docs/product-feed-parameters#product_type_key) should coincide exactly with the value in the parameter [`category`](/retailer-integration/docs/category-page#category) sent to Criteo's Delivery API call or [OneTag event](/retailer-integration/docs/onetag#browse-page). **Benefit** By knowing the correct categories: * Criteo is able to build a better keyword model customized to your business * Advertisers will have access to the correct category listing on their campaigns * Ads will perform with their best relevancy *** ## Keep your Feed up to Date Ensure that you upload your catalog data at least daily. If your product data changes constantly, consider using the [Product Importer API](/retailer-integration/docs/product-importer-guide) allows for close to real-time sku-level updates. If you opt to upload a daily feed file to Criteo's SFTP server, we recommend appending the upload date in the format `_yyyy-MM-dd` to your file and keep it in the server for up to 30 days, so we can perform audits. E.g. `my_product_feed_2025-09-18.csv` **Benefit** Up to date product data ensures a good user experience and avoids displaying ads with incorrect prices or products that are out of stock. ***
## What's next * [Feed upload guide](/retailer-integration/docs/product-upload-guide) * [Product Importer API guide](/retailer-integration/docs/product-importer-guide) # Homepage Source: https://developers.criteo.com/retailer-integration/docs/homepage # Definition The homepage is **the initial landing page of the website**. When making API calls for the homepage, the parameters described below should be used. *** # Parameters ## `event-type` **Value**: `viewHome` **Description**: Indicates to the API that this is a homepage request. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewHome_API_desktop`, `viewHome_API_mobile`, `viewHome_API_android`, `viewHome_API_iOS`. * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewHomeApiDesktop`, `viewHomeApiMobile`, `viewHomeApiAios`, `viewHomeApiAa`. **Required**: Yes *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewHome_API_desktop" \ --data-urlencode "event-type=viewHome" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ## EMEA ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewHomeApiAios" \ --data-urlencode "event-type=viewHome" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` *** ## Mock retailer API response The API call below will return a response for a mock retailer. ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=108341" \ --data-urlencode "retailer-visitor-id=456" \ --data-urlencode "customer-id=789" \ --data-urlencode "page-id=viewHomeApiDesktop" \ --data-urlencode "event-type=viewHome" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` You can see an example of the response [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewHomeApiDesktop\&event-type=viewHome). ***
## What's next * [Search pages](/retailer-integration/docs/search-page) * [Search bar dropdown](/retailer-integration/docs/search-bar-dropdown) * [AI assistant](/retailer-integration/docs/ai-assistant) * [Category pages](/retailer-integration/docs/category-page) * [Category flyout](/retailer-integration/docs/category-flyout) * [Product details page](/retailer-integration/docs/product-details-page) * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Integration process Source: https://developers.criteo.com/retailer-integration/docs/integration-process An overview of the integration process using the Direct API method ## Overview To leverage all features offered by Criteo's Retail Media platform, it is necessary to integrate with the **Retail Media ad delivery system.** The Direct Ad Server integration entails three main steps that are detailed in this documentation: 1. Requesting ads 2. Rendering ads 3. Tracking ads The **Direct Ad Server Integration** is also referred to as the 'Direct API method', 'Delivery API method' or simply as 'API method'. It follows the process illustrated below: The Direct Ad Server integration process This is the preferred and recommended integration process. If for some reason you are unable to follow the given process, there could be alternative ways to integrate in which case you should reach out to your Criteo technical representative. *** ### Step 1: Requesting Ads When a user browses the retailer’s website and reaches a page with ad placements, an API call to request ads is triggered. This call, known as a Bid Request or Ad Request, is made from the retailer's site (server-side or client-side) to Criteo's servers via the Criteo Delivery API, allowing us to deliver the most relevant ads to the user. We detail the general ad server requirements [below](/retailer-integration/docs/integration-process#general-ad-server-requirements), [API calls](/retailer-integration/docs/api-calls) , [response formats](/retailer-integration/docs/api-responses), as well as [how to use tokens](/retailer-integration/docs/using-tokens), and the [full detail of all API parameters](/retailer-integration/docs/api-parameters-1) in the **Requesting Ads** section. *** ### Step 2: Rendering Ads Once an ad has been requested, Criteo will run an auction based on the campaigns that have been set up and the present campaign settings, also taking into account the information provided in the API request. The results are the product IDs (SKUs) to show in ads alongside associated tracking beacons. The API response will return specific product, placement and beacon details in JSON format. The Retailer then handles the rendering of the ad, checking for the price, image, and name of the product and displays it on their website. We provide a [full format overview](/retailer-integration/docs/format-overview) and the details of the rendering for each format in the **Ad Rendering** section. *** ### Step 3: Tracking Ads Ad tracking is done through beacons that send data back to Criteo for every user interaction related to an ad. We provide [a general introduction](/retailer-integration/docs/introduction-1) about how we use beacons at Criteo, as well as [details on beacon types](/retailer-integration/docs/beacon-types), [the universal beacons feature](/retailer-integration/docs/legacy-universal-beacons), and [the BeaconSDK library](/retailer-integration/docs/beacon-sdk) in the **Ad Tracking** section. *** ## Prerequisites Before integrating with Criteo's Retail Media ad delivery system, ensure the following prerequisites are met: 1. **Validated and configured product feed**: Send a product feed that has been validated and configured according to Criteo's specifications. Detailed guidelines for feed configuration can be found [here](/retailer-integration/docs/feed-definition). 2. **Configured account and ad inventory**: Have your account and ad inventory validated and configured in Criteo’s Retail Media Platform by your technical account manager. *** ## General Ad Server Requirements When integrating with Criteo's Retail Media Ad Delivery system, please adhere to the following ad server requirements: * **No caching of API responses**: The API response cannot be cached. It is generated based on real-time campaigns, inventory, price, and navigation data. Caching the response will distort attribution and reporting. * **Client-side or Server-side API calls**: The API can be called both on the client side and the server side. * **Server-side calls recommended**: We recommend server-side calls to allow for server-side rendering of the ads. * **Allowed request method**: The only request method allowed is the `GET` method. * **Headers for server-side requests**: To protect our partners and advertiser from being billed for illegitimate traffic, Criteo implemented Invalid Traffic (IVT) detection rules. As part of these rules, all server-side requests should contain the following headers: * **Referer** (optional): Learn more by visiting the [Referer documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer). Please note that for apps, deeplinks are recommended instead. * **X-Forwarded-For**: [X-Forwarded-For documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For). This should be set to the IP address of the end-user. * **User Agent**: [User-Agent documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent). Besides sending the `user-agent` header, it must comply with IAB's requisites. IAB provides a sample list of invalid user-agents [here](https://www.iab.com/guidelines/iab-abc-international-spiders-bots-list/). *** ## Platform Service Agreements * **Response Time Guarantee**: Criteo guarantees a response time of 150ms or less at the 95th percentile. This response time pertains to our servers and does not include external network latencies, such as the time beyond the point of connection between Criteo and the internet. * **Availability Rate**: The availability rate of the Ad Delivery Service is calculated by dividing the number of minutes the service is available by the total number of minutes in the assessment period, which is defined as one calendar month. Criteo guarantees a monthly availability rate of at least 99.5% for the Ad Delivery Service. ***
## What's next * [Glossary](/retailer-integration/docs/rm-glossary) # Introduction Source: https://developers.criteo.com/retailer-integration/docs/introduction-1 Sharing your catalog with Criteo is the first step for a succesful integration Catalog integration process # Feeds vs. Product Importer API Both **feeds** and the **Product Importer API** serve as tools for delivering product information and generating product datasets, but they are tailored to distinct requirements and use cases. > 👍 Feed vs. Product Dataset > > * The feed is the raw input file provided by the client, while the product dataset is the organized and processed output created by Criteo for use in campaigns. > * Feeds require ingestion and transformation to create product datasets that are ready for operational use. Below is a detailed comparison:

Feature

Feeds

Product Importer API

Data Format

XML, CSV, JSON

JSON

Ingestion Speed

Slower, due to file processing

Faster, enabling almost real-time updates

Automation

Requires manual uploads or scheduling

Fully automated via API endpoints

Flexibility

Limited

High, with granular update capabilities

Use Case

Suitable for small catalogs or periodic updates

Designed for large catalogs and updates

**Which to choose?** The **Product Importer API** is perfect for clients with extensive inventories (over one million products) who require faster data ingestion and more control over product updates. In contrast, **feeds** are better suited for simpler scenarios (smaller product counts, one ingestion per day) or when API integration isn't possible. Head this way for the [Feed upload guide](/retailer-integration/docs/product-upload-guide), or this way for the [Product Importer API guide](/retailer-integration/docs/product-importer-guide). If you need assistance to choose between feeds and/or the Product Importer API, please contact your Criteo representative. *** # Feed Definitions ## Feed A feed is the raw data file provided by a client, typically in formats like XML, CSV, or JSON. It contains product inventory information such as product IDs, names, prices, availability, and other attributes. Feeds are unstructured or semi-structured and serve as the input for platforms to ingest, transform, and process product data. ## Product Dataset A product dataset is the processed and structured collection of product information derived from the feed. It includes comprehensive product attributes such as IDs, descriptions, prices, availability, and additional metadata. The dataset is optimized to support Retail Media campaigns, ensuring accurate, consistent, and up-to-date product information for ad targeting, delivery, and reporting. ## Product Importer API The Product Importer API is a RESTful API that enables the upload, update, and management of product datasets on the Criteo platform. It ensures that critical product details, such as IDs, prices, availability, and other attributes, remain accurate and synchronized, supporting the optimization and performance of retail media campaigns. ***

## What's next * [Feed upload guide](/retailer-integration/docs/product-upload-guide) * [Product feed parameters](/retailer-integration/docs/product-feed-parameters) * [Product feed examples](/retailer-integration/docs/product-feed-examples) * [Product Importer API Guide](/retailer-integration/docs/product-importer-guide) * [Dataset parameters](/retailer-integration/docs/dataset-parameters) * [Product Dataset Examples](/retailer-integration/docs/product-dataset-examples) # Lookup Files Source: https://developers.criteo.com/retailer-integration/docs/lookup-files # Introduction Lookup files serve as an auxiliary resource in your product feed system, providing a flexible solution for incorporating additional information that might not be included directly in the main product feed. These files are particularly useful when you need to supplement the existing feed with extra data without altering its fundamental structure. *** # Key Characteristics of Lookup Files ## Purpose * **Supplemental data**: Lookup files are intended to store additional information that, for various reasons, cannot be directly added to the main feed. This can include extended descriptions, custom attributes, or any other data that enhances product listings. ## Storage * **Location on Criteo's SFTP**: By default, Criteo’s SFTP servers contain a specific folder named `/vlookup` where lookup files should be stored. This standardized location ensures that Criteo systems can reliably access and integrate these files into the broader feed processing workflow. ## File format * **CSV file requirement**: The lookup file must be formatted as a CSV (Comma-Separated Values) file. This format is widely supported and allows for straightforward handling of tabular data. * **Separator**: It is recommended to use a semicolon (`;`) as the separator in lookup files. This helps avoid common issues with comma-separated data, such as conflicts arising from commas within data fields. ## Content structure * **SKU ID and extra fields**: The primary column should be the SKU ID, which uniquely identifies each product. This ID should match exactly with the SKU IDs used in the main product feed to ensure proper linkage. Following the SKU ID, each additional column should represent a separate field containing the supplemental data. *** # Best Practices * **Consistency in SKU IDs**: Ensure that SKU IDs in the lookup file exactly match those in the main product feed. Any discrepancies can lead to issues in data merging and utilization. * **Regular updates**: Keep the lookup file updated in sync with changes in the product feed. This alignment is crucial for maintaining the accuracy and relevance of the data presented to Criteo's systems. * **Secure and structured data handling**: When updating the lookup file on the SFTP server, make sure to follow secure data handling protocols to prevent unauthorized access and ensure data integrity. Using lookup files effectively allows you to expand the depth and breadth of product information available for your campaigns without overcomplicating the primary feed structure, thereby enhancing both performance and manageability. *** # Example File To illustrate a sample lookup CSV file as described, we'll create a file that includes columns for SKU ID, Store ID, Price, and Tracking Code. This file will use a semicolon (`;`) as the separator, adhering to the recommendation for lookup files. Here’s how the sample CSV content might look: ```csv csv theme={null} sku_id;store_id;price;custom_filter 12345;001;29.99;CF12345A 23456;002;49.99;CF23456B 34567;003;19.99;CF34567C 45678;004;59.99;CF45678D ``` ## Breakdown of Each Column: * **sku\_id**: This is the unique identifier for each product. It must match the SKU ID used in the main product feed. * **store\_id**: Represents a unique identifier for the store or location where the product is available. * **price**: The selling price of the product at the specified store. * **custom\_filter**: An extra filter that can be sent in ad calls to allow only specific products to show up pages like special sales or deals. The columns in this example are just for demonstration purposes. The lookup file that you send can contain any extra data that you wish to include. You can tailor the columns to fit your specific needs, adding any additional fields that provide valuable context or information for your product listings. ***
## What's next * [Feed best practices](/retailer-integration/docs/feed-best-practices) # Integration Introduction Source: https://developers.criteo.com/retailer-integration/docs/overview Learn more about the Criteo Retail Media Ad Delivery System and how to integrate with it # Welcome This documentation will guide you through the integration of our Onsite retail media delivery solution. In this documentation, you will find content about: * [The product feed](/retailer-integration/docs/product-upload-guide) * [Requesting ads](/retailer-integration/docs/api-calls) * [Rendering ads and the available ad formats](/retailer-integration/docs/format-overview) * [Tracking ad activity and beacon configuration](/retailer-integration/docs/introduction-1) * [Commerce Onsite Video (video ads integration)](/retailer-integration/docs/commerce-video-integration) * [A QA checklist per ad format](/retailer-integration/docs/qa-checklists) * [OneTag JavaScript documentation](/retailer-integration/docs/onetag) * [The Google Ad Manager (GAM)](/retailer-integration/docs/gam-overview) *** ## Integration flow The integration timeline can vary depending on the resources available and the level of prioritization. Here is an overview of the integration flow and steps: * **The preparation phase** follows the initial kick-off. That's a time dedicated to the creation and validation of the ad formats and mock-ups, as well as providing the integration documentation and setting up the product feed alongside its QA and ingestion. This is followed by the account setup. * **The technical integration phase** has two parts: * the first part is dedicated to Ad requests development, testing and QA, * the second part focuses on Ad rendering and beaconing development, testing and QA. * **The "Go live" phase** goes from Prod release, to Prod & Data QA, to the actual "go live", followed by algorithm optimization Overview of the Criteo Retail Media API integration flow ## Timeline precisions * Each step duration depends on the integrated scope and on retailer’s integration capacity and resources. * QA duration depends on the scope and round(s) of feedback between Criteo and the Retailer. * For example, an 8 to 10 weeks duration is standard for a scope of `Sponsored Products` in one environment (Web/Web mobile or Apps). Whereas, simultaneously integrating a scope of `Sponsored Products` & `Commerce display` formats in multiple environments and countries is estimated to take from 15 to 20 weeks. *** ## Onsite vs. Offsite At Criteo, Retail Media solutions are split into two categories: **Onsite** and **Offsite**. ### Onsite Onsite advertisements are displayed within a retailer's website or mobile app. Onsite ads use first party data to reach shoppers who visit, browse, or search on a specific retailer. There are two campaign types, which include Onsite Display and Sponsored products. ### Offsite Offsite is a Retail Media solution used to target unique audiences using retailer first-party data to reach shoppers across the open internet. **C-Yield Help Center** You can learn more about [Onsite Display](https://help.cyield.criteo.com/kb/guide/en/introduction-to-onsite-monetization-VL8zE0Bv9w/Steps/3358081) and [Offsite](https://help.cyield.criteo.com/kb/guide/en/offsite-monetization-overview-mC5iDvxIgO/Steps/3357447) on the dedicated pages of the [C-Yield Criteo Help Center.](https://help.cyield.criteo.com/kb/en/) This documentation addresses the integration of **Onsite solutions only**. In order to activate Offsite, a separate OneTag integration is needed. Please reach out to your technical representative for more information. *** ## Integration best practices You will find best practices to guide you at each step of the integration process: * [Best practices for the product feed](/retailer-integration/docs/feed-best-practices), * [Best practices for Ads requests](/retailer-integration/docs/requesting-ads-best-practices), * [Best practices for Ads rendering](/retailer-integration/docs/ad-rendering-best-practices), * [Best practices for Ad Tracking](/retailer-integration/docs/ad-tracking-best-practices). *** ## Assistance **Contact** If you require assistance along the integration process for ad delivery, please contact your technical account manager.




## What's next * [Integration process](/retailer-integration/docs/integration-process) * [Glossary](/retailer-integration/docs/rm-glossary) # Product Details Page Source: https://developers.criteo.com/retailer-integration/docs/product-details-page # Definition A product details page (PDP) shows the details of a single product or multiple products under the same parent ID. *** # Parameters ## `event-type` **Value**: `viewItem` **Description**: Indicates to the API that this is a PDP request. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return (if any) for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewItem_API_desktop`, `viewItem_API_mobile`, `viewItem_API_iOS`, `viewItem_API_android`. * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewItemApiDesktop`, `viewItemApiMobile`, `viewItemApiAios`, `viewItemApiAa`. **Required**: Yes *** ## `item` **Description**: SKU IDs corresponding to the product(s) on the PDP. To send multiple products, separate values with a pipe (`|`). The order of values must match the order used in `price` and `availability`. **Example (single product)**: `123-ab` **Example (multiple products)**: `123-ab|456-cd|789-ef` **Required**: Yes *** ## `parent-item` **Description**: Only use this if parent SKUs are being passed. If so, this value should match what is being sent in the `item_group_id` field of the product feed. **Example**: `123` **Required**: Recommended if the eCommerce platform uses parent items *** ## `price` **Description**: Current price of the product (with discount, if any). When sending multiple products, provide one price per product separated by a pipe (`|`), in the same order as `item`. **Example (single product)**: `34.99` **Example (multiple products)**: `34.99|42.21|38.99` **Required**: Yes *** ## `availability` **Description**: Stock status of the product. Send `1` if in stock, `0` if out of stock. When sending multiple products, provide one value per product separated by a pipe (`|`), in the same order as `item`. **Example (single product)**: `1` **Example (multiple products)**: `1|0|1` **Required**: Yes *** ## `category` **Description**: For PDP calls, this parameter passes an explicit category used for both ad-serving and Served Category reporting. If this field is not present, Criteo will default to the primary taxonomy of the SKU passed in the `item` parameter. If passed, this value should match the `product_type_key` value in the product feed. See more details [here](/retailer-integration/docs/product-feed-parameters#product_type_key). Without this parameter, all PDP ad activity is grouped under **Page Without Category** in UI reporting. While ad-serving still works, Served Category reporting will not reflect the actual page categories for PDPs. **Examples**: * Category ID, full breadcrumb style: `123>4567>89012` * Category ID, end-node-only style: `89012` * Category name style: `Computing>Keyboards and Mice>Mice` **Best Practices**: * Category ID is preferred over category name to avoid issues with typos, punctuation, and accented letters (especially in non-English languages). * If opting for category name: * The category name is case-insensitive. * Spaces between the separator (`>`) are ignored. **Required**: No *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## AMER ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewItem_API_desktop" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "item=123-ab" \ --data-urlencode "price=34.99" \ --data-urlencode "availability=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ## EMEA ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewItemApiAios" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "item=123-ab" \ --data-urlencode "price=34.99" \ --data-urlencode "availability=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` *** ## Multiple products When a PDP displays several products under the same parent, send all items in a single call using pipe-separated values. The position of each value in `item`, `price`, and `availability` must correspond to the same product. ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewItem_API_desktop" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "item=123-ab|456-cd|789-ef" \ --data-urlencode "price=34.99|42.21|38.99" \ --data-urlencode "availability=1|0|1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ## Mock retailer API response The API call below will return a response for a mock retailer. ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=108341" \ --data-urlencode "retailer-visitor-id=456" \ --data-urlencode "customer-id=789" \ --data-urlencode "page-id=viewItemApiDesktop" \ --data-urlencode "event-type=viewItem" \ --data-urlencode "item=19539" \ --data-urlencode "price=1" \ --data-urlencode "availability=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` You can see an example of the response [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewItemApiDesktop\&event-type=viewItem\&item=19539\&price=1\&availability=1). ***

## What's next * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) # Product Feed Examples Source: https://developers.criteo.com/retailer-integration/docs/product-feed-examples ## CSV / TSV To create a comprehensive CSV product feed sample incorporating all the parameters discussed in [Feed parameters](/retailer-integration/docs/product-feed-parameters), we structure the CSV to include the headers with corresponding example values for each parameter. This sample illustrates how to structure your data for upload to Criteo. Here's an example of what the CSV might look like: ```csv CSV theme={null} id,title,description,link,image_link,additional_image_link,sale_price,price,gtin,mpn,product_type,product_type_key,brand,item_group_id,google_product_category,availability,filters,seller_id,seller_name,regiondata,product_rating,number_of_reviews,is_buybox,cross_sellers_product_id 12345-123seller,"Red Men's T-Shirt Size L","A classic red T-shirt perfect for casual wear.","http://www.example.com/products/red-mens-t-shirt-size-l","http://www.example.com/images/red-t-shirt.jpg","http://www.example.com/images/red-t-shirt-back.jpg","25.99","29.99","012345678905","RT12345","Men>Clothing>T-Shirts","1>3>25","Adidas","12340","Apparel & Accessories > Clothing > Shirts & Tops","In Stock","Color=Red|Blue,Size=S|M|L|XL","123seller","Top Fashion","{'4126':{'Price':25.99,'Quantity':6}","4.5","10",true,12345 12345-999seller,"Red Men's T-Shirt Size L","A classic red T-shirt perfect for casual wear.","http://www.example.com/products/red-mens-t-shirt-size-l","http://www.example.com/images/red-t-shirt.jpg","http://www.example.com/images/red-t-shirt-back.jpg","24.99","29.99","012345678905","RT12345","Men>Clothing>T-Shirts","1>3>25","Adidas","12340","Apparel & Accessories > Clothing > Shirts & Tops","In Stock","Color=Red|Blue,Size=S|M|L|XL","999seller","Alt Fashion","{'4126':{'Price':24.99,'Quantity':3}","4.4","8",false,12345 23456-456seller,"Blue Women's Jeans","Comfortable blue jeans with a modern fit.","https://www.example.com/products/blue-womens-jeans","https://www.example.com/images/blue-jeans.jpg","https://www.example.com/images/blue-jeans-side.jpg","45.99","49.99","987654321098","BW23456","Women>Clothing>Jeans","4>10>22","Levi's","23450","Apparel & Accessories > Clothing > Pants","Out of Stock","Color=Blue|Black,Size=4|6|8|10|12","456seller","Jeans Boutique","'789':{}, '1011':{}","3.8","25",true,23456 34567,"Green Women's Scarf","Soft and stylish green scarf.","http://www.example.com/products/green-womens-scarf","http://www.example.com/images/green-scarf.jpg","","17.99","19.99","234567890123","GS34567","Women>Accessories>Scarves","5>11>23","Gucci","","Apparel & Accessories > Clothing Accessories > Scarves & Shawls","In Stock","","","","","4.7","40",true,34567 45678,"Black Men's Wallet","Elegant black leather wallet.","https://www.example.com/products/black-mens-wallet","https://www.example.com/images/black-wallet.jpg","","54.99","59.99","345678901234","BM45678","Men>Accessories>Wallets","6>12>24","Prada","","Apparel & Accessories > Clothing Accessories > Wallets & Money Clips","In Stock","","","","","4.9","15",true,45678 ``` *** ### CSV Breakdown * **`id`**: Unique identifier for each product variant. * **`title`**: The product's name as displayed on the website. * **`description`**: A brief description of the product. * **`link`**: URL to the product's detail page. * **`image_link`**: Main image URL of the product. * **`additional_image_link`**: URL for additional product images. * **`sale_price`**: How much you charge for your product during a sale. * **`price`**: Current product price, not including sales. * **`gtin`**: Global Trade Item Number, a unique identifier for products within the global marketplace. * **`mpn`**: Manufacturer Part Number. * **`product_type`**: Category breadcrumb in a hierarchical format. * **`product_type_key`**: Corresponding category IDs matching the `product_type`. * **`brand`**: Manufacturer or brand name. * **`item_group_id`**: Identifier for related product variants (e.g., different sizes or colors of the same product). * **`google_product_category`**: Google's taxonomy classification for the product. * **`availability`**: Current stock status of the product. * **`filters`**: Custom filter values for the product. * **`seller_id`**: Identifier for the seller on a marketplace. * **`seller_name`**: Name of the seller on a marketplace. * **`regiondata`**: Store-specific availability, optionally with pricing. * **`product_rating`**: The average customer rating for the product, scaled typically from 1 to 5. * **`number_of_reviews`**: The total number of customer reviews for the product. * **`is_buybox`**: Identifies the buybox winner for seller SKUs * **`cross_sellers_product_id`**: any ID that links all items as the same item despite having different sellers (This can be GTIN, MPN) *** ### Additional Notes * **Column order:** The order of columns in the CSV does not affect the processing. You can arrange the columns in any order that suits your workflow or system requirements. * **Field formatting:** Use double quotes for fields that contain commas, special characters, or embedded double quotes. For fields containing embedded double quotes, ensure each double quote is represented by two double quotes (e.g., `"Example ""quoted"" text"`). * **Protocols:** Always include the protocol (`http://` or `https://`) in URLs to ensure they are correctly processed. * **Commas in fields:** Do not use commas within fields. If you need to separate elements within a field, use alternative separators like vertical bars `|` or semicolons `;`. * **Image links:** Ensure that image URLs are accessible and conform to specified criteria such as resolution and file size. The `image_link` must specify a valid image content type (e.g., image/png, image/gif, image/jpeg). * **Character encoding:** The CSV file should be encoded in UTF-8 to support international characters and special symbols correctly. This sample CSV is designed to be illustrative and may need to be adjusted based on the specific requirements and systems used by Criteo and your eCommerce platform. *** ## XML Here's how the XML version of the feed above might look. We'll add `custom_label` tags which are commonly used to group products in custom ways that aren't covered by standard product attributes. ```xml expandable theme={null} 12345-123seller 12345 true Red Men's T-Shirt Size L A classic red T-shirt perfect for casual wear. http://www.example.com/products/red-mens-t-shirt-size-l http://www.example.com/images/red-t-shirt.jpg http://www.example.com/images/red-t-shirt-back.jpg 29.99 25.99 012345678905 RT12345 Men>Clothing>T-Shirts 1>3>25 Adidas 12340 Apparel & Accessories > Clothing > Shirts & Tops In Stock Color=Red|Blue,Size=S|M|L|XL 123seller Top Fashion '123':{'Price':'23.99'}, '456':{'Price':'27.99'} 4.5 10 Spring Clearance Men 45678 Black Men's Wallet Elegant black leather wallet. https://www.example.com/products/black-mens-wallet https://www.example.com/images/black-wallet.jpg 59.99 54.99 345678901234 BM45678 Men>Accessories>Wallets 6>12>24 Prada Apparel & Accessories > Clothing Accessories > Wallets & Money Clips In Stock 4.9 15 Year-Round Premium Men 23456-456seller 23456 true Blue Women's Jeans Comfortable blue jeans with a modern fit. https://www.example.com/products/blue-womens-jeans https://www.example.com/images/blue-jeans.jpg https://www.example.com/images/blue-jeans-side.jpg 49.99 45.99 987654321098 BW23456 Women>Clothing>Jeans 4>10>22 Levi's 23450 Apparel & Accessories > Clothing > Pants Out of Stock Color=Blue|Black,Size=4|6|8|10|12 456seller Jeans Boutique '789':{}, '1011':{} 3.8 25 Fall New Arrival Women 34567-789seller 34567 true Green Women's Scarf Soft and stylish green scarf. http://www.example.com/products/green-womens-scarf http://www.example.com/images/green-scarf.jpg 19.99 17.99 234567890123 GS34567 Women>Accessories>Scarves 5>11>23 Gucci Apparel & Accessories > Clothing Accessories > Scarves & Shawls In Stock 789seller Luxury Closet 4.7 40 Winter Luxury Women ``` ### Additional Notes * In this XML feed example, the category levels are separated by `>` instead of `>` as it is more compliant with XML best practices. However, Criteo supports both options. *** ### About `custom_label` **`custom_label`** tags are used to provide additional non-standard information that can be useful for sorting, filtering, or categorizing products within the feed. In the example above: * **`custom_label_0`**: Identifies which season the product is best suited for (e.g., Spring, Fall). * **`custom_label_1`**: Indicates if the product is part of any special promotional category like Clearance or New Arrival. * **`custom_label_2`**: Helps in targeting specific demographic groups, such as Men or Women. Custom labels are particularly useful in marketing and promotional campaigns where products need to be dynamically grouped or highlighted based on specific themes or sales strategies. They allow for greater flexibility in how products are presented and promoted on platforms that use this feed. ***

## What's next * [Lookup files](/retailer-integration/docs/lookup-files) * [Feed best practices](/retailer-integration/docs/feed-best-practices) # Product Feed Parameters Source: https://developers.criteo.com/retailer-integration/docs/product-feed-parameters ## Introduction This page provides a comprehensive list of fields that can be included in your product feed. Recommended fields are not mandatory but help streamline campaign management, improve performance, and enhance the shopper experience. Below is the list of mandatory and recommended parameters, including their descriptions and status (required or recommended), for both Onsite and Offsite Retail Media. *** # Required Parameters These are parameters that will prevent product ingestion if left blank/not included. ## **`id`** **Definition** A unique identifier assigned to a single product variant. Each version of a product (such as different sizes or colors) must have its own distinct ID to ensure accurate tracking and management. **Specifications** * Must be unique and consistent; changes to product IDs will break attribution and reporting. * Must match with the data shared in API requests. * Quotation marks, non-ASCII characters. * Will default to lowercase in our ad response if using alphanumeric IDs. * Case-insensitive, * Cannot match `item_group_id`, `seller_id`. * Limit: `50` * Type: `String` * Example: `25c48` * Required for Onsite: ` Yes` * Required for Offsite:` Yes` *** ## **`title`** **Definition** The product’s name, typically as shown on its detail page. This will be used as the primary text descriptor in banners for the product. **Specifications** * Must start with a letter or number. * Limit: `500` * Type: `String` * Example: `Working Boots – Size 7.5` * Required for Onsite: `Yes` * Required for Offsite: `Yes` *** ## **`description`** **Definition:** The `description` is a detailed and informative text field that highlights the product’s key features, specifications, benefits, and use cases. A robust, keyword-rich description improves search recommendations and enhances product discoverability across platforms. **Specifications** * The description must start with a letter or number. Remove all HTML tags from this field, including style, embed, object, and anchor tags. * Limit: `5000` * Type: `String` * Example: `"Get ready for sunny days in comfortable style with this short-sleeve T-shirt. Fashioned in a relaxed fit, the short-sleeve tee is crafted from cotton jersey fabric for comfortable wear. You can coordinate it with different bottoms and match it with layering pieces to create a range of outfits...."` * Required for Onsite: `Yes` * Required for Offsite: `Yes` *** ## **`link`** **Definition** The URL of the product’s dedicated detail page. It should be unique to each product, and the information on the page must match the details provided in your catalog. **Specifications** * The `link` must start with the protocol (http\:// or https\://) followed by the full URL of the product detail page. * All symbols must be encoded. For example, “\$” must be replaced with “%24”. * Limit: `2000 characters`, including CAT prefix + encoded URL. * Type: `String`. * Example: `https://www.example.com/ProductA` * Required for Onsite: `Yes` * Required for Offsite: `Yes` *** ## **`image_link`** **Definition** The URL linking directly to an image of the product (SKU). The image should accurately represent the product being sold. **Specifications** * Limit: `2000 characters`. * Size: Recommended to be at least `800x800 pixels` and less than 16MB. * Supported formats: `PNG`, `JPEG`, or `GIF`. * Example: `https://www.example.com/image.png` * Required for Onsite: `Yes` * Required for Offsite: `Yes` *** ## **`product_type`** **Definition** The categorization of the product as defined on your website. It should reflect the product’s placement within your site's hierarchy or category structure. **Specifications:** * Only ASCII characters. * Must start with a letter or number. * Individual levels of a path must be separated by `>` or `>` in the XML file. * Multiple categories should be comma-separated. * `Case sensitive`: please ensure that you use proper casing to reflect what is shown on site. * Each path should be wrapped in single quotes (`'`). * Must match your website architecture. * If multiple categories are passed: the first one must be the most relevant (main category for PDP recommendations). * Submit up to `10 categories`. * Limit: Maximum of `10240 characters`. The maximum length of an individual category node is `750 characters`. * Type: `String` * Example: `'Computing>Keyboards and Mice>Mice','Hardware>Input Device'` * Required for Onsite: `Yes` * Required for Offsite: `Yes` *** ## **`product_type_key`** **Definition** The corresponding IDs of the categories passed in the `product_type` field. **Specifications:** * These category IDs should match those shown on the site. * Limit: Maximum of `10240 characters`. - The maximum length of an individual category node is `750 characters`. * Type: `String` * Example: `'123>4567>89012','456>7890'` * Required for Onsite: `Yes ` * Required for Offsite: `Yes` *** ## **`mpn`** **Description:** A unique identifier assigned by the manufacturer to distinguish an individual product. **Specifications:** * The MPN of a product is a series of numbers and letters. Required for all products without a `GTIN` assigned. Only provide an `MPN` if you are sure it is correct. When in doubt, do not provide an MPN. * Limit: `70` * Type: `String` * Example: `T49025028767898` * Required for Onsite: `Yes` *(if no`gtin` is assigned)* * Required for Offsite: `Yes` (*if no`gtin` is assigned)* *** ## **`gtin`** **Definition** A unique identifier used to identify a product, service, or item in the global marketplace. Providing a GTIN makes products easier to find and properly categorized. Products without a GTIN may be harder to categorize and could be ineligible for some features. **Specifications** * The value must be an 8-, 12-, 13-, or 14-digit number (UPC, EAN, JAN, or ISBN): * `GTIN-8 (EAN/UCC-8)`: this is an 8-digit number used predominately outside of North America. * `GTIN-12 (UPC-A)`: this is a 12-digit number used primarily in North America. * `GTIN-13 (EAN/UCC-13)`: this is a 13-digit number used predominately outside of North America. * `GTIN-14 (EAN/UCC-14 or ITF-14)`: this is a 14-digit number used to identify trade items at various packaging levels. * Limit: `50` * Type: `String` * Example: `00012345678905` * Required for Onsite: `Yes` *(if no`mpn` is assigned)* * Required for Offsite: `Yes` *(if no`mpn` is assigned)* *** ## **`brand`** **Definition** The name of the consumer-facing brand under which the product is marketed and sold.\ *This excludes the name of the parent company or manufacturer.* **Specifications:** * Must be consistently set across products: changes to brand values will break campaign attribution and reporting. * Maximum of `70 characters`. * Must start with either a letter or number. * Recommended: only ASCII characters. * Non-ASCII version of the brand can be added as an extra parameter. * Example: `Adidas` * Required for Onsite: `Yes` (*Blank values in this field will prevent the SKU from being added to campaigns*) * Required for Offsite: `No` (*recommended*) *** ## **`price`** **Definition** The standard price of the product before any discounts or promotions are applied. **Specifications:** * The decimal separator must be a period (.) with no thousands separator. * Limit: `14` * Type: `Number` * Example: `19.99` * Required for Onsite: `Yes` * Required for Offsite: `No` (*Recommended*) *** ## **`availability`** **Definition** Indicates whether the product can be purchased on the site. Populate this field with one of three values: `preorder` (the item is not shipping yet and orders are not being accepted), `out of stock` (the item is not available for shipping and orders are not being accepted), or `in stock` (the item is available for shipping and can be ordered). Products marked as out of stock will be excluded from appearing in ad placements. **Specifications:** * The availability must be populated with one of the following three values: preorder, out of stock, or in stock. * Limit: `25` * Type: `String` * Example: `in stock` * Required for Onsite: `Yes` * Required for Offsite: `No` (Recommended) *** ## **`size`** **Definition** Describes the product's size. Sizes should follow standardized formatting, depending on category (apparel, shoes, accessories, etc.). **Specifications**

Product Category

Example Sizes

Men's T-Shirt

S, M, L, XL, XXL

Women's Dress

2, 4, 6, 8, 10

Shoes (US)

7, 7.5, 8, 8.5, 9

Kids Apparel

2T, 3T, 4T, 5T

Accessories

One Size, Adjustable

Furniture

Small, Medium, Large, Queen, King

* For clothing, use either alpha (S, M, L) or numeric (4, 6, 8), not both. * Use "One Size" or "Adjustable" for items like hats, scarves, or belts. * 100 characters max. * Required for Onsite: `Yes` * Required for Offsite: `Yes` *** ## **`color`** **Definition** Describes the product's color(s). These should be simple, user-friendly, and consistent. Avoid internal color codes or overly specific color names. **Specifications:**

Product Example

Color Description

Nike Air Max (Black/White)

Black/White

Levi's 501 Jeans – Indigo Rinse

Indigo

Patagonia Down Jacket – Forge Grey

Grey

Apple Watch Band – Midnight Blue

Midnight Blue

Floral Summer Dress – Red/Pink Combo

Red/Pink

* Use Title Case (capitalize each word). * If multiple colors, specify up to three colors separated by a slash ( / )(for instance, `Blue/White`). * Avoid brand color names like "Solar Red" unless widely recognized. * 100 characters max. * Required for Onsite: `Yes` * Required for Offsite: `Yes` *** # Recommended Parameters ## **`google_product_category`** **Definition** The category of the product based on Google's product taxonomy. If a product fits multiple categories, provide only the single most relevant one. **Specifications:** * Limit: `750` * We accept both IDs and full category path. * `Case sensitive` * Type: `String` * Example: `2271 or Apparel & Accessories > Clothing > Dresses` * Required for Onsite: `No` (recommended)(*Not using category1/2/3*) * Required for Offsite: `No` (recommended) *** ## **`item_group_id`** **Definition** Use the same value for the `item_group_id` field to group related product variants. Variants are products that are fundamentally the same but differ in specific details like size, color, material, pattern, age range, or gender. Grouping products with the same `item_group_id` clearly defines them as variants (children) of a common parent product, and helps prevent duplicate products from being displayed together in the same ad placement. **Specifications** * The `item_group_id `can only contain ASCII characters, and must not contain quotation marks. * Limit: `50 ` * Type: `String ` * Case-insensitive, no quotation marks, ASCII characters, * Cannot `match id`, `seller_id`, `cross_sellers_product_id`. * Example for CSV/TSV: `AB1234` * Example for XML: `Ab1234\` * Required for Onsite: `No` (recommended) * Required for Offsite: `No` (recommended) *** ## **`sale_price`** **Definition** The final price of the product after applying a discount or promotional offer. **Specifications:** * Decimal separator must be a period (.) with no thousands separator. * Limit: `14` * Type: `Number` * Example: `49.99` * Required for Onsite: `No` (Recommended) * Required for Offsite: `No `(Recommended) *** ## **`filters`** **Definition:** Attributes that highlight differences between products within the same category, such as size and color. Filters help Criteo return the most relevant products on filtered or refined pages. **Specifications:** * Distinct filter sets must be comma-separated. * Multiple filter values within a set should be separated by pipe character `|`. * Ensure that there are no ampersands or commas (`&` or `,`) in the filter names or values as this will break the URL parsing when included in an ad request, and Criteo's internal parsing of the product feed. * Type: `String` * Example: `'Color=Red|Black, Size=S|M|L|XL, Screen size=21'` * Required for Onsite: `No` (*recommended if ads are serving on a page with filtering capabilities*) * Required for Offsite: `No` (recommended) *** ## **`product_rating`** **Definition** The average customer rating for the product, typically based on reviews collected on your site. Ratings help improve product relevance and user trust. **Specifications** * Must start with a number or a letter. * Limit: `8` * Type: `String ` * Example: `1, 2, 3.50, 4, 4.92`, or `5` * Required for Onsite: `No` (recommended) * Required for Offsite: `No` (recommended) *** ## **`number_of_reviews`** **Definition** The number of user reviews the product has received on site. **Specifications** * Limit:` 8` * Type: `String` * Example: `215` * Required for Onsite: `Yes` * Required for Offsite: `N/A` *** ## **`regiondata`** **Definition** The store IDs where the product is available and, optionally, its local prices. **Specifications** * Comma-separated * It is possible to send the price object empty (i.e.`{'123':{}, '456':{}}`) In this case, we will fallback to `price` as its value. * If the product is “out of stock” on the website across all stores, this field should contain `{}` (no stores). * Limit: `200` * Type: `String` * Example: `{'123':{'Price':'3.50'}, '456':{'Price':'4.29'}, '872':{'Price':'3.75'}, '958':{'Price':'5.00'}}` * Required for Onsite: `Yes` (*only if availability is store-based.*) * Required for Offsite: `N/A` *** ## **`custom_label_0`** **Definition** A field to include additional custom details about the product. It is useful for sorting, filtering, or categorizing products within the feed. **Specifications** * Create up to 5 custom labels, named from `custom_label_0` to `custom_label_4`. * Submit only one value for each custom label attribute. * Limit: `100` * Type: `String` * Example: `Best Seller` * Required for Onsite: `No` (recommended) * Required for Offsite: `No` (recommended) *** # Marketplace ## **`seller_name`** **Definition** The name of the marketplace seller. **Specifications:** * Only required if you are a marketplace and are reselling a product for several sellers. * Limit: `200` * Type: `String` * Example: `Best Shoe Store` * Required for Onsite: `Yes `(*If the client is using private market and reselling a product for several sellers, the user needs to set`isMarketplace` field to true*) * Required for Offsite: `No` (recommended) *** ## **`seller_id`** **Definition** The unique identifier that represents the seller on your site or in your internal systems. **Specifications:** * Only required if you are a marketplace and are reselling a product for several sellers. * Limit: `50` * Type:` String` * Example: `seller123` * Case-insensitive, no quotation marks, ASCII characters, * Cannot match `id`, `item_group_id`, `cross_sellers_product_id`. * Required for Onsite: `Yes` (*If the client is using private market and reselling a product for several sellers, the user needs to set`isMarketplace` field to true*) * Required for Offsite: `No` (recommended) *** ## **`cross_sellers_product_id`** **Definition** The unique identifier that represents the same product sold by another seller in your catalog, used to link equivalent products across different sellers. **Specifications:** * Used to associate products that are identical but offered by different sellers. * Case-insensitive, no quotation marks, ASCII characters. * Cannot match `item_group_id`, `seller_id`. * Limit: `50` * Type: String * Example: `product_abc_456` * Required for Onsite: No (optional) * Required for Offsite: No (optional) *** ## `is_buybox` **Definition** Indicates whether an offer is the selected “winning” Buy Box offer for a product at a given time among all offers grouped by the same `cross_sellers_product_id`. **Specifications** * True: The offer is the winning Buy Box offer shown by default on the product page. * False: The offer participates in the Buy Box competition but is not the winning offer. * Empty: The offer is related to the same product (`cross_sellers_product_id`) but does not participate in the Buy Box competition (e.g., retailer offer). * Type: Boolean * Example: true * Required for Onsite: No (optional) * Required for Offsite: No (optional) *** # Custom Parameters Criteo allows the inclusion of custom parameters to enhance SKU representation on your site, aligning the appearance of SKUs with your organic tiles more closely. These customizations ensure that the product tile rendered by Criteo match the native look and feel of your site. *** ## Implementation Details ### JavaScript Implementations For JavaScript-based implementations, it is essential that **all data necessary to display the product tile are included in the feed**. This ensures that Criteo can effectively use the data on-site. If your current feed does not include these fields, they should be added as new columns in the product feed file. This addition enables the dynamic rendering of product tiles that include custom attributes specific to your site's design and functional requirements. *** ### API Implementations For retailers using API implementations that pull data from their own systems based on product ID, there is no need to adjust the feed for custom parameters. The API method provides flexibility to fetch additional data as needed without changing the feed structure.. *** ## Examples of Custom Parameters in Use To better understand how custom parameters can be used, here are two visual examples: ### Standard Feed Parameters *In this first example, all the data necessary for the product tile is already included as eligible parameters in the standard feed.* *** ### Custom Feed Parameters *In the second example, the highlighted information includes "custom" data not present in the standard feed. These would need to be added to the feed in additional fields to allow Criteo to utilize them for rendering.* These examples highlight the flexibility of Criteo's platform in accommodating various data requirements, ensuring that the product tiles seamlessly integrate with the existing user interface of your website. ***
## What's next * [Product feed examples](/retailer-integration/docs/product-feed-examples) * [Lookup files](/retailer-integration/docs/lookup-files) # Product Importer API Guide Source: https://developers.criteo.com/retailer-integration/docs/product-importer-guide ## Overview **Product Importer API** If you are working with a big dataset, we strongly recommend that you use the Product Importer API, instead of a file (product feed) - mainly for performance reasons. **Product Importer API Guide** You can find a full guide for the Product Importer API on[ this page](/retail-media/v2026-preview/docs/product-importer-api) of the Retail Media API documentation, as well as a Product Importer examples [here](/retail-media/v2026-preview/docs/product-importer-examples). ***
# Product Feed Upload Guide Source: https://developers.criteo.com/retailer-integration/docs/product-upload-guide For a comprehensive list of all the fields that can/should be included in your feed, please refer to the [Product feed parameters](/retailer-integration/docs/product-feed-parameters) page. *** # Introduction Powering your Retail Media integration involves providing a daily product feed with up-to-date information about all the SKUs in your catalog. This section outlines the file formats, upload methods, and ingestion frequencies supported by Criteo. *** # Connection There are 3 main ways to store and send the product feed: * using Criteo's SFTP server, * using your own SFTP server, * through an HTTP GET request, We detail those options below. *** ## 1. Using Criteo's SFTP Server Criteo provides an SFTP server for storing the feed file. Access can be granted using a randomly generated username and password or an SSH key. Your Technical Account Manager will provide the access credentials. ### Uploading the Feed * Use a consistent filename for all subsequent feeds * Please append a datestamp (`_yyyyMMdd`) to the end of the filename so that each subsequent feed does not overwrite the previous version. This is helpful in case we should ever need to revert to a prior version. * **Example**: `feed_[yyyyMMdd]` --> `feed_20240701`, `feed_20240702`, `feed_20240703`, etc. *** ## 2. Using your own SFTP Server Criteo supports retrieving the feed from your own SFTP server. Please provide the SFTP server details to your Technical Account Manager to configure the connection. *** ## 3. HTTP(s) Criteo can access the feed via an HTTP GET request. Please provide the necessary endpoint to your Technical Account Manager for configuration. *** # Specification ## Formats Criteo can process two types of feed files: CSV (or TSV) and XML. Please refer to the [Feed examples](/retailer-integration/docs/product-feed-examples) for templates. *** ### 1. CSV/TSV * Choose your preferred separator (comma for CSV, tab for TSV). * Declare column headers in the first row. * Field names in headers should not contain spaces; use underscores (\_) instead. * Use lowercase characters only. *** ### 2. XML XML files can often be generated by web servers or automated feed providers. The file uses a series of XML nodes to enclose product data. * Ensure the file has a [valid XML tree structure](https://www.w3.org/TR/REC-xml). * Begin with an XML declaration: ``. * Enclose each product in its own node. * Place the product's SKU ID either in its own node or as an attribute of the product node. #### Examples of SKU ID nodes SKU ID as its own node: ```xml theme={null} 12345 ``` SKU ID as an attribute: ```xml theme={null} ``` *** ### 3. JSON JSON files can be used to for feeds, need to make sure the JSON feed has arrays of products with a specific name for an array object. #### Example of the feed with the array called "Products" ```json JSON theme={null} { "Products": [{ "id": "3865406", "title": "Red Men's T-Shirt Size L", "product_type": "'Computing>Keyboards and Mice>Mice','Hardware>Input Device'", "product_type_key": "'123>4567>89012','456>7890'", "google_product_category": "Electronics > Electronics Accessories > Memory", "brand": "Adidas", "gtin": "123456789012", "price": "24.99", "link": "https://www.example.com/ProductA", "availability": "in stock", "image_link": "https://www.example.com/image.png", "item_group_id": "256dc9", "regiondata": "{'123':{'Price':'3.50'}, '456':{'Price':'4.29'}, '872':{'Price':'3.75'}, '958':{'Price':'5.00'}}", "seller_id": "as5df", "seller_name": "bestbookshop", "description": "A red cotton T-Shirt", "product_rating": "4.5", "number_of_reviews": "56", "sale_price": "34.99", "filters": "Color=Red|Black, Size=XL, Screen Size=21", }] } ``` *** ## Frequency of Ingestion Regardless of the storage method, Criteo's servers can ingest the feed up to 4 times per day. The feed is then processed, which can take up to 24 hours (see the "Processing the Feed" section below). *** ## Size Criteo has a soft cap of **10GB per feed file**. If the feed size exceeds this limit, consider using the **Product Importer API**. Alternatively, you can contact your Technical Account Manager to request an increase in the limit. *** ## Compressed Feed Files To optimize the upload and processing of your product feed, Criteo supports the use of compressed files across all connection types. You can compress your feed file using`.zip` or `.gz` formats. This can significantly reduce the file size, leading to faster upload times and more efficient data handling. * **Compression formats supported**: `.zip` and `.gz` * **Connection types supported**: Compressed files can be used regardless of whether you are using Criteo's SFTP server, your own SFTP server, or HTTP(s) methods. Using compressed files helps streamline the feed submission process, particularly for larger datasets, ensuring quicker and more reliable integration with Criteo's systems. *** # Processing the Feed Once the feed is uploaded, Criteo processes it as follows: 1. **File validation**: Checks for format compliance (CSV/TSV/XML) and structure. 2. **Data parsing**: Extracts product data from the file. 3. **Data validation**: Verifies that all required fields are present and correctly formatted. 4. **Database update**: Updates the product catalog in Criteo's system with the new data. These 4 steps can take up to 24 hours to finish. Please ensure that your feed file adheres to the specifications to avoid processing delays. *** # Connecting to Criteo's SFTP Server To facilitate the secure transfer of your product feed files, Criteo provides an SFTP server. You can connect using either a username and password or an SSH key. You will find below detailed instructions for both methods, including terminal commands and steps for using FileZilla. *** ## Using Username and Password Please make sure you replace the **username** and **password** in the examples below with the credentials provided by your Technical Account Manager. *** ### Terminal Connection To connect to Criteo's SFTP server via terminal using a username and password, follow these steps: 1. Open your terminal. 2. Type the following command: ```bash theme={null} sftp top_123e4567-e89b-12d3-a456-426614174000@data-sftp.criteo.com ``` 3. When prompted, enter your password: `123e4567-e89b-12d3-a456-426614174000`. *** ### FileZilla Connection To connect using FileZilla with a username and password: 1. Open FileZilla. 2. Go to *File > Site Manager*. 3. Click *New Site* and configure the following settings: * **Host**: `data-sftp.criteo.com` * **Port**: Leave blank or enter `22` (for SFTP). * **Protocol**: SFTP - SSH File Transfer Protocol * **Logon Type**: Ask for password * **User**: `top_123e4567-e89b-12d3-a456-426614174000` 4. Click *Connect*. 5. Enter your password when prompted. *** ## Using an SSH Key ### Generating an SSH Key Before connecting with an SSH key, you need to generate one if you don't already have it: 1. Open your terminal. 2. Run the following command to generate an RSA key pair: ```bash theme={null} ssh-keygen -t rsa -b 2048 -C "your_email@example.com" ``` * Replace `"your_email@example.com"` with your email address. This is a label that helps identify the key. * Follow the prompts to choose a file location and set a passphrase (optional). *** ### Sharing the Public Key Send the public key to your Technical Account Manager. The public key file is typically located at `~/.ssh/id_rsa.pub`. You can view and copy the contents of this file with: ```bash theme={null} cat ~/.ssh/id_rsa.pub ``` *** ### Terminal Connection To connect to Criteo's SFTP server via terminal using an SSH key: 1. Use the following command: ```bash theme={null} sftp -i ~/.ssh/id_rsa top_123e4567-e89b-12d3-a456-426614174000@data-sftp.criteo.com ``` * Replace `~/.ssh/id_rsa` with the path to your private key if it's located elsewhere. *** ### FileZilla Connection Using SSH Key To connect using FileZilla with an SSH key: 1. Open FileZilla. 2. Go to *Edit > Settings*. 3. Under *Connection > SFTP*, click *Add key file…*. 4. Browse and select your private key file (`id_rsa`). 5. Go to *File > Site Manager*. 6. Click *New Site* and configure the following settings: * **Host**: `data-sftp.criteo.com` * **Port**: `22` * **Protocol**: SFTP - SSH File Transfer Protocol * **Logon Type**: Key file * **User**: `top_123e4567-e89b-12d3-a456-426614174000` * **Key file**: Browse to your private key if not already added. 7. Click *Connect*. These instructions will help you securely connect to Criteo's SFTP server using either method, ensuring safe and efficient management of your product feeds. ***

## What's next * [Product feed parameters](/retailer-integration/docs/dataset-parameters) * [Product feed examples](/retailer-integration/docs/product-feed-examples) * [Lookup files](/retailer-integration/docs/lookup-files) # Glossary Source: https://developers.criteo.com/retailer-integration/docs/rm-glossary **Retail Media Delivery Glossary** You will find on this page a list of the definitions we use across this documentation. Some are section specific (for Commerce video, or for GAM), while others are general to Ad tech. The definitions are visible across all pages, as interactive pop-up displaying when hovering on the designated words, like in this example: Ad unit. **Commerce-Yield Help Center** For more Retail Media integration definitions, you can also visit the [C-Yield Glossary](https://help.cyield.criteo.com/kb/guide/en/commerce-yield-glossary-Roj5c2Oi0V/Steps/3216082). *** ## AMER (Americas) is a global business and sales region encompassing North, Central, and South America. ## APAC (Asia-Pacific) is a global business region that spans Asia and the Pacific. ## Ad unit (GAM) (in GAM) is a location where ads are shown. The Ad Unit in GAM is equivalent to the placement in the Retail Media platform. ## Beacons A web beacon is a small object, such as a 1-pixel GIF, embedded in markup, and used to communicate information back to a web server or to third-party servers. Beacons are often included within third-party scripts for collecting user data, performance metrics, and error reporting. ## Branded Header is a Commerce Display format for mobile, focused on static branding. ## Butterfly is a Commerce Display unit containing a dual-panel with two banner-like elements, to be displayed on either side of a webpage. ## Commerce Display Refers to ad formats placed across a retailer’s website, in the context of Onsite Display. The Commerce Display formats include Flagship, Showcase, Butterfly, Branded Header and Interactive Header. ## Creatives (GAM) Ads are called Creatives in GAM. A Creative may be an asset that is uploaded to GAM and served directly from GAM, or it may be an HTML tag that calls to a third party ad server for demand. Retail Media’s integration with GAM relies on a custom creative that calls into the Retail Media Delivery ad server. ## Digital Shelf Talker Is an image displayed within a product tile that redirects to a URL. ## Display banners Are visual ads placed in designated spaces on a retailer’s website, in the context of Onsite Display. Display banners include the IAB format, Display Panel and Digital Shelf Talker. ## Display Panel Is an image that redirects to a URL. ## DSA The Digital Services Act is a legislative framework led by the European Commission aimed at updating and regulating the legal framework for digital services within the European Union (EU). It requires online platforms to ensure that users have real-time access to certain elements of information about any ad shown to them. ## EMEA (Europe, Middle East, and Africa) is a global commercial region that includes Europe, the Middle East, and Africa. ## Flagship Is a Commerce Display unit that serves as the primary branding unit on a webpage, often placed in prominent areas such as a homepage. ## First-party cookie Is a small set of data created by the website a user is visiting. First-party cookies are used to collect user data for analytics, and store preferences such as language settings, login information, etc. ## Fragment Is a reusable UI component that represents a part of the screen in an Android app. Fragments allow modularizing the interface and managing different parts of the UI separately. ## GAM (Google Ad Manager) is a comprehensive ad management platform that enables publishers to manage, sell, and optimize both direct and programmatic ad inventory across web, mobile, and app environments. ## Google Publisher Tag (GPT) is the HTML snippet that a publisher integrates with their website in order to access GAM functionality. If the Ad Unit is a logical representation of a location where ads can be shown, the GPT is the physical manifestation of that abstraction. Within the GAM user interface, GPT is generated from an Ad Unit, and then this tag is pasted into the Publisher’s website. ## IAB Banners Are static display units that redirect to a dedicated URL. ## Interactive Header Corresponds to the mobile version of the Butterfly display unit. ## Line item (GAM) (in GAM) defines the rules that associate Creatives to Ad Units, as well as the terms negotiated with the advertiser about when their ads will serve. ## Macros (GAM) (in GAM) represents a variable that will be expanded to a concrete value at the time a Creative is served. The Retail Media integration with GAM uses Macros to manifest query parameters for the request to Delivery. ## Offsite Is a Commerce Max solution used to target unique audiences using retailer first-party data to reach shoppers across the open internet. ## Onsite Display Refers to ads shown directly on a retailer's website to promote products or campaigns. ## Placement Refers to the specific ad space or location on a digital property (such as a website or app) where advertisements are served, typically defined by publishers to optimize visibility and user engagement. ## Product feed Is a file containing all the most up-to-date client’s catalog and product information. Criteo's servers can ingest the feed up to four times per day. ## Product tile Is an ad unit that consist of modular, clickable product displays. Product tiles can appear in grid or carousel layouts within the ad spaces. ## SKU (Stock Keeping Unit) is a unique alphanumeric code used by retailers to identify and track individual products or items in inventory, aiding in efficient stock management and sales processes. ## Showcase Is a Commerce Display unit combining branded assets with product tiles, often used as a premium display format for high-impact visuals. ## Sponsored products Are native ads that appear directly within a retailer’s product listings or search results, blending seamlessly with the site's content. ## Tag The tag (or Criteo OneTag) is a small snippet of JavaScript code embedded in a webpage to collect data, perform a specific function, or load third-party services. ## VAST tag (Commerce Video) A VAST tag is a piece of XML code used to serve video ads through a video player. It contains all the necessary information for the ad, including the ad's media file URLs, tracking URLs, and instructions for how and when the video ad should be displayed. ## VAST video player (Commerce Video) Refers to a video player that is compatible with the Video Ad Serving Template (VAST), a standard protocol for serving video ads across different platforms. VAST provides a structured framework for delivering video ads, including ad tracking, click-through options, and creative variations. ## Verbosity Refers to the amount of data included in the API response. A “full verbosity” response contains a large amount of detailed information, while a “low verbosity” response includes essential data only. ## Viewport (Commerce Video) Refers to the visible area of a web page that a user can see on their screen or device without scrolling. It adjusts dynamically based on the size of the device and the browser window, determining what content is immediately visible to the user. ## XPath XPath stands for XML Path Language. It uses a non-XML syntax to provide a flexible way of addressing (pointing to) different parts of an XML document. It can also be used to test addressed nodes within a document to determine if they match a pattern. ***
## What's next * [Introduction](/retailer-integration/docs/introduction-1) * [Product feed upload guide](/retailer-integration/docs/product-upload-guide) * [Product Importer API guide](/retailer-integration/docs/product-importer-guide) # Search Bar Dropdown Source: https://developers.criteo.com/retailer-integration/docs/search-bar-dropdown # Definition A Search bar dropdown **shows relevant products as the user types their keyword**. A new call should be made each time the predicted keyword changes. *** # Parameters ## `event-type` **Value**: `viewSearchBar` **Description**: Indicates to the API that this is a search bar dropdown event. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return (if any) for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewSearchBar_API_desktop`, `viewSearchBar_API_mobile`, `viewSearchBar_API_android`, `viewSearchBar_API_iOS`. * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewSearchBarApiDesktop`, `viewSearchBarApiMobile`, `viewSearchBarApiAios`, `viewSearchBarApiAa`. **Required**: Yes *** ## `keywords` **Description**: The search query entered by the user. If possible, send the final predicted keyword being matched for the organic results. For example, if by typing "app" the keyword being matched is `app store`, send `app store` in the API call. If the user then types "appl" and the predicted keyword changes to `apple`, make another call with `apple` in the API call. All keywords should be URL encoded. **Examples**: * `black%20laptops` * `black+laptops` **Required**: Yes *** ## `page-uid` **Description**: This value is returned within the response of the **initial call made on page load**. By storing this value and including it in subsequent `viewSearchBar` event calls, Criteo is able to link the events to the initial ad request. **Example**: `545d9a70-f096-4568-b4b9-8f2f32a452d4` **Required**: Yes *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## Search Bar Dropdown Example (AMER) ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewSearchBar_API_desktop" \ --data-urlencode "event-type=viewSearchBar" \ --data-urlencode "keywords=black laptops" \ --data-urlencode "page-uid=545d9a70-f096-4568-b4b9-8f2f32a452d4" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ## Search Bar Dropdown Example (EMEA) ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewSearchBarApiAios" \ --data-urlencode "event-type=viewSearchBar" \ --data-urlencode "keywords=black laptops" \ --data-urlencode "page-uid=545d9a70-f096-4568-b4b9-8f2f32a452d4" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` ***
## What's next * [AI assistant](/retailer-integration/docs/ai-assistant) * [Category pages](/retailer-integration/docs/category-page) * [Category flyout](/retailer-integration/docs/category-flyout) * [Product details page](/retailer-integration/docs/product-details-page) * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Search Pages Source: https://developers.criteo.com/retailer-integration/docs/search-page # Definition A search page is a **listing page showing the results of a user's inputted keyword**. Search result pages are divided into two types: * **Search result**: A search page that displays a product grid. * **Null search result**: A search page with no results and no corresponding product grid. *** # Parameters ## `event-type` **Value**: `viewSearchResult` **Description**: Indicates to the API that this is a search result request. **Required**: Yes *** ## `page-id` **Description**: An identifier that tells Criteo which placements to return for the ad request. Placements are instantiated by your Technical Account Manager depending on your desired ad configuration. Below are the standard page-ids for this page type: * **In Americas / APAC**: Typically follows the structure `[event-type]_API_[environment]`, e.g., `viewSearchResult_API_desktop`, `viewNullSearchResult_API_iOS` * **In EMEA**: Typically follows the structure `[event-type]Api[environment]`, e.g., `viewSearchResultApiMobile`, `viewNullSearchResultApiAndroid` **Required**: Yes *** ## `keywords` **Description**: The search query entered by the user. Should be URL encoded. **Examples**: * `black%20laptops` * `black-laptops` **Required**: Yes *** ## `item` **Description**: The list of SKUs that are organically shown on the page in the grid or list. Must match the parameter `id` in the feed (See details [here](/retailer-integration/docs/product-feed-parameters#id)). Multiple items should be separated by a pipe `|` or `%7C` (URL encoded). Used for reporting and for organic deduplication, if enabled. **Examples**: * `123|456|789` * `123%7C456%7C789` **Required**: Recommended, but not required *** ## `parent-item` **Description**: Only use this if parent SKUs are being passed. Must match the parameter `item_group_id` in the feed (See details [here](/retailer-integration/docs/product-feed-parameters#item_group_id)). Multiple parent items should be separated by a pipe `|` or `%7C` (URL encoded). For SKUs that do not have parent SKUs, `NULL` should be sent instead. Used for reporting and for organic deduplication, if enabled. **Examples**: * `12345P|NULL|456789P` * `12345P%7CNULL%7C456789P` **Required**: Recommended if the eCommerce platform uses parent items *** ## `list-size` **Description**: The total number of organic items on the page. Preferably, it should match the number of item IDs sent in the `item` parameter. **Required**: Recommended *** ## `page-number` **Description**: Represents the page number for either paginated results or scroll fold if products are loaded dynamically. This parameter can be used for result deduplication, by limiting the number of products shown on each page. Please note that a valid `page-number` starts at 1 and not 0. **Example**: `3` **Required**: Recommended *** ## `filters` **Description**: Corresponds to the filters applied by the shopper on the results. See the filter section for details on how to use this parameter. **Examples**: * `(price,le,100)` * `(color,eq,blue)` **Required**: Recommended. If not used, the ads will not follow the selected filters and might result in a poor user experience. *** # Sample Calls The header values in the sample calls are illustrative. Make sure to replace them with the appropriate values for your implementation. *** ## Search Result Page Example ### AMER / APAC ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewSearchResult_API_desktop" \ --data-urlencode "event-type=viewSearchResult" \ --data-urlencode "keywords=fast laptops" \ --data-urlencode "item=123|456|789" \ --data-urlencode "page-number=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` ### EMEA ```bash cURL theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailervisitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewSearchResultApiAios" \ --data-urlencode "event-type=viewCategory" \ --data-urlencode "keywords=black laptops" \ --data-urlencode "item=123|456|789" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` *** ## Null Search Result Page Example ### AMER / APAC ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewSearchResult_API_iOS" \ --data-urlencode "event-type=viewSearchResult" \ --data-urlencode "keywords=fast laptops" \ --data-urlencode "item=123|456|789" \ --data-urlencode "page-number=1" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` ### EMEA ```bash cURL theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "environment=d" \ --data-urlencode "retailer-visitor-id=a1b2c3d4e5" \ --data-urlencode "customer-id=123456789" \ --data-urlencode "page-id=viewNullSearchResultApiAios" \ --data-urlencode "event-type=viewSearchResult" \ --data-urlencode "keywords=notarealkeyword" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: app_ios 1.2.3" ``` *** ## Mock retailer API response The API call below will return a response for a mock retailer. ```bash theme={null} curl -X GET "https://d.eu.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=108341" \ --data-urlencode "retailer-visitor-id=456" \ --data-urlencode "customer-id=789" \ --data-urlencode "page-id=viewSearchResultApiDesktop" \ --data-urlencode "event-type=viewSearchResult" \ --data-urlencode "keywords=drink" \ -H "Referer: https://www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` You can see an example of the response [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewSearchResultApiDesktop\&event-type=viewSearchResult\&keywords=drink). ***
## What's next * [Search bar dropdown](/retailer-integration/docs/search-bar-dropdown) * [AI assistant](/retailer-integration/docs/ai-assistant) * [Category pages](/retailer-integration/docs/category-page) * [Category flyout](/retailer-integration/docs/category-flyout) * [Product details page](/retailer-integration/docs/product-details-page) * [Favorites page](/retailer-integration/docs/favorites-page) * [Basket page](/retailer-integration/docs/cart-page) * [Order confirmation page](/retailer-integration/docs/order-confirmation-page) * [Organic add-to-cart events](/retailer-integration/docs/organic-add-to-cart-events) * [Filters](/retailer-integration/docs/filtering) # Seller Catalog Integration Source: https://developers.criteo.com/retailer-integration/docs/seller-catalog-integration ## Introduction This guide walks you through the steps required to configure your catalog to support seller offers, including SKU ID structure, Cross Seller Product IDs (CSPID), and Buy Box Winner (BBW) updates. Any update to your SKU ID structure must be validated with your Technical Solutions (TS) representative before making any changes. *** ## Glossary | Term | Definition | | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Product** | The physical item being sold (e.g. one specific TV model), regardless of which seller/brand is offering it. | | **Offer** | One seller's way of selling a product (seller + price + availability). | | **Seller** | A third-party (neither the retailer nor the 1P brand) offering products on the retailer's marketplace. | | **Brand SKU** | The retailer/brand's identifier for a product, not tied to any 3P marketplace seller. | | **Seller SKU** | The product identifier sold by a 3P entity within a marketplace. | | **SKU ID (`externalId`)** | The identifier the retailer sends in the feed for an orderable item. In marketplace contexts this is often a concatenation like `productId-sellerId`. | | **Cross Seller Product ID (CSPID)** | The product-level key shared across all offers (retailer + all sellers) for the same physical product. | | **Concatenation** | A pattern where the retailer builds a unique SKU ID by combining product and seller information (e.g. `productId-sellerId`). | | **Rotation** | A pattern where the retailer only sends the current winning offer in the feed for each product, removing losing offers altogether. | | **PDP (Product Detail Page)** | The retailer's product detail page, often used as a source of frequent intraday checks/updates. | | **Buy Box Winner (BBW)** | The offer chosen as the "winning" offer for a product at a given time — the one shoppers see by default on the product page. Indicated by the `is_buybox` flag. | *** ## Step 1 — Understand your current structure Before you begin, identify your existing processes and setup, as they will impact the steps you need to complete. | Scenario | Action required | | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | You already use a unique SKU ID | Confirm your SKU ID structure, select a CSPID, and update processes for Buy Box Winner. | | You do not have seller SKUs in your account | Follow the steps below to implement a unique SKU ID structure, select a CSPID, and implement a BBW. | | You currently use a Rotation model | Follow the steps below to update your catalog with a per-offer SKU ID structure, select a CSPID, and update BBW processes. | **To get started:** 1. Create a diagram with your TS rep for your current SKU ID structure (Parent ID → SKU ID), mapping your `SKU_ID` structure with the correct product `SKU_ID`s and any `Parent` and `Seller_ID`s. 2. Create an example file of your current feed to share with the Criteo R\&D team. Diagram showing a parent product (XYZ) with two child SKUs (XXX for Orange Hat, YYY for Green Hat), each offered by Seller A, Seller B, and Brand *** ## Step 2 — Decide on your SKU ID and CSPID structures Do NOT make any adjustments to your Brand SKUs while mapping your future structure or in any of the following steps. ### Choose a SKU ID structure Design a unique SKU ID for each seller × product combination using one of three methods: * **Concatenation (recommended):** Combine the SKU ID with the Seller ID separated by a character (typically `-` or `_`). * Example: `SKU_ID=XXX` + `Seller_ID=Seller_A` → `XXX-Seller_A` * **Unique SKU per seller:** Create a new SKU designation for each seller. * Example: `XXX`, `YYY`, `ZZZ` * **Hashing:** Use a mathematical function combining the current SKU ID and Seller ID to produce a unique, consistent identifier. * Example: `b21b29df0a2e2c2a` **SKU ID requirements:** * Maximum 50 characters * Case-insensitive * Must use ASCII characters * Cannot use quotation marks * `id`, `item_group_id`, and `seller_id` cannot match each other Refer to the [Product Feed Parameters](/retailer-integration/docs/product-feed-parameters) and [Product Feed Examples](/retailer-integration/docs/product-feed-examples) pages for approved formats and examples. ### Choose a CSPID structure The CSPID must represent one physical product across all sellers. You can use: * **SKU ID** — if your current SKU ID will continue to serve as the unique product identifier even after switching to a unique Seller ID (recommended when applicable). * **GTIN** — already unique across products and consistent across sellers. * **Other** — any value that is consistent over time and represents a single product across multiple sellers. Once decided, create a sample file of your future feed to share with the Criteo R\&D team. Diagram showing parent XYZ mapping to CSPID Orange Hat (XXX) and CSPID Green Hat (YYY), each with concatenated SKU IDs per seller (e.g. XXX-Seller_A, XXX-Seller_B) *** ## Step 3 — Populate a CSPID Before populating the CSPID, confirm with your TS rep that your chosen CSPID will work as expected. The CSPID groups all offers for the same physical product across all sellers. It enables Buy Box Winner changes by product group and lets users search for a specific product to see all offers at once. **If you are newly introducing Seller IDs, or using a Rotation model:** Introduce a unique product identifier. You must provide one CSPID per unique product across all sellers, reusing an existing, well-understood product identifier where possible. **If your catalog already uses a concatenated SKU ID (`productId-sellerId`):** 1. Populate `cross_seller_product_id` using one CSPID per physical product across all sellers. * Example: `cross_sellers_product_id = XXX` for all offers around `XXX-*`, and `cross_sellers_product_id = YYY` for all offers around `YYY-*`. 2. The concatenated SKUs remain the ingestion key per offer (e.g. `XXX-seller_A`, `XXX-seller_B`), while the CSPID becomes the stable product-level grouping key used for Buy Box Winner and search. UI screenshot showing Search by Product ID returning no results without CSPID, and results found after CSPID is populated **Example feed structure with CSPID:** ```xml theme={null} 12345-123seller 12345 true Red Men's T-Shirt Size L 123seller Top Fashion In Stock ``` *** ## Step 4 — Make necessary catalog changes Do NOT make any changes to Brand SKUs. All catalog changes must be reviewed and approved by your TS rep before deployment. | Scenario | Action | | ---------------------------------------------------------------------- | --------------------------------------------------------------------------- | | Your existing SKU ID structure does not need changes | No catalog changes needed — confirm with your TS rep and move to Step 5. | | You do not have seller SKUs in your catalog | Add Seller SKUs using the unique SKU ID structure decided with your TS rep. | | You are updating your existing SKU ID model (Rotation → Concatenation) | Deploy updates to your catalog with the new SKU ID and CSPID. | **Required feed tags for seller offers:** * `seller_id` * `sellername` * `is_marketplace` * `is_buybox` **Impact to accounts after Criteo-led migration:** * SKUs in the previous format will be removed from the product feed and marked as "out of stock" in line-item reports. * Direct sold Seller SKUs will be switched to the appropriate unique Seller SKUs — users will see 2 rows for the same product in the UI for up to 30 days. Data will not be duplicated or impacted. * A message will be added directly in the UI to explain the temporary duplicate view. **Impact to attribution:** * Attribution metrics will be saved on the old SKU — the updated SKU will show no data until it begins serving. *** ## Step 5 — Deploy SKU ID updates elsewhere in your account Complete this step alongside or immediately after Step 4 to ensure accurate attribution metrics. Wherever you share the SKU ID must be updated to use the new structure, including the **Order Confirmation Page** and **Universal Beacons** (when in use). The SKU ID value in the catalog feed must match the value used in Ad Requests, Beacons, and all Sales/Attribution events. **Example — Concatenated SKU IDs (`productID-sellerID`):** ```text expandable theme={null} https://d.us.criteo.com/delivery/retailmedia?criteo-partner-id=108747&event-type=trackTransaction&page-id=trackTransaction&retailer-visitor-id=visitorid1&item=XXX-Seller_A&price=1&quantity=1&transaction-id=order123 ``` **Example — Unique SKU ID per seller:** ``` https://d.us.criteo.com/delivery/retailmedia?criteo-partner-id=108747&event-type=trackTransaction&page-id=trackTransaction&retailer-visitor-id=visitorid1&item=XXX&price=1&quantity=1&transaction-id=order123 ``` *** ## Step 6 — Implement or update Buy Box Winner Using the API endpoint to share Buy Box Winner updates is strongly recommended for the best experience. Now that you are using a CSPID, the Buy Box Loser is inferred automatically — there is no need to send information for both winners and losers. Your full feed update will still contain both winners and losers so sellers can add products to a campaign regardless of Buy Box status. Diagram showing CSPID groups (XXX and YYY) with multiple seller SKU IDs, each labeled as BuyBox Winner or BuyBox Loser ### Add BBW to your catalog feed Send `is_buybox` in the feed for seller offers. This tag tells Criteo the initial winner per CSPID group. | Value | Meaning | | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | | `true` | This offer is the Buy Box winner among all offers with the same CSPID. | | `false` | This offer competes in BBW but is not the winner. | | empty/absent | This offer shares the same CSPID but does not participate in BBW (e.g. a retailer/brand offer that should never be the marketplace loser). | ### Send winner-only BBW data via the API To set the winner per product using the API, call `SetBuyBoxWinners` with the new SKU ID structure. The request body specifies the Offer ID of the current Buy Box winner. A maximum of 5,000 Buy Box winners can be updated simultaneously. ``` POST /preview/retail-media/retailers/{retailer-id}/products/set-buy-box-winners ``` ```json theme={null} { "data": { "type": "SetProductBuyBoxWinnersRequest", "attributes": { "productBuyBoxWinners": [ { "offerId": "100" } ] } } } ``` The API does not replace the `is_buybox` column in your catalog feed for existing PDP intraday updates (i.e. shopper visits). Both mechanisms work in tandem. # Authentication Tokens Source: https://developers.criteo.com/retailer-integration/docs/using-tokens ## Introduction Clients can opt to use tokens to avoid exposing server-side API calls to unauthorized parties. There are two types of tokens: **static** and **dynamic**. If the token is incorrect or missing, you will receive a 401 response with the following content: ```json theme={null} {"Status Message":"Unauthorized"} ``` *** ### Static Tokens * **Contact your technical representative**: Reach out to your Technical Account Manager to have a token generated internally and shared with your team. * **Authentication header**: Add the token in the authentication header of your API calls. *** ### Dynamic Tokens A dynamic token expires after a certain period. Every time it expires, you must make a new request to the authentication service to generate a fresh token. * **Set up an app**: Generate an API token by setting up an app in our developer portal. Follow the instructions here: [Configuring Your API Application](/retail-media/v2024.10/docs/configuring-your-api-application). * **Share application ID**: Share your `application_id` with your TAM. This ID will be used to set up our authentication server. * **Authentication request**: Make an authentication request as described here: [Authentication](/retail-media/docs/authentication). * **Get token**: You will receive a token that can be used to make calls to the ad delivery API. *** ## Example of API Calls with Authentication ### Static token example ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "event-type=viewHome" \ --data-urlencode "page-id=viewHome_API_desktop" \ -H "Authorization: Bearer YOUR_STATIC_TOKEN" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` *** ### Dynamic token example 1. **Request token** ```bash theme={null} curl -X POST 'https://api.criteo.com/oauth2/token' \ -H 'content-type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'client_id=YOUR_CLIENT_ID' \ --data-urlencode 'client_secret=YOUR_CLIENT_SECRET' ``` 2. **Use token** ```bash theme={null} curl -X GET "https://d.us.criteo.com/delivery/retailmedia" \ --data-urlencode "criteo-partner-id=12345" \ --data-urlencode "retailer-visitor-id=123" \ --data-urlencode "customer-id=456" \ --data-urlencode "event-type=viewHome" \ --data-urlencode "page-id=viewHome_API_desktop" \ -H "Authorization: Bearer YOUR_DYNAMIC_TOKEN" \ -H "Referer: www.criteo.com" \ -H "X-Forwarded-For: 123.456.789.012" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" ``` ***

## What's next * [API parameters](/retailer-integration/docs/api-parameters-1) # Adjust In-App Events [Android] Source: https://developers.criteo.com/mobile-integrations/docs/adjust-android Implement Criteo in-app events for Android using the Adjust SDK. ## Overview This document provides detailed information on the following implementation steps related to the source code of the app (if required): * Recommended events and parameters * Deep link implementation * Testing requirements For general integration steps, check [Criteo Integration With Adjust](/mobile-integrations/docs/adjust-criteo-integration). ## In-App Events Implementation ### View Home The viewHome event is automatically sent once Criteo has been activated on the app. It is triggered for each new user session. ### App Deeplink The AppDeeplink event should be triggered every time the app is opened with a deeplink. For each activity that accepts deep links, find the `onCreate` method and add the following call: ```java theme={null} protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); Uri data = intent.getData(); AdjustEvent event = new AdjustEvent("{deeplinkEventToken}"); event.addPartnerParameter("criteo_deeplink", data.toString()); Adjust.trackEvent(event); //... } ``` ### View Listing The viewListing event should be triggered on screens displaying product lists, like category or search results screens. To allow our platform to identify the type of products the user is interested in, you must include the IDs of the top three products displayed in the list, which should match those provided in the catalog feed. ```java theme={null} AdjustEvent event = new AdjustEvent("{viewListingEventToken}"); List productIds = Arrays.asList("productId1", "productId2", "productId3"); event.addPartnerParameter("products", productIds.toString()); Adjust.trackEvent(event); ``` ### View Product The viewProduct event should be triggered on all product-details screens. You must include the ID of the product detailed on the screen, which must be the same one provided in the catalog feed. ```java theme={null} AdjustEvent event = new AdjustEvent("{viewProductEventToken}"); event.addPartnerParameter("product", "productId"); Adjust.trackEvent(event); ``` ### View Basket The viewBasket event should be triggered on the basket-details screens. You must include the IDs, unit prices, and quantities of the products available in the basket. ```java theme={null} AdjustEvent event = new AdjustEvent("{cartEventToken}"); List productIds = Arrays.asList("productId1","productId2","productId3"); List productPrice = Arrays.asList(12.0, 25.0, 2.0); List productQuantity = Arrays.asList(1, 2, 3); event.addPartnerParameter("productids", productIds.toString()); event.addPartnerParameter("productPrice", productPrice.toString()); event.addPartnerParameter("productQuantity", productQuantity.toString()); Adjust.trackEvent(event); ``` ### Track Transaction The trackTransaction event should be triggered on order confirmation screens after checkout. You must include a unique transaction ID as well as the IDs, unit prices, and quantities of the products contained in the transaction. ```java theme={null} AdjustEvent event = new AdjustEvent("{transactionConfirmedEventToken}"); List productIds = Arrays.asList("productId1","productId2","productId3"); List productPrice = Arrays.asList(12.0, 25.0, 2.0); List productQuantity = Arrays.asList(1, 2, 3); event.addPartnerParameter("productids", productIds.toString()); event.addPartnerParameter("productPrice", productPrice.toString()); event.addPartnerParameter("productQuantity", productQuantity.toString()); event.addPartnerParameter("transactionId", "abc123"); event.addPartnerParameter("currency", "AUD"); event.addPartnerParameter("setRevenue", "68.0"); Adjust.trackEvent(event); ``` ### Dates for Travel It's possible to attach check-in and check-out dates to every Criteo event with the parameter keys `din` & `dout`. The format of the dates is `"yyyy-mm-dd"` and it has to be set every time a user enters new search dates. For example: ```java theme={null} event.addPartnerParameter("din", "2020-01-01"); event.addPartnerParameter("dout", "2020-01-07"); ``` The dates will be sent with every Criteo event for the duration of the application lifecycle, so they must be set again when the app is re-launched. The search dates can be removed by setting the parameter keys `din` & `dout` to `null`. For one-way flight, you can skip the check-out parameter. ### Hashed Email for Cross-Device Targeting Clients have the option of sending Criteo the email address of app users when available. This will enable the cross-device Criteo targeting feature. For instance, if the email is "[*j.doe@gmail.com*](mailto:j.doe@gmail.com)", it can be sent in the format of [SHA-256](https://en.wikipedia.org/wiki/SHA-2) (preferred) or [MD5](https://en.wikipedia.org/wiki/MD5) hashed strings in the events as below: SHA-256: ```java theme={null} event.addPartnerParameter("criteo_email_hash_sha256", "3ce6f3866c13320081cd44f40402527b94f4c2ef24ea1ee163e83650b8f04d01"); ``` MD5: ```java theme={null} event.addPartnerParameter("criteo_email_hash_md5", "8115b7da7fff37aeaec18779411a1042"); ``` The hashed email will be sent with every Criteo event for the duration of the application lifecycle, so it must be set again when the app is relaunched. The hashed email can be removed by setting the value to an empty string: ```java theme={null} event.addPartnerParameter("criteo_email_hash", ""); ``` Following are the steps to generate a hashed email address for Criteo: * Convert all characters to lower case * Remove any blank spaces * Convert to UTF-8 * Hash using SHA-256 or MD5 algorithm * Email addresses need to be hashed before setting them in the event parameter. You can use existing libraries in Java/Kotlin or create your own function for it. ### Customer ID A Customer ID can be provided in all events. If the user is logged in to the advertiser's app, the user ID should be passed. User ID is an optional parameter and should be left as an empty string if the user is logged out or the User ID is unavailable. Customer ID can be any string, as long as it does not contain any Personally Identifiable Information. ```java theme={null} event.addPartnerParameter("customer_id", "12323dsvhdsb23"); ``` ## Enabling Reattribution via Deeplink ### Adjust SDK v4.11.4+ Adjust enables you to run re-engagement campaigns with usage of deep links. If you are using the Adjust SDK v4.11.4 and above, this feature is enabled within the SDK. Once you have received deep link content information in your app, add a call to the `appWillOpenUrl` method. By making this call, the Adjust SDK will try to find if there is any new attribution info inside of the deep link and if any, it will be sent to the Adjust backend. The function `appWillOpenUrl` should be implemented as follows to support deep linking reattributions in all Android versions: ```java theme={null} @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = getIntent(); Uri data = intent.getData(); Adjust.appWillOpenUrl(data); } ... @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Uri data = intent.getData(); Adjust.appWillOpenUrl(data); } ``` For more info, check Adjust Help Center: [Reattribution using deep links](https://help.adjust.com/en/article/deep-linking-android-sdk#reattribution-deep-links) ## Testing Process You should contact Criteo to start the testing phase as soon as the events are implemented. Please allow sufficient time (at least a week before) for testing prior to the app submission in order to ensure that the data you are sending is complete. Criteo will require an app build (APK) to test the collection of events on Criteo side, so please share the same with your Criteo Contact. # Criteo Integration With Adjust Source: https://developers.criteo.com/mobile-integrations/docs/adjust-criteo-integration Configure your Criteo App campaign with Adjust, including attribution windows, event postbacks, and tracking link creation. ## Overview This page will guide you in setting up your Criteo App campaign with Adjust. ## Dashboard Configuration ### Attribution Windows Setup (App-Level) Under **AppView** > **All Apps**, select your app, navigate to **Attribution settings** tab and consider the attribution settings recommended by Criteo below. In case you are proceeding with the integration for both Android & iOS apps (or multiple apps from the same platform), proceed with the following steps for all of them. Keep in mind that the following settings are Criteo's recommendations but the ultimate goal is to match the options you want to take into account for your setup! #### New Users: Attribution (Install) Hit **Edit** button on the left to change your settings: ##### **Click Based Attribution** * \[Recommended] **Device matching**: at least `7` days * Sets the click attribution window for deterministic device matching. * \[Recommended] Set **Enable probabilistic modeling** to `ON` and the respective window to `24` hours * If deterministic device matching cannot be performed, Adjust can try probabilistic attribution. * **Temporary attribution**: * By default set to **off**. In case you want to avoid the default Lifetime Attribution from Adjust, enable this toggle. You can find more information [here](https://help.adjust.com/en/article/temporary-attribution). * Suggested temporary window: at least `30` days, to properly measure post-install events on the Criteo side. Image
##### **\[Optional] Impression Based Attribution** Setting up Impression based attribution is optional. Enable these options ONLY if taken into account. * Set **Device matching** to `24` hours * Controls whether Adjust can attribute installs or reattributions based on an ad impression when there was no click. The 24-hour window is the maximum time after the impression during which Adjust will consider that impression eligible for attribution. * Set **Enable probabilistic modeling** to `ON` and respective window to `24` hours * This is another form of impression attribution, but it's different from device matching. Probabilistic modeling allows Adjust to attribute installs or reattributions when deterministic identifiers are unavailable or insufficient. * **Temporary attribution**: * By default set to **off**. In case you want to avoid the default Lifetime Attribution from Adjust, enable this toggle. You can find more information [here](https://help.adjust.com/en/article/temporary-attribution). * Suggested temporary window: at least `30` days, to properly measure post-install events on the Criteo side. Image Hit **Save** to confirm changes! #### Existing Users: Reattribution (Retargeting) Hit **Edit** button on the left to change your settings: ##### **Click Based Attribution** * **Enable Reattribution**: make sure to toggle `ON` this option if you intend to run Retargeting campaigns * **Inactivity period**: * Defines the amount of time users must be inactive (a user must not have opened the app) before they can be reattributed to retargeting campaigns. * Criteo **strongly recommends** setting it to `0` days. * **Reattribution window**: * Once the user is eligible, the reattribution window determines how long after the retargeting engagement Adjust can attribute the user to that retargeting campaign. * Criteo recommends setting it to `30` days. * \[Recommended] Set **Enable probabilistic modeling** to `ON`, the reattribution inactivity period to `7` days and the reattribution window to `24` hours * If deterministic device matching cannot be performed, Adjust can try probabilistic attribution. * **Temporary attribution**: * By default set to **off**. In case you want to avoid the default Lifetime Attribution from Adjust, enable this toggle. You can find more information [here](https://help.adjust.com/en/article/temporary-attribution). * Suggested temporary window: at least `30` days, to align with Criteo's default Post-Click 30 days attribution model for Retargeting. In case you decide to set an **Inactivity Period** greater than **0**, please inform your Criteo contact so our campaigns don't target those recent users (which could directly affect our measured results - CPO/ROAS). Image
##### **\[Optional] Impression Based Attribution** Setting up Impression based attribution is optional. Enable these options ONLY if taken into account. Image In case of doubts or concerns, please consult your Criteo technical contact. Hit **Save** to confirm changes! ### Enabling Criteo Module To proceed with the Criteo configuration in Adjust Suite dashboard: * Under **Campaign Lab**, select **Partners** * Click on **New Partner** button on top-left, then type *Criteo* in the search bar, select the respective module and hit **Next** Image * Under **App Selection**, select the app you want to integrate and proceed to the **Next** step Image In case you are proceeding with the integration for both Android & iOS apps (or multiple apps from same platform), proceed with the following steps for all of them. * Under **Link Structure**: * For **Link name**, give an arbitrary name to your link; choose a name that easily identifies Criteo as Network, as this will appear in your Adjust reports (suggestion) * Edit the campaign parameters hierarchy, if desired * You can also enable **Include ad spend parameters**, in case you want Criteo to share ad spend data with Adjust * Press **Next** Image * Under **User destinations** tab, leave the default settings configured and press **Next** * For default campaign setups, Criteo uses direct deeplinking to the App Store (in case of Install) or back to the app. * In the meantime, Adjust click trackings will be fired S2S, causing those link destination settings not to be taken into account. In case of doubts or concerns, please consult your Criteo technical contact. * Under **Attribution settings** tab, leave the default settings configured and press **Next** * In case you want to override app-level attribution settings, please take into consideration the attribution settings suggested in the [Attribution Windows Setup](#attribution-windows-setup-app-level) section above. Image * Review overall settings and confirm clicking on **Create link** Image ### Link URL Creation To track attribution for Criteo campaigns running through Adjust, the client must create an Adjust Link URL (also known as impression/click trackings) in order to have them configured on our Criteo creatives. If the Criteo module was enabled just now and you pressed **Create link**, Adjust Link URLs have already been automatically created and you can share both Click & Impression URLs with your Criteo contact: Image Otherwise, you can create a new Link URL at any time: * Navigate to **Campaign Lab** > **Partners** section and select our **Criteo** module * Under the default **Links** tab, you can review all existing Link URLs created at network-level for Criteo * Click on **New Link** to create a new one, if desired * You can also simply edit the settings of your existing Link URL by clicking at its respective name Image In case existing Link URLs were modified, don't forget to share with your Criteo contact the updated Click & Impression URLs! Depending on your Adjust plan, you may have the ability to create Link URLs at other levels than network (campaign, adgroup or creative levels). For simplification purposes and to avoid discrepancy issues, Criteo recommends to **always use network-level Link URLs**. ### Data Sharing with Criteo To allow Criteo to properly target the expected audiences, as well as optimize and measure the correct results of our campaigns, it's crucial to share the actions of your existing app users with us. To configure those event postbacks: * Navigate to **Campaign Lab** > **Partners** section and select our **Criteo** module * Under **Data sharing** tab, locate the respective app and click in the pencil icon on the left to **Edit settings** Image * Under **Enable data sharing for Criteo** area, click in the **Edit** button * Input your `appId` that is registered in the App Stores, so Criteo can identify their respective event postbacks on our side * In case you have the same app in Adjust for both Android & iOS platforms, enter the `appId` for both here, as in the example below: * Android: `com.criteo.adjust.sampleapp` * iOS: `id123456789` * Then, **Enable** it Image * Under **Set your data sharing options**, ensure that you have enabled: * **Data from all attribution sources**: to be able to target all existing users for Retargeting or exclude existing users for Install campaigns * **Sessions**: to track all users sessions * **Uninstalls and reinstalls**: for enriched measurements (if available) * **In-app revenue (from in-app purchases)**: for [revenue tracking](https://help.adjust.com/en/article/event-tracking-android-sdk#revenue-tracking) (if available) * **Parameters**: to receive all [Partner Parameters](https://help.adjust.com/en/article/event-tracking-android-sdk#partner-parameters) available in your Adjust events (product ids, order id, hashed e-mail, etc.) Image * Under **Map your events**, make sure to set the mapping for all your relevant in-app events that Criteo should receive * Press **Map event** * In **Adjust event**, select your event in the dropdown * In **Partner event**, type the Adjust event name to map it as **custom event** (removing possible special characters, spaces, etc.) * Hit **Apply** In **Partner event**, do NOT select the predefined event types from the dropdown (*achievementUnlocked*, *customEvent*, etc.). Those are obsolete postback templates and won't work as expected! Image * Repeat the process for all other in-app events * Finally, click **Save** to start sharing your users data with Criteo Image For more info, check: [Adjust Integrated Module Partners - Criteo](https://help.adjust.com/en/classic/integrated-partners-classic/criteo) ### Adding Additional In-App Events If you need to create/modify in-app events using Adjust SDK, please see the links below to have them implemented in your app: * [Android](/mobile-integrations/docs/adjust-android) * [iOS](/mobile-integrations/docs/adjust-ios) ### Recommended Events per Vertical The recommendation is to send all events that describe the "user-flow" in the app. The table below shows the recommended events per vertical: | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | --------------------------------------------------- | ------------------------------------------------------------------ | ------ | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when a user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when a user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when a user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when a user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / create an account / sign up | when a user creates an account, signs up or completes registration | Y | Y | Y | Y | Y | Y | Y | Y | | login | when a user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when a user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when a user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / purchase refund | when a user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when a user generates a lead | | | Y | | | | | | | start trial | when a user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when a user subscribes (recurring payment) | Y | | | | Y | Y | Y | | | select item | when a user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when a user earns virtual currency | | | | Y | | | | | | level up | when a user passes a level | | | | Y | | | | | | spend virtual currency/credit | when a user spends virtual currency | | | | Y | | | | | | tutorial begin | when a user starts the tutorial | | | | Y | | | | | | tutorial complete | when a user completes the tutorial | | | | Y | | | | | | unlock achievement | when a user unlocks an achievement | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start or media play | when user starts to play media in the app | | | | | Y | | | | ## Granting Access to Criteo Granting Adjust dashboard access to Criteo allows our expert teams to validate integration setups and provide a better level of support, if required: * Hover over the profile icon at the bottom-left and choose **Account settings** * Under the tab **Users**, click on the button **New user** (in case there isn't any user from Criteo yet) * In **User Details**, add the e-mail address requested by your Criteo contact: * In case no specific account was requested, input `adjust_criteo@criteo.com` * For first & last names, feel free to type any name (from existing accounts, those will be overwritten by the names defined previously) * Leave *English* as preferred language * As role, choose: * **Editor**: to give our teams edit access to our integration module, under Campaign Lab, on your behalf and read access to campaigns metrics, under Datascape (preferred option) * or **Reader**: to provide only read access to your campaigns metrics, under Datascape * Hit **Add user** Image Both options above will give access to all your edit/read access to all your apps and links. In case you prefer to customize it, choose **Custom** and define specific app(s) and link(s) you want to grant access to. For more info, check: [Adjust Permission Levels](https://help.adjust.com/en/article/permission-levels) ## Additional Features ### Audiences Connection Criteo has the ability to receive Audiences created by marketers on [Audience Builder](https://help.adjust.com/en/classic/article/audience-builder-classic). If this feature is available in your Adjust plan and you wish to share audiences to use on Criteo campaigns, the process to create the connection is described below: * Under **DataWorks** > **Connections**, select **New Connection** * Look for *Criteo* in the **Partner** field and, in **Services**, choose **Audience Builder** * Press **Connect** Image * After it, you'll be redirected to a Criteo page where you need to review the permissions for Adjust's API app to access your account on Criteo platform * *Audience*: `Manage` access, to create/update audiences in our Criteo account on your behalf * *Analytics*: `Read` access, to read statistics about your campaigns and enrich Adjust dashboard * Under **Portfolio access**, make sure to **Select all entities** to allow Adjust to access all your advertisers accounts (if applicable) * **Approve** it! Image You should now be redirected back to Adjust dashboard and able to connect your audiences with us seamlessly. ## Catalog Feed for Dynamic Campaigns A catalog feed is an XML or a CSV file containing product information (name, price, deep link, image link…) that allows Criteo to dynamically generate the product-recommendation banners. Therefore, it is important to keep this file up to date for Criteo to show the right data in your banners. Criteo may already have the products catalog in some cases (i.e. advertisers already live on web campaigns). Criteo **recommends** to have both Native Deeplinks (aka "URI Scheme" links) and Universal/App Links whenever possible. For more info, check: * [Adjust Deep Linking for Android](https://help.adjust.com/en/article/deep-linking-android-sdk) * [Adjust Deep Linking for iOS](https://help.adjust.com/en/article/deep-linking-ios-sdk) # Adjust In-App Events [iOS] Source: https://developers.criteo.com/mobile-integrations/docs/adjust-ios Implement Criteo in-app events for iOS using the Adjust SDK. ## Overview This document provides detailed information on the following implementation steps related to the source code of the app (if required): * Recommended events and parameters * Deep link implementation * Testing requirements For general integration steps, check [Criteo Integration With Adjust](/mobile-integrations/docs/adjust-criteo-integration). ## In-App Events Implementation ### View Home The viewHome event is automatically sent once Criteo has been activated on the app. It is triggered for each new user session. ### App Deeplink The AppDeeplink event should be triggered every time the app is opened with a deeplink. For each activity that accepts deeplinks, add the following call: ```swift theme={null} func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { ... let event = ADJEvent(eventToken: "{deeplinkEventToken}") event.addPartnerParameter("criteo_deeplink", value: url.toString(data)); Adjust.trackEvent(event); ... // Apply your logic to determine the return value of this method return true; // or // return false; } func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { ... if userActivity.activityType == NSUserActivityTypeBrowsingWeb { let event = ADJEvent(eventToken: "{deeplinkEventToken}") let url = userActivity.webpageURL! event?.addPartnerParameter("criteo_deeplink", value: url.toString(data)); Adjust.trackEvent(event); } // Apply your logic to determine the return value of this method return true; // or // return false; ... } ``` ### View Listing The viewListing event should be triggered on pages displaying product lists, like category or search results screens. To allow our platform to identify the type of products the user is interested in, you must include the IDs of the top three products displayed in the list, which should match those passed in the catalog feed. ```swift theme={null} let event = ADJEvent(eventToken: "{viewListingEventToken}") let productIds = ["productId1", "productId2", "productId3"] event?.addPartnerParameter("products", value: String(describing: productIds)) Adjust.trackEvent(event) ``` ### View Product The viewProduct event should be triggered on all product-details screens. You must include the ID of the product detailed on the screen, which must be the same one provided in the catalog feed. ```swift theme={null} let event = ADJEvent(eventToken: "{viewProductEventToken}") event?.addPartnerParameter("product", value: "productId") Adjust.trackEvent(event) ``` ### View Basket The viewBasket event should be triggered on the basket-details screens. You must include the IDs, unit prices, and quantities of the products available in the basket. ```swift theme={null} let event = ADJEvent(eventToken: "{cartEventToken}") let productIds = ["productId1", "productId2", "productId3"] let productPrice = ["1200","2500","200"] let productQuantity = ["1","2","3"] event?.addPartnerParameter("productids", value: String(describing: productIds)) event?.addPartnerParameter("productPrice", value: String(describing: productPrice)) event?.addPartnerParameter("productQuantity", value: String(describing: productQuantity)) Adjust.trackEvent(event) ``` ### Track Transaction The trackTransaction event should be triggered on order confirmation screens after checkout. You must include a unique transaction ID as well as the IDs, unit prices, and quantities of the products contained in the transaction. ```swift theme={null} let event = ADJEvent(eventToken: "{transactionConfirmedEventToken}") let productIds = ["productId1", "productId2", "productId3"] let productPrice = [12.0, 25.0, 2.0] let productQuantity = [1, 2, 3] event?.addPartnerParameter("productids", value: String(describing: productIds)) event?.addPartnerParameter("productPrice", value: String(describing: productPrice)) event?.addPartnerParameter("productQuantity", value: String(describing: productQuantity)) event?.addPartnerParameter("transactionId", value: "abc123") event?.addPartnerParameter("currency", value: "EUR") event?.addPartnerParameter("setRevenue", value: "68.0") Adjust.trackEvent(event) ``` ### Dates for Travel It's possible to attach check-in and check-out dates to every Criteo event with the parameter keys `din` & `dout`. The format of the dates is `"yyyy-mm-dd"` and it has to be set every time a user enters new search dates. For example: ```swift theme={null} event?.addPartnerParameter("din", value: "2021-01-01") event?.addPartnerParameter("dout", value: "2021-01-07") ``` The dates will be sent with every Criteo event for the duration of the application lifecycle, so they must be set again when the app is re-launched. The search dates can be removed by setting the parameter keys `din` & `dout` to null. For flight, if no checkout date has been selected then the same date should be provided in the check-in and checkout dates. ### Hashed Email for Cross-Device Targeting Clients have the option of sending Criteo the email address of app users when available. This will enable the cross-device Criteo targeting feature. For instance, if the email is "[*j.doe@gmail.com*](mailto:j.doe@gmail.com)", it can be sent in the format of [SHA-256](https://en.wikipedia.org/wiki/SHA-2) (preferred) or [MD5](https://en.wikipedia.org/wiki/MD5) hashed strings in the events as below: SHA-256: ```swift theme={null} event?.addPartnerParameter("criteo_email_hash_sha256", value: "3ce6f3866c13320081cd44f40402527b94f4c2ef24ea1ee163e83650b8f04d01") ``` MD5: ```swift theme={null} event?.addPartnerParameter("criteo_email_hash_md5", value: "8115b7da7fff37aeaec18779411a1042") ``` The hashed email will be sent with every Criteo event for the duration of the application lifecycle, so it must be set again when the app is relaunched. The hashed email can be removed by setting the value to an empty string: ```swift theme={null} event?.addPartnerParameter("criteo_email_hash", value: "") ``` Following are the steps to generate a hashed email address for Criteo: * Convert all characters to lower case * Remove any blank spaces * Convert to UTF-8 * Hash using SHA-256 or MD5 algorithm * Email addresses need to be hashed before setting them in the event parameter. You can use existing libraries in Objective-C/Swift or create your own function for it. ### Customer ID A Customer ID can be provided in all events. If the user is logged in to the advertiser's app, the user ID should be passed. User ID is an optional parameter and should be left as an empty string if the user is logged out or the User ID is unavailable. Customer ID can be any string, as long as it does not contain any Personally Identifiable Information. ```swift theme={null} event?.addPartnerParameter("customer_id", value: "12323dsvhdsb23") ``` ## Enabling Reattribution via Deeplink ### Adjust SDK v4.11.4+ Adjust enables you to run re-engagement campaigns with usage of deep links. If you are using the Adjust SDK v4.11.4 and above, this feature is enabled within the SDK. Once you have received deep link content information in your app, you must call the `appWillOpenUrl` method. By making this call, the Adjust SDK will try to find if there is any new attribution info inside of the deep link and if any, it will be sent to the Adjust backend. See below for implementation of `appWillOpenUrl` for `openURL` & `continueUserActivity`: ```swift theme={null} func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { Adjust.appWillOpen(url) // Apply your logic to determine the return value of this method return true; // or // return false; } ``` ```swift theme={null} func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { ... if userActivity.activityType == NSUserActivityTypeBrowsingWeb { let url = userActivity.webpageURL! Adjust.appWillOpen(url) } // Apply your logic to determine the return value of this method return true; // or // return false; ... } ``` For more info, check Adjust Help Center: [Set up direct deep linking](https://help.adjust.com/en/article/set-up-direct-deep-linking-ios#modify-your-ios-app) ## Testing Process You should contact Criteo to start the testing phase as soon as the events are implemented. Please allow sufficient time (at least a week before) for testing prior to the app submission in order to ensure that the data you are sending is complete. Criteo will require the following elements: * App build to test the collection of events on Criteo side. * It is recommended to set the Sandbox environment and the logs level to verbose on your app as shown: ```swift theme={null} let appToken = "{YourAppToken}" let environment = ADJEnvironmentSandbox let adjustConfig = ADJConfig(appToken: appToken, environment: environment) adjustConfig?.logLevel = ADJLogLevelVerbose Adjust.appDidLaunch(adjustConfig!) ``` # AppsFlyer In-App Events [Android] Source: https://developers.criteo.com/mobile-integrations/docs/appsflyer-android Implement Criteo in-app events for Android using the AppsFlyer SDK. ## About this Guide This document provides detailed information on the following: * Recommended events and parameters * Deep link implementation * Testing process ## Recommended Events per Vertical The recommendation is to send all events that describe the "user-flow" in the app. | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | ------------------------------- | ---------------------------------------------------- | ------ | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when a user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when a user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when a user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when a user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / sign up | when a user creates an account | Y | Y | Y | Y | Y | Y | Y | Y | | login | when a user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when a user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when a user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / refund | when a user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when a user generates a lead | | | Y | | | | | | | start trial | when a user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when a user subscribes (recurring payment) | Y | | | | Y | Y | Y | | | select item | when a user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when a user earns virtual currency | | | | Y | | | | | | level up | when a user passes a level | | | | Y | | | | | | spend virtual currency | when a user spends virtual currency | | | | Y | | | | | | tutorial begin | when a user starts the tutorial | | | | Y | | | | | | tutorial complete | when a user completes the tutorial | | | | Y | | | | | | unlock achievement | when a user unlocks an achievement | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start | when user starts to play media in the app | | | | | Y | | | | ## In-App Events Implementation ### viewHome The `viewHome` event is automatically tracked once the AppsFlyer SDK initializes. This event is fired for each user session. ### viewListing The `viewListing` event should be fired on pages displaying product lists such as a category page or a search results page. You can use `af_view_list` as the event name. You must include the IDs of the first three products displayed on the page. **These IDs must be unique and match those used in the catalog feed.** ```java theme={null} Map listViewEvent = new HashMap(); listViewEvent.put(AFInAppEventParameterName.CONTENT_LIST, new String[]{"item123", "item456", "item789"}); listViewEvent.put(AFInAppEventParameterName.CURRENCY,"USD"); listViewEvent.put(AFInAppEventParameterName.DATE_A,"2015-10-01"); // Check-in date listViewEvent.put(AFInAppEventParameterName.DATE_B,"2015-10-05"); // Check-out date AppsFlyerLib.getInstance().trackEvent(this.getApplication(), "af_view_list", listViewEvent); ``` ### viewProduct The `viewProduct` event should be fired on all product-details pages. You can use AppsFlyer's `AFInAppEventType.CONTENT_VIEW` constant for this event. You must use the ID of the product detailed on the page. **The product ID must be unique and must be the same ID used in the catalog feed.** ```java theme={null} Map contentViewEvent = new HashMap(); contentViewEvent.put(AFInAppEventParameterName.CONTENT_ID,"item123"); contentViewEvent.put(AFInAppEventParameterName.CURRENCY,"USD"); contentViewEvent.put(AFInAppEventParameterName.DATE_A,"2015-10-01"); // Check-in date contentViewEvent.put(AFInAppEventParameterName.DATE_B,"2015-10-05"); // Check-out date AppsFlyerLib.getInstance().trackEvent(this.getApplication(), AFInAppEventType.CONTENT_VIEW, contentViewEvent); ``` ### viewBasket The `viewBasket` event should be fired on the basket-details pages. You can use the event name `af_view_cart`. You must include the ID, unit price, and quantity for each product in the basket. ```java theme={null} Map viewBasket = new HashMap(); viewBasket.put(AFInAppEventParameterName.CONTENT_ID, new String[]{"123a","988b","399c"}); viewBasket.put(AFInAppEventParameterName.QUANTITY, new String[]{"2","1","1"}); viewBasket.put(AFInAppEventParameterName.PRICE, new String[]{"25.20","50.25","10.15"}); viewBasket.put(AFInAppEventParameterName.CURRENCY, "USD"); viewBasket.put(AFInAppEventParameterName.DATE_A,"2015-10-01"); // Check-in date viewBasket.put(AFInAppEventParameterName.DATE_B,"2015-10-05"); // Check-out date AppsFlyerLib.getInstance().trackEvent(this.getApplication(), AFInAppEventType.INITIATED_CHECKOUT, viewBasket); ``` ### trackTransaction The `trackTransaction` event should be fired on order-confirmation pages. You can use AppsFlyer's `AFInAppEventType.PURCHASE` constant for this event. **You must include a unique transaction ID as well as the ID, unit price, and quantity for each purchased product.** ```java theme={null} Map trackTransaction = new HashMap(); trackTransaction.put(AFInAppEventParameterName.CONTENT_TYPE,"category_a"); trackTransaction.put(AFInAppEventParameterName.REVENUE,110); trackTransaction.put(AFInAppEventParameterName.CURRENCY,"USD"); trackTransaction.put(AFInAppEventParameterName.CONTENT_ID,new String[]{"123a", "343rd", "39f9w"}); trackTransaction.put(AFInAppEventParameterName.QUANTITY,new String[]{"2","1","1"}); trackTransaction.put(AFInAppEventParameterName.PRICE, new String[]{"25.20","50.25","10.15"}); trackTransaction.put(AFInAppEventParameterName.DATE_A,"2015-10-01"); // Check-in date trackTransaction.put(AFInAppEventParameterName.DATE_B,"2015-10-05"); // Check-out date trackTransaction.put(AFInAppEventParameterName.RECEIPT_ID,"insert-transaction-id-here"); AppsFlyerLib.getInstance().trackEvent(this.getApplication(), AFInAppEventType.PURCHASE, trackTransaction); ``` ### Hashed Email for Cross-Device Targeting Clients should send Criteo the hashed email address of the app user when available, to enable cross-device targeting. Steps to generate a hash of an email address: 1. Convert all characters to lower case 2. Remove any blank spaces 3. Convert to UTF-8 4. Hash using **SHA256** algorithm ```java theme={null} // You can pass one email... AppsFlyerLib.getInstance().setUserEmails(AppsFlyerProperties.EmailsCryptType.SHA256, "email@mydomain.com"); // ...or multiple emails AppsFlyerLib.getInstance().setUserEmails(AppsFlyerProperties.EmailsCryptType.SHA256, "email1@mydomain.com", "email2@mydomain.com"); ``` ### Dates for Travel It's possible to attach check-in and check-out dates to every Criteo event with `AFInAppEventParameterName.DATE_A` for check-in date and `AFInAppEventParameterName.DATE_B` for check-out date. The format is `"yyyy-mm-dd"`. ```java theme={null} Event.put(AFInAppEventParameterName.DATE_A,"2015-10-01"); Event.put(AFInAppEventParameterName.DATE_B,"2015-10-05"); ``` ## Testing Process Once all events have been implemented, you should contact your Criteo representative to begin the testing phase. Please allow sufficient time (at least a week before) for testing **prior** to the app submission in order to ensure that the data you are sending is complete. Criteo requires the following elements: * App build to test the collection of events on Criteo side. * If testing remotely, the IDFA of the test device. * Deep link example (homepage & product detail). # Criteo Integration With AppsFlyer Source: https://developers.criteo.com/mobile-integrations/docs/appsflyer-criteo-integration Set up your Criteo App campaigns (App Install or App Retargeting) with AppsFlyer. ## Overview This page will guide you in setting up your Criteo App campaign(s) with AppsFlyer, either App Install or App Retargeting campaigns. ## Dashboard Configuration Keep in mind that the following settings are Criteo's recommendations but the ultimate goal is to match the options you want to take into account for your setup! ### App Settings Under **Settings** > **App Settings**, please follow these steps: 1. **Enable view-through attribution via probabilistic modeling** 2. Enable **Re-engagement attribution** * When enabled, AppsFlyer can attribute users who already have the app installed to a retargeting campaign if they engage with the campaign and then return to the app. 3. Leave default option **None** for **Minimum time between re-engagement conversions** * On re-engagement a window opens to attribute re-engagement in-app events to the retargeting network. This helps you to measure the effectiveness of retargeting campaigns. However, if another network brings a new re-engagement during this window, it replaces the last re-engagement, and all subsequent events are attributed to the new network. By using the **Minimum time between re-engagement conversions** set to **none**, you can stop this from occurring. You can find more information [here](https://support.appsflyer.com/hc/en-us/articles/207033786-Retargeting-attribution-guide#exclusion-windows). 4. Hit **Save settings** Image In a case where **Re-engagement attribution** is left disabled, Criteo won't have any in-app conversions/sales attributed to our Retargeting campaigns. ### Partner Configuration To proceed with Criteo-specific configurations: 1. Navigate to **Collaborate** > **Partner Integrations** > **Marketplace** and search for **Criteo** 2. Select **Integrate** Image 3. You will be automatically redirected to the **Integration** tab, where you should switch on the toggle **Activate partner** Image 4. \[Optional] **Install view-through attribution** * Set to **OFF** by default. Enable ONLY if you consider Install view-through attribution. It attributes installs to a media source after the user sees an impression. You can find more information [here](https://support.appsflyer.com/hc/en-us/articles/210084473-Measure-view-through-engagements). 5. \[Optional] **Re-engagement view-through attribution** * Set to **OFF** by default. Enable ONLY if you consider Re-engagement view-through attribution. It determines whether a retargeting partner can receive credit when a user sees a retargeting ad (but does not click it) and later opens or engages with the app. When it is **off**, AppsFlyer requires a click for re-engagement attribution. Image 6. **Default postbacks** — Defines the sources of users sending postbacks. You can find more info [here](https://support.appsflyer.com/hc/en-us/articles/4410395957521-Set-up-an-integrated-partner#default%20postbacks). * **Install: All media sources, including organic** * To share with Criteo the full MMP install stream (including installs not attributed to Criteo) in order to perform troubleshooting and discrepancy analysis. Criteo knows from the postbacks which ones are attributed to it and which ones are not. * **Rejected Install: This partner only** * It is a separate rejected-events / fraud-quality stream, not the general install stream. Keeping it partner only means Criteo receives its own rejected installs for fraud/troubleshooting, rather than all rejected installs from every media source. * **Re-engagement: This partner only** * AppsFlyer sends re-engagement postbacks only when Criteo is credited for the re-engagement. Image 7. To configure the Criteo postbacks, set **In-App Events Postbacks** to **ON**: * Set **In-App Events Postback Window** to **Lifetime**, so that Criteo can receive postbacks from all active app users * Map all relevant **AppsFlyer events** to **CriteoData** * As sending option, select **All media sources, including organic** * Include **Values & revenue** to forward all available event parameters * **Save** the integration Image Please see the section [Recommended Events per Vertical](#recommended-events-per-vertical) below for the list of recommended events per vertical. ### Criteo Permissions Under the **Permissions** tab, it is highly recommended to: 1. Enable **Ad Network Permissions** for Criteo to see your app in the dashboard 2. Grant, at least, the following permissions to the Criteo team: * Configure integration * Configure In-app event postbacks * Access retention report * Access aggregated conversion data * Access aggregate in-app events data 3. Please don't forget to **Save**. Allowing Criteo to configure the integration and in-app event postbacks can increase the efficiency in the partner setup and allow quicker troubleshooting. Image ## Tracking in AppsFlyer ### Tracking Generation Under the **Attribution Link** tab, generate the **Click Tracking Link** and send it to your Criteo contact. Some typical settings: * Add campaign name Image * Enable **Retargeting settings** (if applicable) * Provide **URI scheme** deeplink * Leave **Ignore active users for retargeting** OFF (recommended) * This is a retargeting setting that determines whether users who are already active in your app can be counted as retargeting conversions. When set to **OFF**, AppsFlyer does not exclude active users. This means an active user can still be attributed to a retargeting campaign if they engage with a retargeting ad and meet the attribution criteria. * Define **Re-engagement window** * The re-engagement window is the period of time after a user interacts with a retargeting ad during which subsequent app opens and in-app events can be attributed to that retargeting campaign. Image * Define **Click-through attribution** (recommended **7 days**) * Credits installs to the media source when users click an ad. * Define **View-through attribution** (recommended **24 hours**) * Attributes installs to a media source after a user sees an ad impression but doesn't click. * Hit **Save Attribution link** and share with your Criteo contact the generated links Image ## Recommended Events per Vertical The recommendation is to send all events that describe the "user-flow" in the app. The table below shows the recommended events per vertical: | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | --------------------------------------------------- | ------------------------------------------------------------------ | ------ | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when a user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when a user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when a user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when a user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / create an account / sign up | when a user creates an account, signs up or completes registration | Y | Y | Y | Y | Y | Y | Y | Y | | login | when a user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when a user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when a user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / purchase refund | when a user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when a user generates a lead | | | Y | | | | | | | start trial | when a user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when a user subscribes (recurring payment) | Y | | | | Y | Y | Y | | | select item | when a user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when a user earns virtual currency | | | | Y | | | | | | level up | when a user passes a level | | | | Y | | | | | | spend virtual currency/credit | when a user spends virtual currency | | | | Y | | | | | | tutorial begin | when a user starts the tutorial | | | | Y | | | | | | tutorial complete | when a user completes the tutorial | | | | Y | | | | | | unlock achievement | when a user unlocks an achievement | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start or media play | when user starts to play media in the app | | | | | Y | | | | ## Adding Additional In-App Events In case you need to create or modify in-app events, please see the iOS and Android guides for how to implement them in your app: * [AppsFlyer iOS](/mobile-integrations/docs/appsflyer-ios) * [AppsFlyer Android](/mobile-integrations/docs/appsflyer-android) ## Additional Features ### Cost Data Criteo has the ability to share Cost Data from our campaigns with AppsFlyer. This feature is currently available only for accounts with **AppsFlyer ROI360** and, if this is your case, the activation is very simple: 1. Select the **Cost** tab under our integration module 2. If available, enable the checkbox **Get cost data** 3. Hit **Save Cost** to confirm the change Image The data is synchronized 2x per day and populates the cost of all your app campaigns in AppsFlyer dashboards, enabling other cost-dependent metrics like Avg eCPI, ROI, etc. For more info, check: [AppsFlyer ROI360 cost aggregation overview](https://support.appsflyer.com/hc/en-us/articles/207040526-ROI360-cost-aggregation-overview) ### Audiences Criteo is connected with [AppsFlyer Audiences](https://www.appsflyer.com/products/audiences/), which allows our platform to receive and work with your audiences seamlessly with our campaigns. If this feature is available in your AppsFlyer plan and you already have Audiences built, follow the steps below to create an outgoing connection with our Criteo Commerce Growth platform: 1. Under **Engage** > **Audiences** > **Connections**, click in **+ New Connection** 2. Search for **Criteo** in **Partner name** 3. Define an arbitrary **Connection name** of your choice Image 4. Click on **Log in with Criteo** * With it, you'll be redirected to a Criteo page where you can review the permissions for AppsFlyer's API app to access your account on Criteo platform * *Audience*: `Manage` access, to create/update audiences in our Criteo account on your behalf * *Analytics*: `Read` access, to read statistics about your campaigns and enrich AppsFlyer dashboard * *Campaign*: `Read` access, to read your campaigns status * Under **Portfolio access**, make sure to **Select all entities** to allow AppsFlyer to access all your advertisers accounts (if applicable) * **Approve** it!
Image
5. Back to the previous screen, make sure to select all **User Identifiers** available: *IDFA*, *GAID*, *Email*, etc. 6. **Save** it to complete the connection creation! For more info, check: [AppsFlyer Audiences](https://support.appsflyer.com/hc/en-us/sections/6551336428945-Audiences) ### Agency-Managed Setups AppsFlyer allows agency teams to manage app marketing campaigns on behalf of marketer clients (app owners) with different ad networks and have their data/measurement shared between all the entities. For those setups to work seamlessly for the client, agency, and Criteo, it's very important to follow the instructions below: 1. **Our integration module needs to be configured by an Agency user**, not users connected to the app-owner team (described in section [Partner Configuration](#partner-configuration) above) * Even if the module is already pre-configured by the app owner, an agency user is required to repeat the module setup to ensure that the postbacks sent to Criteo are sent respecting the attribution settings made to your agency account. 2. **The ad trackings need to include the correct Agency ID** (`af_prt` parameter — case-sensitive) on both click and impression trackings, if applicable. * `af_prt` stands for Agency Partner ID (or agency account identifier). It's a parameter added to attribution links to indicate that the traffic is being managed by a specific agency account rather than directly by the advertiser. * If the integration module is correctly enabled by the agency, your respective `af_prt` parameter will be automatically included during the [Tracking Generation](#tracking-generation). 3. **Your Agency ID needs to be included in Criteo's list of authorized agencies** before the launch of the campaign(s) * If you believe it's the first time Criteo and your Agency is running campaigns with AppsFlyer, make sure to ask your Criteo contact to add your Agency ID to our allowlist. Not following one of the points above might lead to incorrect attribution from AppsFlyer to our campaigns, which will directly impact the results measured on both platforms. For more info, check: [About agency accounts](https://support.appsflyer.com/hc/en-us/articles/207034106-About-agency-accounts) ## Products Catalog for Dynamic Campaigns A catalog feed is an XML or a CSV file containing product information (name, price, deep link, image link, etc.) that allows Criteo to dynamically generate the product-recommendation banners. Therefore, it is important to keep this file up to date for Criteo to show the right data in your banners. Criteo may already have the products catalog in some cases (i.e., advertisers already live on web campaigns). Criteo **recommends** to have both Native Deeplinks (aka "URI Scheme" links) and Universal/App Links whenever possible. For more information, please follow [AppsFlyer's deep linking guide](https://www.appsflyer.com/resources/guides/deep-linking-for-mobile-marketers/). # AppsFlyer In-App Events [iOS] Source: https://developers.criteo.com/mobile-integrations/docs/appsflyer-ios Implement Criteo in-app events for iOS using the AppsFlyer SDK. ## About this Guide This document provides detailed information on the following: * Recommended events and parameters * Deep link implementation * Testing process ## Recommended Events per Vertical The recommendation is to send all events that describe the "user-flow" in the app. | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | ------------------------------- | ---------------------------------------------------- | ------ | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when a user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when a user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when a user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when a user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / sign up | when a user creates an account | Y | Y | Y | Y | Y | Y | Y | Y | | login | when a user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when a user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when a user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / refund | when a user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when a user generates a lead | | | Y | | | | | | | start trial | when a user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when a user subscribes (recurring payment) | Y | | | | Y | Y | Y | | | select item | when a user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when a user earns virtual currency | | | | Y | | | | | | level up | when a user passes a level | | | | Y | | | | | | spend virtual currency | when a user spends virtual currency | | | | Y | | | | | | tutorial begin | when a user starts the tutorial | | | | Y | | | | | | tutorial complete | when a user completes the tutorial | | | | Y | | | | | | unlock achievement | when a user unlocks an achievement | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start | when user starts to play media in the app | | | | | Y | | | | ## In-App Events Implementation ### viewHome The `viewHome` event is automatically tracked once the AppsFlyer SDK initializes. This event is fired for each user session. ### viewListing The `viewListing` event should be fired on pages displaying product lists such as a category page or a search results page. You can use `AFEventListView` to represent this event. You must include the IDs of the first three products displayed on the page. **These IDs must be unique and match those used in the catalog feed.** ```objc theme={null} [[AppsFlyerTracker sharedTracker] trackEvent:AFEventListView withValues:@{ AFEventParamCurrency: @"USD", AFEventParamContentList: @[@"4", @"5", @"6"], AFEventParamDateA: @"2017-05-05", AFEventParamDateB: @"2017-05-06" } ]; ``` ### viewProduct The `viewProduct` event should be fired on all product-details pages. You can use AppsFlyer's `AFEventContentView` constant for this event. You must use the ID of the product detailed on the page. **The product ID must be unique and must be the same ID used in the catalog feed.** ```objc theme={null} [[AppsFlyerTracker sharedTracker] trackEvent:AFEventContentView withValues:@{ AFEventParamCurrency: @"USD", AFEventParamContentId: @"4", AFEventParamDateA: @"2017-05-05", AFEventParamDateB: @"2017-05-06" } ]; ``` ### viewBasket The `viewBasket` event should be fired on the basket-details pages. You must include the ID, unit price, and quantity for each product in the basket. **These IDs must be unique and match those used in the catalog feed.** ```objc theme={null} [[AppsFlyerTracker sharedTracker] trackEvent:AFEventInitiatedCheckout withValues:@{ AFEventParamCurrency: @"USD", AFEventParamContentId: @[@"5",@"6",@"7"], AFEventParamPrice: @[@5.40,@6.20,@2.45], AFEventParamQuantity: @[@2,@5,@1], AFEventParamDateA: @"2017-05-05", AFEventParamDateB: @"2017-05-06" } ]; ``` ### trackTransaction The `trackTransaction` event should be fired on order-confirmation pages. You can use AppsFlyer's `AFEventPurchase` constant for this event. **You must include a unique transaction ID as well as the ID, unit price, and quantity for each purchased product.** ```objc theme={null} [[AppsFlyerTracker sharedTracker] trackEvent:AFEventPurchase withValues:@{ AFEventParamCurrency: @"USD", AFEventParamReceiptId: @"unique-transaction-id", AFEventParamRevenue: @58.9, AFEventParamContentId: @[@"5",@"6",@"7"], AFEventParamPrice: @[@10.2,@15.99,@12.50], AFEventParamQuantity: @[@1,@3,@5], AFEventParamDateA: @"2017-05-05", AFEventParamDateB: @"2017-05-06" } ]; ``` ### Hashed Email for Cross-Device Targeting Clients should send Criteo the hashed email address of the app user when available, to enable cross-device targeting. Steps to generate a hash of an email address: 1. Convert all characters to lower case 2. Remove any blank spaces 3. Convert to UTF-8 4. Hash using **SHA256** algorithm ```objc theme={null} // You can pass one email... [[AppsFlyerTracker sharedTracker] setUserEmails:@"email2@mydomain.com" withCryptType:EmailCryptTypeSHA256 ]; // ...or multiple emails [[AppsFlyerTracker sharedTracker] setUserEmails:@[@"email1@mydomain.com", @"email2@mydomain.com"] withCryptType:EmailCryptTypeSHA256 ]; ``` ## Testing Process Once all events have been implemented, you should contact your Criteo representative to begin the testing phase. Please allow sufficient time (at least a week before) for testing **prior** to the app submission in order to ensure that the data you are sending is complete. Criteo requires the following elements: * App build to test the collection of events on Criteo side. * If testing remotely, the IDFA of the test device. * Deep link example (homepage & product detail). # Branch In-App Events [Android] Source: https://developers.criteo.com/mobile-integrations/docs/branch-android Implement Criteo in-app events for Android using the Branch SDK. ## Overview Criteo serves personalized ads to mobile app users that have high probability of clicking through and making a purchase. Criteo technology is based on real-time product recommendation optimization and prediction engines. In order to enable its technology, Criteo needs: * App Events — App events and relevant data correctly captured on your mobile app. * Deep Linking Capability — Product level deep link capabilities in app to take users back to the products they clicked on. * Catalog Feed — A CSV or XML file (called Catalog Feed) containing product information of a large portion of your mobile app's offers. This document provides detailed information on the following: * Integration * Required events and parameters * Implementation guidelines ## Integration Steps | Steps to Follow | Where to Integrate | | --------------------------- | ------------------------------- | | Integration Kickoff Call | Criteo & client technical teams | | Integration Questionnaire | Client-side | | Catalog Feed Integration | Client-side | | Criteo Event Implementation | Client-side | | Dashboard Configuration | Client-side | | Testing Phase | Criteo & client technical teams | | App Submission & Release | Client-side | | Pre-Launch Checks | Client-side | | Campaign Launch | Client-side | ## App Events & Data ### SDK Initialization Set up and initialize the Branch SDK as recommended by the Branch standard documentation. Find additional SDK Setup documentation [here](https://docs.branch.io/pages/apps/android/#initialize-branch). #### Branch SDK Initialization Ensure that the Branch SDK is initialized in `onStart`. ```java theme={null} // Branch init @Override public void onStart() { super.onStart(); // Branch init Branch.getInstance().initSession(new Branch.BranchReferralInitListener() { @Override public void onInitFinished(JSONObject referringParams, BranchError error) { if (error == null) { Log.i("BRANCH SDK", referringParams.toString()); } else { Log.i("BRANCH SDK", error.getMessage()); } } }, this.getIntent().getData(), this); } @Override public void onNewIntent(Intent intent) { this.setIntent(intent); } ``` #### Track appDeeplink Event ```java theme={null} @Override protected void onCreate() { // NOTE: be sure to remove sensitive / PII data from the intent data coming in. mIntentData = this.getIntent().getData().toString(); // other operations below } @Override public void onNewIntent(Intent intent) { // NOTE: be sure to remove sensitive / PII data from the intent data coming in. mIntentData = this.getIntent().getData().toString(); // other operations below } // ... Branch.getInstance().setRequestMetadata("$criteo_deep_link_url", mIntentData); // map mIntentData to $criteo_deep_link_url ... Branch.initSession(...); ``` ### Events Implementation in the App Criteo requires the implementation of the following events: | Event Name | Retail Event Description | Travel Event Description | | ---------------- | ----------------------------------------- | ------------------------------------------------------------ | | viewHome | App open / app brought to the foreground. | | | viewListing | View of a list of products. | View of a list of hotels or flights, usually after a search. | | viewProduct | View of a specific product. | View of a specific hotel or flight. | | viewBasket | View of shopping basket. | Begin booking process. | | trackTransaction | Purchase of one or more products. | Purchase / booking confirmation. | Below is a table of Branch Event Name constants and how they map to Criteo events. | Branch Event | Criteo Event | | ---------------------------------- | ---------------- | | `BRANCH_STANDARD_EVENT.VIEW_ITEMS` | viewListing | | `BRANCH_STANDARD_EVENT.VIEW_ITEM` | viewProduct | | `BRANCH_STANDARD_EVENT.VIEW_CART` | viewBasket | | `BRANCH_STANDARD_EVENT.PURCHASE` | trackTransaction | #### Branch Universal Objects The Criteo integration with Branch relies on the creation of `BranchUniversalObjects` through the Branch SDK. An array of `BranchUniversalObjects` should be sent with all events (except `app open`). `BranchUniversalObject` represent the product that the user has viewed or purchased and have an associated product **id**, **price**, and **quantity**. If an equivalent of a required Criteo event is already implemented in the app, then either the `BranchUniversalObjects` array needs to be implemented in that event or else a new event needs to be created. #### View Home The `viewHome` event is automatically sent once Criteo has been activated on the app. It is triggered for each new user session. #### View Listing The `viewListing` event should be triggered on pages displaying product lists like a category page or a search results page for Retail, and travel search results page for Travel. You must include the IDs of the top three products displayed in the list by setting the `BranchUniversalObject` name to the ID. These IDs must match those passed in the catalog feed. For **travel** apps, you must send check in (Date1) and check out (Date2) information along with the event. ```java theme={null} BranchUniversalObject buo = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item1") .setPrice(1.0, CurrencyType.USD) .setQuantity(1.5) ); BranchUniversalObject buo2 = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item2") .setPrice(2.0, CurrencyType.USD) .setQuantity(2.5) ); BranchUniversalObject buo3 = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item3") .setPrice(3.0, CurrencyType.USD) .setQuantity(3.5) ); // ... new BranchEvent(BRANCH_STANDARD_EVENT.VIEW_ITEMS) .addContentItems(buo1,buo2,buo3) .addCustomDataProperty("sha256_hashed_email","insert_hashed_email_value") // sha256 hashed email .addCustomDataProperty("din","2025-05-06") // for travel .addCustomDataProperty("dout","2025-05-12") // for travel .logEvent(this); ``` #### View Product The `viewProduct` event should be triggered on all product-details pages. You must include the ID of the product detailed on the page via the `BranchUniversalObject` name, and send the `BranchUniversalObject` with the event. It must be the same ID as used in the catalog feed, and must be unique. ```java theme={null} BranchUniversalObject buo = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item1") .setPrice(1.0, CurrencyType.USD) .setQuantity(1.5) ); // ... new BranchEvent(BRANCH_STANDARD_EVENT.VIEW_ITEM) .addContentItems(buo) .addCustomDataProperty("sha256_hashed_email","insert_hashed_email_value") // sha256 hashed email .addCustomDataProperty("din","2025-05-06") // for travel .addCustomDataProperty("dout","2025-05-12") // for travel .logEvent(this); ``` #### View Basket The viewBasket event should be triggered on the basket-details pages for Retail and when a user begins entering booking details for Travel. You must include the IDs, prices, and quantities of the basket's products via the `BranchUniversalObjects` array. ```java theme={null} BranchUniversalObject buo = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item1") .setPrice(1.0, CurrencyType.USD) .setQuantity(1.5) ); BranchUniversalObject buo2 = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item2") .setPrice(2.0, CurrencyType.USD) .setQuantity(2.5) ); BranchUniversalObject buo3 = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item3") .setPrice(3.0, CurrencyType.USD) .setQuantity(3.5) ); // ... new BranchEvent(BRANCH_STANDARD_EVENT.VIEW_CART) .addContentItems(buo1,buo2,buo3) .addCustomDataProperty("sha256_hashed_email","insert_hashed_email_value") // sha256 hashed email .addCustomDataProperty("din","2025-05-06") // for travel .addCustomDataProperty("dout","2025-05-12") // for travel .logEvent(this); ``` #### Track Transaction The trackTransaction event should be triggered on order confirmation pages for Retail and booking confirmation pages for Travel. For Retail, you must include a unique transaction ID as well as the IDs, prices, and quantities of the products bought in the transaction via the `BranchUniversalObjects` array. For Travel, transaction ID is not required. ```java theme={null} BranchUniversalObject buo = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item1") .setPrice(1.0, CurrencyType.USD) .setQuantity(1.5) ); BranchUniversalObject buo2 = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item2") .setPrice(2.0, CurrencyType.USD) .setQuantity(2.5) ); BranchUniversalObject buo3 = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item3") .setPrice(3.0, CurrencyType.USD) .setQuantity(3.5) ); // ... new BranchEvent(BRANCH_STANDARD_EVENT.PURCHASE) .addContentItems(buo1,buo2,buo3) .addCustomDataProperty("sha256_hashed_email","insert_hashed_email_value") // sha256 hashed email .setTransactionID("transactionID123") // set unique transaction ID .setRevenue(500) // purchase revenue .addCustomDataProperty("din","2025-05-06") // for travel .addCustomDataProperty("dout","2025-05-12") // for travel .logEvent(this); ``` #### UI Status The `Status` should be triggered every time the user opens the app or user status has changed. You must include the status value of the updated status with the event. ```java theme={null} new BranchEvent("UI_STATUS") .addCustomDataProperty("ui_status", "vip_user") .logEvent(MainActivity.this); ``` #### UI Level The `Level` event should be triggered every time the user opens the app or levels up. You must include the level value of the new incremental level reached. ```java theme={null} new BranchEvent("ACHIEVE_LEVEL") .addCustomDataProperty("ui_level", "42") .logEvent(MainActivity.this); ``` #### UI Achievement The `Achievement` event should be triggered every time the user unlocks a new achievement. You must include the name of the achievement. ```java theme={null} new BranchEvent("UI_ACHIEVEMENT") .addCustomDataProperty("ui_achievement", "abc123") .logEvent(MainActivity.this); ``` #### Extra Data The Branch Event allows you to add any key-value pairs via the `addCustomDataProperty` method. To include extra data in the Criteo postback, you must add the extra data in the event. For example, to send the extra data `ui_custom` in the `viewProduct` event: ```java theme={null} BranchUniversalObject buo = new BranchUniversalObject() .setContentMetadata( new ContentMetadata() .setSku("item1") .setPrice(1.0, CurrencyType.USD) .setQuantity(1.5) ); // ... new BranchEvent(BRANCH_STANDARD_EVENT.VIEW_ITEM) .addContentItems(buo) .addCustomDataProperty("ui_custom", "customValue") // add custom parameter .logEvent(MainActivity.this); ``` After this is added to the event, you must also modify the event's postback configuration in Branch's dashboard, referencing this extra data parameter, in order for it to be passed in the event. Image It is highly recommended to [give Branch Dashboard access](https://docs.branch.io/pages/dashboard/access-level/) to your Criteo Technical Solutions Engineer to modify the postback configuration on your behalf. ### Customer ID A Customer ID can be provided in all events. Use the following code snippet to implement: ```java theme={null} branch.getInstance(this).setIdentity("userid123"); ``` If the user is logged in to the advertiser's app, the user ID should be passed. User ID is an optional parameter and should not be set if the user is logged out or the User ID is unavailable. Customer ID can be any string, as long as it does not contain any Personally Identifiable Information. ## Recommended Events per Vertical | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | --------------------------------------------------- | ------------------------------------------------------------------ | ------ | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when a user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when a user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when a user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when a user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / create an account / sign up | when a user creates an account, signs up or completes registration | Y | Y | Y | Y | Y | Y | Y | Y | | login | when a user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when a user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when a user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / purchase refund | when a user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when a user generates a lead | | | Y | | | | | | | start trial | when a user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when a user subscribes (recurring payment) | Y | | | | Y | Y | Y | | | select item | when a user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when a user earns virtual currency | | | | Y | | | | | | level up | when a user passes a level | | | | Y | | | | | | spend virtual currency/credit | when a user spends virtual currency | | | | Y | | | | | | tutorial begin | when a user starts the tutorial | | | | Y | | | | | | tutorial complete | when a user completes the tutorial | | | | Y | | | | | | unlock achievement | when a user unlocks an achievement | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start or media play | when user starts to play media in the app | | | | | Y | | | | ## Testing Process Once all events have been implemented, you should contact your Criteo representative to begin the testing phase. Please allow sufficient time (at least a week before) for testing **prior** to the app submission in order to ensure that the data you are sending is complete. Criteo requires the following elements: * App build to test the collection of events on Criteo side. * If testing remotely, the GAID of the test device. * Deep link example (homepage & product detail). # Branch In-App Events [iOS] Source: https://developers.criteo.com/mobile-integrations/docs/branch-ios Implement Criteo in-app events for iOS using the Branch SDK. ## Overview Criteo serves personalized ads to mobile app users that have high probability of clicking through and making a purchase. Criteo technology is based on real-time product recommendation optimization and prediction engines. In order to enable its technology, Criteo needs: * App Events — App events and relevant data correctly captured on your mobile app. * Deep Linking Capability — Product level deep link capabilities in app to take users back to the products they clicked on. * Catalog Feed — A CSV or XML file (called Catalog Feed) containing product information of a large portion of your mobile app's offers. This document provides detailed information on the following: * Integration * Required events and parameters * Implementation guidelines ## Integration Steps | Steps to Follow | Where to Integrate | | --------------------------- | ------------------------------- | | Integration Kickoff Call | Criteo & client technical teams | | Integration Questionnaire | Client-side | | Catalog Feed Integration | Client-side | | Criteo Event Implementation | Client-side | | Dashboard Configuration | Client-side | | Testing Phase | Criteo & client technical teams | | App Submission & Release | Client-side | | Pre-Launch Checks | Client-side | | Campaign Launch | Client-side | ## App Events & Data ### SDK Initialization Set up and initialize the Branch SDK as recommended by the Branch standard documentation. Find additional SDK Setup documentation [here](https://docs.branch.io/pages/apps/ios/#initialize-branch). #### Branch SDK Initialization Ensure that the Branch SDK is initialized in `didFinishLaunching`. ```objc theme={null} #import "Branch/Branch.h" - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Branch *branch = [Branch getInstance]; [branch initSessionWithLaunchOptions:launchOptions andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) { if (!error && params) { // params are the deep linked params associated with the link that the user clicked -> was re-directed to this app // params will be empty if no data found // ... insert custom logic here ... NSLog(@"params: %@", params.description); } }]; [branch setIdentity:@"customerid123"]; // set customer ID return YES; } ``` #### Track Session Start and App Deeplink Launch Ensure to track the App Launch and App Deeplink Launch events. ```objc theme={null} - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler { // handler for Universal Links [[Branch getInstance] setRequestMetadataKey:@"$criteo_deep_link_url" value:userActivity.webpageURL.absoluteString]; // collect deeplink [branch continueUserActivity:userActivity]; return YES; } // ... @import Branch - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { [[Branch getInstance] setRequestMetadataKey:@"$criteo_deep_link_url" value:url.absoluteString]; // collect deeplink // handler for URI Schemes (depreciated in iOS 9.2+, but still used by some apps) Branch *branch = [Branch getInstance]; [branch application:app openURL:url options:options]; return YES; } ``` ### Events Implementation in the App Criteo requires the implementation of the following events: | Event Name | Retail Event Description | Travel Event Description | | ---------------- | ----------------------------------------- | ------------------------------------------------------------ | | viewHome | App open / app brought to the foreground. | | | viewListing | View of a list of products. | View of a list of hotels or flights, usually after a search. | | viewProduct | View of a specific product. | View of a specific hotel or flight. | | viewBasket | View of shopping basket. | Begin booking process. | | trackTransaction | Purchase of one or more products. | Purchase / booking confirmation. | Below is a table of Branch Event Name constants and how they map to Criteo events. | Branch Event | Criteo Event | | ------------------------------ | ---------------- | | `BranchStandardEventViewItems` | viewListing | | `BranchStandardEventViewItem` | viewProduct | | `BranchStandardEventViewCart` | viewBasket | | `BranchStandardEventPurchase` | trackTransaction | #### Branch Universal Objects The Criteo integration with Branch relies on the creation of `BranchUniversalObjects` through the Branch SDK. An array of `BranchUniversalObjects` should be sent with all events (except `app open`). `BranchUniversalObject` represent the product that the user has viewed or purchased and have an associated product **id**, **price**, and **quantity**. If an equivalent of a required Criteo event is already implemented in the app, then either the `BranchUniversalObjects` array needs to be implemented in that event or else a new event needs to be created. #### View Home The `viewHome` event is automatically sent once Criteo has been activated on the app. It is triggered for each new user session. #### View Listing The `viewListing` event should be triggered on pages displaying product lists like a category page or a search results page for Retail, and travel search results page for Travel. You must include the IDs of the top three products displayed in the list by setting the `BranchUniversalObject` name to the ID. These IDs must match those passed in the catalog feed. For **travel** apps, you must send check in (Date1) and check out (Date2) information along with the event. ```objc theme={null} BranchUniversalObject *buo = [BranchUniversalObject new]; BranchUniversalObject *buo2 = [BranchUniversalObject new]; buo.contentMetadata.sku = @"item1"; buo.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"1.5"]; buo.contentMetadata.quantity = 1; buo2.contentMetadata.sku = @"item2"; buo2.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"2.5"]; buo2.contentMetadata.quantity = 2; buo3.contentMetadata.sku = @"item2"; buo3.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"3.5"]; buo3.contentMetadata.quantity = 3; // ... BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewItems]; event.contentItems = (id) @[ buo, buo2, buo3 ]; event.customData = (NSMutableDictionary*) @{ @"sha256_hashed_email": @"insert_hashed_email_value", // sha256 hashed email @"din": @"2025-02-21", // for travel @"dout": @"2025-02-27" }; // for travel // Log Event [event logEvent]; ``` #### View Product The `viewProduct` event should be triggered on all product-details pages. You must include the ID of the product detailed on the page via the `BranchUniversalObject` name, and send the `BranchUniversalObject` with the event. It must be the same ID as used in the catalog feed, and must be unique. ```objc theme={null} BranchUniversalObject *buo = [BranchUniversalObject new]; buo.contentMetadata.sku = @"item1"; buo.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"1.5"]; buo.contentMetadata.quantity = 1; BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewItem]; event.contentItems = (id) @[ buo ]; event.customData = (NSMutableDictionary*) @{ @"sha256_hashed_email": @"insert_hashed_email_value", // sha256 hashed email @"din": @"2025-02-21", // for travel @"dout": @"2025-02-27" }; // for travel // Log Event [event logEvent]; ``` #### View Basket The viewBasket event should be triggered on the basket-details pages for Retail and when a user begins entering booking details for Travel. You must include the IDs, prices, and quantities of the basket's products via the `BranchUniversalObjects` array. ```objc theme={null} BranchUniversalObject *buo = [BranchUniversalObject new]; BranchUniversalObject *buo2 = [BranchUniversalObject new]; BranchUniversalObject *buo3 = [BranchUniversalObject new]; buo.contentMetadata.sku = @"item1"; buo.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"1.5"]; buo.contentMetadata.quantity = 1; buo2.contentMetadata.sku = @"item2"; buo2.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"2.5"]; buo2.contentMetadata.quantity = 2; buo3.contentMetadata.sku = @"item2"; buo3.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"3.5"]; buo3.contentMetadata.quantity = 3; // ... BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewCart]; event.contentItems = (id) @[ buo, buo2, buo3 ]; event.customData = (NSMutableDictionary*) @{ @"sha256_hashed_email": @"insert_hashed_email_value", // sha256 hashed email @"din": @"2025-02-21", // for travel @"dout": @"2025-02-27" }; // for travel // Log Event [event logEvent]; ``` #### Track Transaction The trackTransaction event should be triggered on order confirmation pages for Retail and booking confirmation pages for Travel. For Retail, you must include a unique transaction ID as well as the IDs, prices, and quantities of the products bought in the transaction via the `BranchUniversalObjects` array. For Travel, transaction ID is not required. ```objc theme={null} BranchUniversalObject *buo = [BranchUniversalObject new]; BranchUniversalObject *buo2 = [BranchUniversalObject new]; BranchUniversalObject *buo3 = [BranchUniversalObject new]; buo.contentMetadata.sku = @"item1"; buo.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"1.5"]; buo.contentMetadata.quantity = 1; buo2.contentMetadata.sku = @"item2"; buo2.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"2.5"]; buo2.contentMetadata.quantity = 2; buo3.contentMetadata.sku = @"item3"; buo3.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"3.5"]; buo3.contentMetadata.quantity = 3; // Create an event and add the BranchUniversalObject to it. BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventPurchase]; // Add the BranchUniversalObjects with the content: event.contentItems = (id) @[ buo, buo2, buo3 ]; // Unique Transaction ID event.transactionID = @"12344555"; event.customData = (NSMutableDictionary*) @{ @"sha256_hashed_email": @"insert_hashed_email_value", // sha256 hashed email @"din": @"2025-02-21", // for travel @"dout": @"2025-02-27" }; // for travel // Log Event [event logEvent]; ``` #### UI Status The `Status` should be triggered every time the user opens the app or user status has changed. You must include the status value of the updated status with the event. ```objc theme={null} BranchEvent *event = [BranchEvent customEventWithName:@"UI_STATUS"]; event.customData = (NSMutableDictionary*) @{ @"ui_status": @"vip_user" }; [event logEvent]; ``` #### UI Level The `Level` event should be triggered every time the user opens the app or levels up. You must include the level value of the new incremental level reached. ```objc theme={null} BranchEvent *event = [BranchEvent customEventWithName:@"ACHIEVE_LEVEL"]; event.customData = (NSMutableDictionary*) @{ @"ui_level": @"42" }; [event logEvent]; ``` #### UI Achievement The `Achievement` event should be triggered every time the user unlocks a new achievement. You must include the name of the achievement. ```objc theme={null} BranchEvent *event = [BranchEvent customEventWithName:@"UI_ACHIEVEMENT"]; event.customData = (NSMutableDictionary*) @{ @"ui_achievement": @"abc123" }; [event logEvent]; ``` #### Extra Data The Branch Event allows you to add any key-value pairs via the `addCustomDataProperty` method. To include extra data in the Criteo postback, you must add the extra data in the event. For example, to send the extra data `ui_custom` in the `viewProduct` event: ```objc theme={null} BranchUniversalObject *buo = [BranchUniversalObject new]; buo.contentMetadata.sku = @"item1"; buo.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:@"1.5"]; buo.contentMetadata.quantity = 1; BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewItem]; event.contentItems = (id) @[ buo ]; event.customData = (NSMutableDictionary*) @{ @"ui_custom": @"customValue" }; // add custom data // Log Event [event logEvent]; ``` After this is added to the event, you must also modify the event's postback configuration in Branch's dashboard, referencing this extra data parameter, in order for it to be passed in the event. Image It is highly recommended to [give Branch Dashboard access](https://docs.branch.io/pages/dashboard/access-level/) to your Criteo Technical Solutions Engineer to modify the postback configuration on your behalf. ### Customer ID A Customer ID can be provided in all events. Use the following code snippet to implement: ```objc theme={null} [branch setIdentity:@"userId"]; ``` If the user is logged in to the advertiser's app, the user ID should be passed. User ID is an optional parameter and should not be set if the user is logged out or the User ID is unavailable. Customer ID can be any string, as long as it does not contain any Personally Identifiable Information. ## Recommended Events per Vertical | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | --------------------------------------------------- | ------------------------------------------------------------------ | ------ | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when a user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when a user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when a user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when a user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / create an account / sign up | when a user creates an account, signs up or completes registration | Y | Y | Y | Y | Y | Y | Y | Y | | login | when a user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when a user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when a user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / purchase refund | when a user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when a user generates a lead | | | Y | | | | | | | start trial | when a user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when a user subscribes (recurring payment) | Y | | | | Y | Y | Y | | | select item | when a user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when a user earns virtual currency | | | | Y | | | | | | level up | when a user passes a level | | | | Y | | | | | | spend virtual currency/credit | when a user spends virtual currency | | | | Y | | | | | | tutorial begin | when a user starts the tutorial | | | | Y | | | | | | tutorial complete | when a user completes the tutorial | | | | Y | | | | | | unlock achievement | when a user unlocks an achievement | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start or media play | when user starts to play media in the app | | | | | Y | | | | ## Testing Process Once all events have been implemented, you should contact your Criteo representative to begin the testing phase. Please allow sufficient time (at least a week before) for testing **prior** to the app submission in order to ensure that the data you are sending is complete. Criteo requires the following elements: * App build to test the collection of events on Criteo side. * If testing remotely, the IDFA of the test device. * Deep link example (homepage & product detail). # Criteo Integration With Branch Source: https://developers.criteo.com/mobile-integrations/docs/branch-overview Configure your Criteo App campaign with Branch. # Overview This page will guide you in setting up your Criteo App campaign with Branch. # App Events & Data Please follow the instructions on [Branch's support pages](https://docs.branch.io/deep-linked-ads/criteo-mobile-tracking/#integrating-the-sdks-and-tracking-in-app-events) for integrating the SDKs and tracking in-app events. # Dashboard Configuration Once your app has the Branch SDK and the relevant events implemented and available in the Branch dashboard, we can proceed with the Dashboard Configuration step. This step allows Branch's Criteo module to: * Start forwarding the events as postbacks to Criteo * Attribute traffic to your Criteo campaigns * Be reviewed by your Criteo technical contact Keep in mind that the following settings are Criteo's recommendations but the ultimate goal is to match the options you want to take into account for your setup! ## \[Recommended] Enable Predictive Aggregate Measurement (PAM) Branch uses PAM to expand attribution coverage for iOS users. For more info, check: [Predictive Aggregate Measurement](https://help.branch.io/v1/docs/predictive-aggregate-measurement) 1. Under **App Settings** > **Attribution** tab, toggle on **PAM** Image 2. Click **Save** ## Enabling Criteo Ad Partner You can enable the Criteo ad partner in the Branch dashboard by following the steps below. 1. Under **Configure** section in the left side menu, select **Ad Partners** 2. Choose "**Criteo**" and click **Save & Enable**: Image ## Configuring Event Postbacks 1. On tab **Postback Config**, enable all relevant event postbacks. Please see the section [Recommended Events per Vertical](#recommended-events-per-vertical) below for the list of recommended events per vertical. 2. \[Recommended] Enable **PAM for Publishers** toggle to enable PAM for Criteo. 3. Make sure you have all checkboxes enabled on columns **Enable** and **All Events**, so that Criteo receives all of those events. 4. Click **Save**! Image ## Attribution Windows Setup Setting up **Impression** based attribution is optional and should be enabled only if taken into account. In order to minimize discrepancies between Criteo and Branch dashboards, we recommend to use the following attribution windows: 1. On tab **Attribution Windows**, enable **Use ad partner attribution settings** 2. For **Install campaigns**, the relevant attribution windows and their recommended values are: * Click to Install: 7 days (default) * Impression to Install: 0 day \[Increase this value if you take impression attribution into account] 3. For **Retargeting campaigns**, they are: * Click to Conversion Event: 30 days (default) * Impression to Conversion Event: 0 day \[Increase this value if you take impression attribution into account] Image 4. Click **Save**! The attribution windows above are **recommendations** to be aligned with our standard campaigns setup. If you still prefer to use different windows, please inform your Criteo contact about your attribution model. For more info, access [Branch Attribution Logic & Settings](https://help.branch.io/using-branch/docs/branch-attribution-logic-settings) ## Branch Link Creation Next, Criteo needs a Branch Link created specifically for our campaign(s), to be used in our banners and inform Branch about our traffic. 1. Still under **Ad Partners** > **Criteo**, click **Create Criteo Link** in the top right side: Image 2. Select **App Install or Engagement** 3. **Name your link** with something that will make it easy to identify if you need it later * Your Ad Partner should be selected already, but feel free to choose one if it isn't. It's important that you select the right Ad Partner for analytics later on. 4. Click **Continue**: Image 5. Now, you can customize your Branch Link in different aspects: * **Analytics Tags**: parameters for reporting purposes, allows you to customize the Channel, Campaign names or Tags Image * **Redirects**: defines the default URLs in case the app is not installed Image Feel free to keep the default options here in case you're not sure what to configure. 6. Click on **Create Link Now** to finish the tracking links creation: Image 7. Copy both Click & Impression Tracking Links and send to your Criteo contact, to be configured on our side! Later on you can find them in the **Link Hub**. ## Dashboard Access Granting your Criteo team access to your Branch dashboard allows us to not only better support you during the integration phase, but it also allows quicker troubleshooting into the future, if needed. 1. Under **Account** -> **Settings** in the left side menu 2. Select tab **Agencies** and **Add New Agency** 3. On **Agency Name**, select **Criteo (641726251249193296)** (our official agency account as Branch Ad Partner) 4. And, on **Access Level**, choose **Team Member**, which will allow us to: * *Link-Level Settings*: view & edit settings for Branch links that need to be configured on Criteo banners * *Channel-Level Settings*: view & edit settings for Criteo-only channel * *App-Level Settings*: view-only access to App settings, for deeper technical troubleshooting * *Aggregate Data*: view-only access to aggregated data, for discrepancies troubleshooting
Image
5. Then, click on **Invite** and our team should accept it soon! # Recommended Events per Vertical The recommendation is to send all events that describe the "user-flow" in the app. Please refer to the detailed integration guide for iOS or Android to configure all events. | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | --------------------------------------------------- | ------------------------------------------------------------------ | ------ | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when a user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when a user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when a user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when a user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / create an account / sign up | when a user creates an account, signs up or completes registration | Y | Y | Y | Y | Y | Y | Y | Y | | login | when a user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when a user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when a user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / purchase refund | when a user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when a user generates a lead | | | Y | | | | | | | start trial | when a user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when a user subscribes (recurring payment) | Y | | | | Y | Y | Y | | | select item | when a user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when a user earns virtual currency | | | | Y | | | | | | level up | when a user passes a level | | | | Y | | | | | | spend virtual currency/credit | when a user spends virtual currency | | | | Y | | | | | | tutorial begin | when a user starts the tutorial | | | | Y | | | | | | tutorial complete | when a user completes the tutorial | | | | Y | | | | | | unlock achievement | when a user unlocks an achievement | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start or media play | when user starts to play media in the app | | | | | Y | | | | # Catalog Feed for Dynamic Campaigns A catalog feed is an XML or a CSV file containing product information (name, price, deep link, image link, etc.) that allows Criteo to dynamically generate the product recommendation banners. Therefore, it is important to keep this file up to date in order for Criteo to show the right data in your banners. The following points need to be kept in mind: * Each product must have a unique ID that must be identical to the one passed in the events. * The catalog feed must contain all or at least most of your site's products. * Recommended image resolution is 300x300 pixels to 400x400 pixels. Criteo will already have the catalog feed in some instances (i.e. live campaigns on mobile, web, or desktop). For more information, please request the dedicated guide from your contact. # Criteo Integration With Singular Source: https://developers.criteo.com/mobile-integrations/docs/criteo-integration-with-singular Configure your Criteo App campaign for App Install or App Retargeting with Singular. ## Overview This page will guide you in setting up your Criteo App campaign(s) with Singular, either App Install or App Retargeting campaigns. ## Singular Dashboard Configuration Keep in mind that the following settings are Criteo's recommendations but the ultimate goal is to match the options you want to take into account for your setup! ### Adding Criteo in Partner Configuration To add Criteo as a partner on Singular's dashboard: 1. Login to Singular Dashboard 2. Under **Attribution Setup** in the side bar, select **Partner Configuration** 3. Search for "*Criteo*" into the text field at the top right 4. Select your app that you want to connect to our campaigns 5. You should see the Criteo partner set up now Image ### Attribution Postbacks Firstly, set the configuration at the app-level, for both **Install** and **Re-engagement** events: * **Send View Through**: ON * **Send All**: ON * Sends postbacks for all users, to allow us to receive all postbacks and identify your existing app audience appropriately. * **Send Fraud Postbacks**: ON * Includes postbacks for events flagged as fraudulent, for troubleshooting. Image Expand the **Postback URL customization and filters** option for both **Install** and **Re-engagement** events: 1. Leave the **Tracker Campaign Name Filter** empty, to allow us to receive all installs/re-engagements independently of the campaign attributed to 2. **Postback URL** can be left with the default postback template (unless your Criteo technical contact says otherwise) Image Image ### Attribution Windows Setup Setting up Impression based attribution is optional. Enable these options ONLY if taken into account. The attribution windows below are **recommendations** to be aligned with our standard campaigns setup. If you still prefer to use different windows, please inform your Criteo contact about your attribution model. In order to minimize discrepancies between Criteo and Singular dashboards, we recommend using the following attribution settings: * Expand the **Installs** section: * Click-through deterministic install window: **7 days** * Click-through probabilistic install window: **24 hours** * View-through deterministic install window: **0(off)** \[Increase this value if you take view-through attribution into account] * View-through probabilistic install window: **0(off)** \[Increase this value if you take view-through attribution into account] Image * Expand the **Re-engagements** section: * Click-through deterministic re-engagement window: **30 days** * Click-through probabilistic re-engagement window: **168 hours** * View-through deterministic re-engagement window: **0(off)** \[Increase this value if you take view-through attribution into account] * View-through probabilistic re-engagement window: **0(off)** \[Increase this value if you take view-through attribution into account] * Re-engagement Inactivity Window: reduced to **1 days** If **Re-engagement Inactivity Window** is **greater than 1 days**, please inform your Criteo contact about the inactivity window used so our campaigns are configured to not retarget users within this window, which would directly affect our results (mostly in terms of CPA and/or ROAS/COS). Image For more info, access Singular's Help Center article [Attribution Logic & Settings](https://support.singular.net/hc/en-us/articles/13000445013531#links_attribution_settings). ### In-app Events Postbacks Next, the following section **In app Events Postback** lets you choose which events postbacks (callbacks) you want to send to Criteo about this app. Here, it's very important that you enable all event postbacks relevant to the user's journey in your app, for our Retargeting campaigns or Installs (for post-install actions measurement). For each of those events, please leave: * Tick **Send All** in order to send postback for all events triggered in your app, regardless of attributed source * **Lookback** as **Unlimited**, so Criteo receives all event postbacks independently of the attribution/install time * This is strongly recommended for Retargeting campaigns * **Include Revenue** enabled, in order to forward revenue data to Criteo and allow us to measure ROAS/COS (enabling the possibility to optimize towards those metrics) Image ## Tracking in Singular To account for Singular attribution settings in our Criteo campaigns, it's required to use Singular Tracking links on our ads. To create it: 1. Navigate to section **Attribution** -> **Manage Link** 2. In case of multiple apps, select the correct one and hit **Create Link** 3. Select **Partner** from the **Link Type** dropdown 4. Select **Criteo** from the **Source Name** dropdown 5. Choose an arbitrary Tracking Link Name Image 6. Expand the **Link Settings and Redirects** section * Set the Link Sub-Domain and Site from the dropdowns. [More info](https://support.singular.net/hc/en-us/articles/13000445013531-How-to-Build-Tracking-Links) * Choose the desired OS to track with this link * Criteo requires one Singular Link per OS * In the option **If the app is not installed go to:**, choose the expected location the user should land in those cases (usually, Google Play / App Store) * For the option **If the app is already installed, go to:**, you can leave it empty for most cases, as Criteo will configure the dynamic redirection through deeplinks in the catalog (see [Products catalog for Dynamic campaigns](#products-catalog-for-dynamic-campaigns)) * Set the **Fallback Destination for Other Platforms** Image 7. Expand the **Attribution Settings** section * Before generating the link, especially if you intend to run App Retargeting campaigns, make sure to turn **ON** the option **Enable re-engagement tracking** * Keep the **Override attribution windows** toggle disabled - because we want to use the partner level configuration settings Image 8. Expand the **Link Summary** section * Forward the links to your Criteo contact Image ## Singular Data Connector Additional metrics can be provided to Singular through our Criteo API, like **Impressions** and **Cost data** (including subsequent metrics, like CTR, eCPC, eCPI, etc.) In order to have those metrics available in our Singular dashboard reports, it is required to configure our respective Data Connector. ### Enabling the Data Connector The next steps guide you in enabling our Data Connector: * On the Singular dashboard, go to **Settings** > **Data Connectors** * Choose to **Add Data Connector** and search for Criteo in the search box * Hit **Sign in with Criteo** Image * In the pop-up that appears, you'll be required to fill in your Criteo credentials and grant access to the Singular Data Pull app to allow it to read statistics data from your campaigns: * In case of multiple advertiser accounts under **Portfolio access**, make sure to **Select all entities** to allow the app to access data from all your campaigns Image **Role:** your Criteo user must have Administrator access to be able to approve this access. If you have doubts, check our [Team section](https://marketing.criteo.com/core/team). For more info, check Singular's Help Center article [Criteo Data Connector](https://support.singular.net/hc/en-us/articles/4410019435419-Criteo-Data-Connector). ## Products Catalog for Dynamic Campaigns A catalog feed is an XML or a CSV file containing product information (name, price, deep link, image link…) that allows Criteo to dynamically generate the product-recommendation banners. Therefore, it is important to keep this file up to date for Criteo to show the right data in your banners. Criteo may already have the products catalog in some cases (i.e. advertisers already live on web campaigns). Criteo **recommends** having both Native Deeplinks (aka "*custom URI Scheme*" links) and Universal Links / Android App Links whenever possible. For more information, please check [Deep Linking Configuration and Requirements](/mobile-integrations/docs/deeplinks). # Deep Linking Configuration and Requirements Source: https://developers.criteo.com/mobile-integrations/docs/deeplinks Configure URI Schemes, Universal Links, and Android App Links for your Criteo App campaigns. ## Overview Deep linking is the mechanism that allows users to be redirected to a specific platform's content by clicking on a link address. This is a process commonly used while users are navigating the Web, under the same or across different websites. It is also applicable, however, to Apps in the mobile environment. The process of App Deep Linking is as follows: * An app's developer will configure the app to "listen" to links of a certain format * When a user clicks on one of these links, the link should trigger a native behaviour from the OS responsible for launching the respective app (Android or iOS) * After the app is launched, its code might contain specific logic to redirect the user to a specific internal screen, or behave in some other particular way based on the specific link triggered Deep linking can be achieved using various approaches, from the original **URI Scheme** mechanism to newer technologies like iOS' **Universal Links** and Android's **App Links**. To maximize compatibility with different environments & publisher capabilities, it's recommended that apps have both functionalities available. ### URI Schemes These can be thought of as similar to the web protocols `https://` and `http://`, only for specific apps. For example: * `myapp://path/to/content?key1=value1&key2=value2` * `mystore://products/details?id=abc123` * `youtube://watch?v=LQoohRwojmw` The first part (before the `://`) is called the **URI Scheme** and it defines which app should be launched by the OS when this link is invoked. The **path** and **query parameters** (after the `://`) can be read by the app's code and will determine the redirection/behaviour inside the app. ### Universal Linking (iOS) / App Links (Android) In iOS 9, Apple introduced what is known as [Universal Links](https://developer.apple.com/ios/universal-links/). This new Mobile Deeplinking solution aims to avoid URI scheme conflicts between apps listening to the same scheme (a known vulnerability of URI schemes), as well as handling cross-environment redirection (between Web & App). It also provides native fallback redirection to a mobile website if the app is not installed. A similar approach called [Android App Links](https://developer.android.com/training/app-links) was released by Google in Android 6.0. Effectively, Universal Links/Android App Links are links that use the secure HTTPS Web protocol to ensure smooth redirection to the app if it's installed, or a fallback to the mobile website: * `https://www.mystore.com/products?id=abc123` * `https://www.youtube.com/watch?v=LQoohRwojmw` * `https://twitter.com/criteo` ### Deep Linking at Criteo Redirection can be set up via either the URI Scheme, Universal Link/App Links, or a combination, and these are required for all campaigns whose landing environment is within your App. Not applicable to App Install campaigns, since in that use case, the user is redirected to the App Store or Play Store. Their usage depends on the type of banner: #### Dynamic Ads These ads have dynamic content that use our varied creative Layouts & our Product Recommendation Engine (powered by proprietary ML algorithms) to maximize the campaign's Click-Through Rate and Conversion Rate. Deeplinking is also specific to the area within the banner that is clicked on. From a macro perspective, our dynamic ads are divided into the zones outlined below: * **Logo Zone:** the part of the banner which has the advertiser's branding content (logo), usually at the top-left of the banner. This is designed to redirect users to the main screen of the app. To configure it, Criteo requires: * `(mandatory)` A URI Scheme that opens the app and redirects the user to the main screen * `(if available)` A similar Universal Link/App Link * **Product Zone:** the part of the banner where the products are displayed and whose resources are loaded directly from the Product Catalog. Clicks in this area are usually designed to redirect users to the product details screen within the app. To configure it, Criteo requires: * `(mandatory)` Product-specific URI Scheme deeplinks in the catalog, which open the app and redirect to the respective product details screen * `(if available)` Similar Universal Links/App Links * **Coupon Zone:** area of the banner covered by Coupons (whenever configured — optional), which are designed to display special offers or seasonal discounts. If configured, Coupons might also redirect users to dedicated screens within the app. To configure it, Criteo requires: * `(optional)` URL Scheme that opens the app and redirects to the main screen * `(optional & if available)` Similar Universal Link/App Link Currently, these configurations are not available in the self-service platform, so please inform your Criteo contact about the desired URI Scheme and UL/AL's to use for your App campaigns. #### Static Ads These are ads whose contents are provided directly & entirely by the advertiser and whose redirection behaviour is the same in the entire banner frame. Here, redirection is also controlled manually and set at the Ad level. To configure it, Criteo requires: * `(mandatory)` URI Scheme which opens the app and redirects to the main screen * `(if available)` Similar Universal Link/App Link This configuration is available in our self-service platform when creating a new Ad under Landing Page URL: Image ### Deep Linking Setup for iOS Apps #### iOS URI Scheme Implementation * These schemes need to be **declared and configured in the info.plist file of your iOS application** * Once configured, a tap on a link of this format will trigger the app and redirect the user into it For more details, please see this [link](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app). Example of a URI Scheme configured in the info.plist file of an iOS project: Image #### Universal Linking To properly configure the Universal Links feature, the following steps must be followed: * The links' domain must be registered in your iOS application's associated domains file * The Apple App Site Association (AASA) file must be hosted on the public domain that the Universal Links should work with: * The AASA file is a JSON file containing the Apple App ID of the app you want the Universal Links to redirect to, as well as the paths from which app redirection should & should not happen For more details, please see this [link](https://developer.apple.com/documentation/xcode/supporting-associated-domains). Example of a domain declared under Associated Domains in Xcode (the iOS IDE) of an iOS project: Image Example AASA file: ```json theme={null} { "applinks": { "details": [ { "appIDs": [ "ABCDE12345.com.example.app", "ABCDE12345.com.example.app2" ], "components": [ { "#": "no_universal_links", "exclude": true, "comment": "Matches any URL with a fragment that equals no_universal_links and instructs the system not to open it as a universal link." }, { "/": "/buy/*", "comment": "Matches any URL with a path that starts with /buy/." }, { "/": "/help/*", "?": { "articleNumber": "????" }, "comment": "Matches any URL with a path that starts with /help/ and that has a query string parameter with name 'articleNumber' and a value of exactly four characters." } ] } ] }, "webcredentials": { "apps": [ "ABCDE12345.com.example.app" ] } } ``` ### Deep Linking Setup for Android Apps #### Android URI Scheme Implementation * These schemes need to be **configured in the manifest.xml of your Android application** * Once configured, a tap on a link of this format will trigger the app and redirect the user into it For more details, please see this [link](https://developer.android.com/training/app-links/deep-linking). Example of URI Scheme configured in manifest.xml of an Android project: Image #### Android App Links To properly configure the Android App Links feature, the following steps must be followed: * The link needs to be registered in your Android application's manifest.xml file, under a **separate intent filter from that of the URI Scheme** * The Digital Asset Link file (assetlinks.json) must be hosted on the public domain that the Android App Links should work with: * `assetlinks.json` is a JSON file which contains the package name and the SHA fingerprint of the app you want the redirection from this link to work for. * `package_name`: The application ID declared in the app's `build.gradle` file * `sha256_cert_fingerprints`: The SHA256 fingerprints of your app's signing certificate. You can use the following command to generate the fingerprint via the Java key tool: ```bash theme={null} keytool -list -v -keystore my-release-key.keystore ``` For more details, please see this [link](https://developer.android.com/training/app-links/verify-android-applinks). Example of a domain configured in the manifest.xml file: Image Example `assetlinks.json` file: ```json theme={null} [{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }] ``` If you are facing issues in identifying either the URI schemes, Universal Links, or App Links to share with the Criteo Team, please reach out to your app's development team for guidance. # Criteo Integration With Kochava [Android] Source: https://developers.criteo.com/mobile-integrations/docs/kochava-android Configure your Criteo App campaign for Android with Kochava. ## Overview Criteo serves personalized ads to mobile app users that have a high probability of clicking through and either installing your app or making an in-app purchase. Criteo technology is based on real-time product recommendation optimization and prediction engines. In order to enable its technology, Criteo needs: * App Events — App events and relevant data correctly captured on your mobile app * Catalog Feed — A CSV or XML file (called a Catalog Feed) containing product information of a large portion of your mobile app's offers * (For Retargeting) Deeplink and Universal Link capability — Product level deep link capabilities in app to take users to the products they clicked on This document provides detailed information on the following integration stages: * App events and parameters * Kochava dashboard configuration, including postbacks * Generation of tracking links * Catalog feed integration (for product-level ads) * Deeplinking & Universal Linking (for Retargeting) * Testing process ## Integration Steps | Steps to Follow | Where to Integrate | | ------------------------------------------------ | ------------------------------------ | | Integration Questionnaire | Client | | Integration Kickoff Call | Criteo & client technical teams | | Dashboard Configuration | Client-side or (recommended) on call | | (for product-level ads) Catalog Feed Integration | Criteo & client technical teams | | (only if needed) Criteo Event Integration | Client-side | | (only if needed) Testing events | Criteo & client technical teams | | (only if needed) App Submission & Release | Client-side | | Pre-Launch Checks | Criteo | | Campaign Launch | Criteo (with client's authorization) | ## App Events & Data If you already have Kochava events configured, please skip this section. To integrate the Kochava SDK and events from scratch, or add additional ones, please expand this section. ### SDK Initialization Please ensure the 'language' parameter in the identity link is the two character language code (lower case) and matches the language of the app to ensure the events are sent to the correct endpoint. Use the following code snippet at the app launch: ```java theme={null} HashMap datamap = new HashMap(); datamap.put(Feature.INPUTITEMS.KOCHAVA_APP_ID, "YOUR_APP_ID_FROM_KOCHAVA_DASHBOARD"); datamap.put(Feature.INPUTITEMS.CURRENCY, Feature.CURRENCIES.USD); Feature kTracker = new Feature(getApplicationContext(), datamap); HashMap kData = new HashMap(); kData.put( "language" , "en" ); kTracker.linkIdentity(kData); ``` ### Events Implementation in the App Below are examples of the different event types Criteo recommends that you integrate using the Kochava SDK: | Kochava event | Description | | -------------------- | ----------------------------------------------------------- | | SessionBegin | App open/brought to the foreground | | View Listing | View of a list of products | | View Product | View of a specific product details page | | View Basket | View of the shopping basket, or an addition made to it | | Purchase | Purchase of one or more products | | Level Achieved | User Level (for Gaming apps) | | Status | User's Subscription Status (i.e. subscriber, free, premium) | | Achievement Unlocked | Major milestone reached within a game (for Gaming apps) | #### SessionBegin The `sessionBegin` event should be sent to Kochava with each new session, after Kochava SDK initialization. *SessionBegin* is a standard event supported by the Kochava SDK. ```java theme={null} kTracker.event("SessionBegin", ""); ``` #### View Listing The `viewListing` event should be triggered on pages displaying product lists like a category page or a search results page. You should include in the array the **IDs of the top 3 products** (it's fine to include more). These IDs must match those passed in the catalog feed. Note that *viewListing* is not supported out of the box using Kochava's SDK and must be implemented as a custom event. ```java theme={null} JSONObject viewListing = new JSONObject(); JSONArray products = new JSONArray(); products.put("productId1"); products.put("productId2"); products.put("productId3"); // number of products in search results, category page, etc. viewListing.put("product", products); kTracker.event("viewListing", viewListing.toString()); ``` #### View Product The `View` event should be triggered on all product details pages. You should include the ID of the product detailed on the page by the Event Item name, and send the Event Item with the event. It must be the same ID as used in the catalog feed, and must be unique. *View* is a standard event supported by the Kochava SDK. ```java theme={null} JSONObject obj = new JSONObject(); obj.put("product", "productId1"); kTracker.event("View", obj.toString()); ``` #### View Basket The `viewBasket` event should be triggered on the basket-details pages. You must include the IDs, prices, and quantities of the basket's products by the Event Items array. Note that *viewBasket* is not supported out of the box using Kochava's SDK and must be implemented as a custom event. ```java theme={null} JSONArray products = new JSONArray(); JSONObject product1 = new JSONObject(); JSONObject product2 = new JSONObject(); // ... add an object for each product in basket JSONObject viewBasket = new JSONObject(); product1.put("id", "productId1"); product1.put("price", 2.95); product1.put("quantity", 5); product2.put("id", "productId2"); product2.put("price", 19.95); product2.put("quantity", 1); products.put(product1); products.put(product2); viewBasket.put("currency", "USD"); // currency of basket viewBasket.put("product", products); MainActivity.kTracker.event("viewBasket", viewBasket.toString()); ``` din/dout parameters are only required for Travel apps (Flights/Hotels/Car Booking) clients. #### Purchase The `Purchase` event should be triggered on order confirmation pages. You should include a unique transaction ID and place the IDs, prices, and quantities of the products bought in the transaction into the Event Items array. *Purchase* is a standard event supported by the Kochava SDK. ```java theme={null} JSONArray products = new JSONArray(); JSONObject product1 = new JSONObject(); JSONObject product2 = new JSONObject(); // ... add an object for each product purchased JSONObject trackTransaction = new JSONObject(); product1.put("id", "productId1"); product1.put("price", 2.95); product1.put("quantity", 5); product2.put("id", "productId2"); product2.put("price", 19.95); product2.put("quantity", 1); products.put(product1); products.put(product2); trackTransaction.put("id", "<>"); // order ID trackTransaction.put("nc", 1); // to indicate a new customer 1, else 0 trackTransaction.put("currency", "USD"); // currency of transaction trackTransaction.put("product", products); kTracker.event("Purchase", trackTransaction.toString()); ``` #### Level Achieved The `userLevel` event allows Kochava to identify the highest level achieved by a user. This event is specific to the Gaming vertical. It should be triggered every time the user levels up. *userLevel* is a standard event supported by the Kochava SDK. ```java theme={null} JSONObject uiLevel = new JSONObject(); uiLevel.put("ui_level", 5); kTracker.event("userLevel", uiLevel.toString()); ``` #### Status The `userStatus` event allows Kochava to identify a user's subscription status (i.e. free, subscriber, premium). This event should be triggered to initialize the user's status and every time when their status changes. Note that *userStatus* is not supported out of the box using Kochava's SDK and must be implemented as a custom event. ```java theme={null} JSONObject uiStatus = new JSONObject(); uiStatus.put("ui_status", "subscriber"); kTracker.event("userStatus", uiStatus.toString()); ``` #### Achievement Unlocked The `achievementUnlocked` event allows Kochava to identify whether a user has reached a specific milestone within the game. *achievementUnlocked* is a standard event supported by the Kochava SDK. ```java theme={null} JSONObject uiAchievement = new JSONObject(); uiAchievement.put("ui_status", "subscriber"); kTracker.event("achievementUnlocked", uiStatus.toString()); ``` ## Hashed Email for Cross-Device Targeting (Recommended) Clients have the option of sending Criteo the email address of app users when available. This will enable the cross-device Criteo targeting feature. To generate a SHA256 hash of an email address: 1. Convert all characters to lower case 2. Remove any blank spaces 3. Convert to UTF-8 4. Hash using SHA256 algorithm The email can be sent to Criteo by associating it with the identity link during SDK initialization. Use the following code snippet as an example of sending a SHA256 hashed email: ```java theme={null} kTracker = new Feature(getApplicationContext(), datamap); HashMap kData = new HashMap(); kData.put( "language" , "en" ); kData.put( "email_sha256" , "46457bb078c674176a72c3a9ac40ba666244652f1b813f8bd839d529285cfa47" ); kTracker.linkIdentity(kData); ``` Kochava's SDK also allows client apps an option to send email in clear text. Kochava servers will hash this email address before forwarding it to Criteo. Use the following code snippet as an example of how to send raw email addresses: ```java theme={null} kTracker = new Feature(getApplicationContext(), datamap); HashMap kData = new HashMap(); kData.put( "language" , "en" ); kData.put( "email_raw" , "kochava@criteo.com" ); kTracker.linkIdentity(kData); ``` ## Kochava Dashboard Configuration ### Adding the 'Criteo New' Network To add 'Criteo New' as a partner on Kochava's dashboard: 1. Login to Kochava Dashboard 2. Select your App 3. Under App Configurations, go to the **Partner Configurations** tab 4. Click **Add Configuration** button Image Finally, input 'Criteo New' into the Media Partner text field and select the 'Criteo New' network option when it appears below the text field. To save Criteo as a partner, click on the Go button. Image ### Configuring Criteo Postbacks Once the partner is configured, postbacks can be set up for each event type. 1. Expand the 'Criteo New' module and go to the **Postbacks** tab. Image 2. *Install* is automatically listed and its status is **Configured Postback**, however, it still needs additional setup (please see step 4 below for details). *SessionBegin* and the other post-install events will be listed once received by Kochava. All the events (except Install) are initially in status **Active Event**, meaning the postback is available but is not sending to Criteo yet. Once a postback is configured, its status becomes **Configured Postback**. Image 3. Click the **+** icon next to an event to create a postback for it. * The postbacks need to be configured for: **Install**, **SessionBegin**, and all other relevant events for the campaign, such as post-install **KPI events**. * For Retargeting, it's highly recommended to also postback the key stages of the purchase funnel (for a retail app this would be events similar to SessionBegin, Search/Category Results, Item Details, Add to Cart, Basket View, Purchase Confirmation). Image 4. All the following settings are **required** for postbacks to function well: * **CRITEO BUNDLE ID**: Unique bundle ID of the app (this uniquely identifies the app to Criteo) * **SEND ALL EVENT DATA**: Switch the toggle **ON** to send all data to Criteo. Essential for harnessing Criteo's machine learning at its full potential (predictive bidding and product recommendations), and useful for other use cases such as audience segmentation and custom reporting. * **DELIVERY DELAY**: Select **Realtime Delivery** * **DELIVERY METHOD**: Select **All** to send attributed, unattributed and organic events to Criteo. Essential for the same machine learning purposes mentioned above, and also to better suppress installed users from your App Install campaigns. Then, click **Save**. Image For **Install**, there is no **Send All Event Data** option to toggle. ### Attribution Settings — Partner Level Keep in mind that the following settings are Criteo's recommendations but the ultimate goal is to match the options you want to take into account for your setup! Kochava attributes conversions through a fallback chain, from most to least precise: **Device Lookback** (deterministic, matches on a hard device ID) is tried first, then progressively looser probabilistic methods — **Fingerprint Lookback** (IP + user agent + other signals), **IP Lookback** (full IP address only), and **Partial IP Lookback** (first three octets of the IP) — to recover attribution for conversions that would otherwise go unmatched. 1. Under App Configurations, go to **Partner Configurations** 2. To the right side of the 'Criteo New' module, select the three-dots menu 3. Click **Reconciliation** Image 4. Configure the windows below according to your attribution model, or these suggested defaults: **\[Optional] Impression Reconciliation** Setting up Impression based attribution is optional. Enable these options ONLY if taken into account. The Impression Reconciliation settings control how Kochava attributes installs/conversions to impression (view-through) ads when no click is available. * **Device Lookback** — Uses a device identifier to match an ad impression to an install/conversion. If set to `24` hours: if the install/conversion happens within 24 hours after the impression, attribution is allowed. * **Modeled Lookback** — The maximum time before an install during which Kochava considers an impression for attribution when a modeled/probabilistic match is used. Modeled attribution is used when no usable device identifier is available and relies on probabilistic device information—primarily IP address and User Agent. If set to `24` hours: Attribution is allowed if the install/conversion occurs within 24 hours of the impression. * **IP Lookback** — The maximum time prior to an install during which Kochava considers impressions for attribution using a modeled IP-based match, where the impression and install are matched using the full IP address, without requiring the User Agent to match. If set to `24` hours: Attribution is allowed if the install/conversion occurs within 24 hours of the impression, when device/modeled matching aren't available. * **Partial IP Lookback** — Uses a less precise version of the IP address. If set to `24` hours: expands probabilistic matching coverage for impression attribution. * **Device Attribution Behavior** — Determines whether Kochava will attempt fingerprint matching when a Device ID is present on the engagement. The default is **Standard**, which means it will not attempt fingerprinting if the device ID is present. More info [here](https://support.kochava.com/articles/campaign-management/15961-partner-reconciliation-settings). **Click Reconciliation** The Click Reconciliation settings control how Kochava attributes installs/conversions to actual ad clicks. * **Device Lookback** — Uses device IDs to match clicks to installs/conversions. If set to `30` days: if the install/conversion happens within 30 days after clicking the ad, attribution is allowed. * **Modeled Lookback** — Modeled Lookback determines how far back, from the time of install, to consider engagements for attribution on a Modeled based match. If set to `7` days: Attribution is allowed if the install/conversion occurs within 7 days after the click. * **IP and Partial IP Lookback** — If set to `24` hours: Allows Kochava to use IP-only and partial-IP matching for click attribution when device/fingerprint matching aren't available. * **Device Attribution Behavior** — Determines whether Kochava will attempt fingerprint matching when a Device ID is present on the engagement. The default is **Standard**, which means it will not attempt fingerprinting if the device ID is present. * **Modeled Attribution Tier** — Modeled Attribution Tier determines the Modeled validation configuration. The Standard setting validates based on a combination of IP Address and User Agent. The Full IP Address setting validates based on IP Address regardless of User Agent. The Partial IP Address setting validates based on the first three stanzas of the IP Address. By default, Modeled Attribution is set to **Standard**. More info [here](https://support.kochava.com/articles/campaign-management/15961-partner-reconciliation-settings). ## Tracking Links ### Install Tracking 1. **Add Tracking to the Campaign** * Log in to Kochava * Select the desired App * Go to Engagement > Campaign Manager * Click 'Add a Tracker' or Select Segment > 'Add a Tracker' Image 2. **Set the Tracking** * **Required:** * Select Campaign * Select Segment * Set Tracker Name * Select Tracker Type: **Acquisition** * Select Media Partner: **Criteo New - Android** * Check the box for **Share with Publisher** * Set Destination URL: Custom / Landing page / Google Referrer Image * **Optional:** * Agency Partner * UTM Parameters * Custom Parameters * Pricing 3. **Copy Click URL and Impression URL** Image ### Retargeting Tracking 1. **Add Tracking to the Campaign** * Log in to Kochava * Select the desired App * Go to Engagement > Campaign Manager * Click 'Add a Tracker' or Select Segment > 'Add a Tracker' Image 2. **Set the Tracking** * **Required:** * Select Campaign * Select Segment * Set Tracker name * Select Tracker Type: Reengagement * Select Media Partner: **Criteo New - Android** * Check the box for **Share with Publisher** * Set Destination URL: Custom / Landing page / Google Referrer Image * Select Event(s) for Reengagement: 'All' (if All is not selected and an event is not in the list, Criteo will not be able to effectively optimize toward the KPI events). Image * **Optional:** * Agency Partner * UTM Parameters * Custom Parameters * Pricing 3. **Set a custom lookback window** * Tracker-level lookback windows can be set within Power Editor → Tracker Overrides, however this is a paid feature of Kochava. 4. **Copy Click URL and Impression URL and send to your Criteo contact** Image ## Catalog Feed A catalog feed is an XML or a CSV file containing product information (name, price, deep link, image link…) that allows Criteo to dynamically generate product-level banners tailored to each user. Therefore, it is important to keep this file up to date in order for Criteo to show the right data in your banners. The following points need to be kept in mind: * Each product must have a unique ID that must be identical to the one passed in the events. * The catalog feed must contain all or at least most of your apps' products for Retail apps, and hotels/airline routes for Travel apps. * Recommended image resolution is 300x300 pixels to 400x400 pixels. Note: In some instances (i.e. live campaigns on mobile web or desktop), Criteo will already have the catalog feed. For more information, please request the dedicated guide from your contact. ## Testing Process Once all events and postbacks have been implemented, you should contact your Criteo representative to begin the testing phase. If you are adding/updating Kochava app events, this will require a release to the app store. In this case, please allow sufficient time (at least a week) for testing **prior** to the app submission in order to ensure that the data you are sending is complete. Criteo requires the following elements: * App build to test the collection of events on Criteo side. * If testing remotely, the GAID of the test device. * (For Retargeting) Deeplink and Universal Link examples — homepage & product details page. # Criteo Integration With Kochava [iOS] Source: https://developers.criteo.com/mobile-integrations/docs/kochava-ios Configure your Criteo App campaign for iOS with Kochava. ## Overview Criteo serves personalized ads to mobile app users that have a high probability of clicking through and either installing your app or making an in-app purchase. Criteo technology is based on real-time product recommendation optimization and prediction engines. In order to enable its technology, Criteo needs: * App Events — App events and relevant data correctly captured on your mobile app * Catalog Feed — A CSV or XML file (called a Catalog Feed) containing product information of a large portion of your mobile app's offers * (For Retargeting) Deeplink and Universal Link capability — Product level deep link capabilities in app to take users to the products they clicked on This document provides detailed information on the following integration stages: * App events and parameters * Kochava dashboard configuration, including postbacks * Generation of tracking links * Catalog feed integration (for product-level ads) * Deeplinking & Universal Linking (for Retargeting) * Testing process ## Integration Steps | Steps to Follow | Where to Integrate | | ------------------------------------------------ | ------------------------------------ | | Integration Questionnaire | Client | | Integration Kickoff Call | Criteo & client technical teams | | Dashboard Configuration | Client-side or (recommended) on call | | (for product-level ads) Catalog Feed Integration | Criteo & client technical teams | | (only if needed) Criteo Event Integration | Client-side | | (only if needed) Testing events | Criteo & client technical teams | | (only if needed) App Submission & Release | Client-side | | Pre-Launch Checks | Criteo | | Campaign Launch | Criteo (with client's authorization) | ## App Events & Data If you already have Kochava events configured, please skip this section. To integrate the Kochava SDK and events from scratch, or add additional ones, please expand this section. ### SDK Initialization Please ensure the 'language' parameter in the identity link is the two character language code (lower case) and matches the language of the app to ensure the events are sent to the correct endpoint. Use the following code snippet at app launch: ```objc theme={null} NSDictionary *identityLinkDictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"TEST_USER_ID", @"myInternalUserID", @"1235467890123456", @"service ID", @"en", @"language", @"46457bb078c674176a72c3a9ac40ba666244652f1b813f8bd839d529285cfa47", @"email_sha256", nil]; NSDictionary *initDict = [NSDictionary dictionaryWithObjectsAndKeys: @"REPLACE_WITH_YOUR_KOCHAVA_APP_ID", @"kochavaAppId", @"USD", @"currency", // optional - usd is default @"0", @"limitAdTracking", // optional - 0 is default @"1", @"enableLogging", // optional - 0 is default identityLinkDictionary, @"identityLink", // optional nil]; kochavaTracker = [[KochavaTracker alloc] initKochavaWithParams:initDict]; ``` ### Events Implementation in the App Below are examples of the different event types Criteo recommends that you integrate using the Kochava SDK: | Kochava event | Description | | -------------------- | ----------------------------------------------------------- | | SessionBegin | App open/brought to the foreground | | View Listing | View of a list of products | | View Product | View of a specific product | | View Basket | View of the shopping basket, or an addition made to it | | Purchase | Purchase of one or more products | | Level Achieved | User Level (for Gaming apps) | | Status | User's Subscription Status (i.e. subscriber, free, premium) | | Achievement Unlocked | Major milestone reached within a game (for Gaming apps) | #### SessionBegin The `sessionBegin` event should be sent to Kochava with each new session, after Kochava SDK initialization. *SessionBegin* is a standard event supported by the Kochava SDK. ```objc theme={null} [delegate.kochavaTracker trackEvent:@"SessionBegin":@"{}"]; ``` #### View Listing The `viewListing` event should be triggered on pages displaying product lists like a category page or a search results page. You should include in the array the **IDs of the top 3 products** (it's fine to include more). These IDs must match those passed in the catalog feed. Note that *viewListing* is not supported out of the box using Kochava's SDK and must be implemented as a custom event. ```objc theme={null} NSMutableDictionary * viewListing = [[NSMutableDictionary alloc] init]; [viewListing setObject:[NSArray arrayWithObjects:@"1", @"2", nil] forKey: @"product"]; jsonData = [NSJSONSerialization dataWithJSONObject:viewListing options:0 error:nil]; [delegate.kochavaTracker trackEvent: @"viewListing": [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; ``` #### View Product The `View` event should be triggered on all product details pages. You should include the ID of the product detailed on the page by the Event Item name, and send the Event Item with the event. It must be the same ID as used in the catalog feed, and must be unique. The Kochava event corresponding to the Criteo Event Type `viewProduct` is *View*. *View* is a standard event supported by the Kochava SDK. ```objc theme={null} NSDictionary * viewProduct = @{@"product": @"1"}; jsonData = [NSJSONSerialization dataWithJSONObject:viewProduct options:0 error:nil]; [delegate.kochavaTracker trackEvent: @"View": [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; ``` #### View Basket The viewBasket event should be triggered on the basket-details pages. You must include the IDs, prices, and quantities of the basket's products by the Event Items array. Note that *viewBasket* is not supported out of the box using Kochava's SDK and must be implemented as a custom event. ```objc theme={null} NSDictionary * viewBasket = @{ @"currency": @"USD", @"product": @[ @{@"id": @"1",@"price": @"2.95",@"quantity": @"5"}, @{@"id": @"2",@"price": @"19.99",@"quantity": @"1"} ], @"din": @"2026-09-07",@"dout": @"2026-09-10" // optional for Travel booking apps }; jsonData = [NSJSONSerialization dataWithJSONObject:viewBasket options:0 error:nil]; [delegate.kochavaTracker trackEvent: @"viewBasket": [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; ``` din/dout parameters are only required for Travel apps (Flights/Hotels/Car Booking) clients. #### Purchase The `Purchase` event should be triggered on order confirmation pages. You should include a unique transaction ID and place the IDs, prices, and quantities of the products bought in the transaction into the Event Items array. *Purchase* is a standard event supported by the Kochava SDK. ```objc theme={null} NSDictionary * trackTransaction = @{ @"nc": @"1", @"id": @"transaction_id", @"currency": @"USD", @"product": @[ @{@"id": @"1",@"price": @"2.95",@"quantity": @"5"}, @{@"id": @"2",@"price": @"19.99",@"quantity": @"1"} ], @"din": @"2026-09-07",@"dout": @"2026-09-10" // optional for Travel booking apps }; jsonData = [NSJSONSerialization dataWithJSONObject:trackTransaction options:0 error:nil]; [delegate.kochavaTracker trackEvent: @"Purchase": [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; ``` #### Level Achieved The `userLevel` event allows Kochava to identify the highest level achieved by a user. This event is specific to the Gaming vertical. It should be triggered every time the user levels up. *userLevel* is a standard event supported by the Kochava SDK. ```objc theme={null} NSDictionary * userLevel = @{@"ui_level": 5}; jsonData = [NSJSONSerialization dataWithJSONObject:userLevel options:0 error:nil]; [delegate.kochavaTracker trackEvent: @"userLevel": [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; ``` #### Status The `userStatus` event allows Kochava to identify a user's subscription status (free, subscriber, premium). This event should be triggered to initialize the user's status, and every time when user status changes. Note that *userStatus* is not supported out of the box using Kochava's SDK and must be implemented as a custom event. ```objc theme={null} NSDictionary * userStatus = @{@"ui_status": @"subscriber"}; jsonData = [NSJSONSerialization dataWithJSONObject:userStatus options:0 error:nil]; [delegate.kochavaTracker trackEvent: @"userStatus": [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; ``` #### Achievement Unlocked The `achievementUnlocked` event allows Kochava to identify whether a user has reached a specific milestone within the game. *achievementUnlocked* is a standard event supported by the Kochava SDK. ```objc theme={null} NSDictionary * userAchievement = @{@"ui_achievement": @"Gold_Medal"}; jsonData = [NSJSONSerialization dataWithJSONObject:userAchievement options:0 error:nil]; [delegate.kochavaTracker trackEvent: @"achievementUnlocked": [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; ``` ## Hashed Email for Cross-Device Targeting (Recommended) Clients have the option of sending Criteo the email address of app users when available. This will enable the cross-device Criteo targeting feature. To generate an SHA256 hash of an email address: 1. Convert all characters to lower case 2. Remove any blank spaces 3. Convert to UTF-8 4. Hash using SHA256 algorithm The email can be sent to Criteo by associating it with the identity link during SDK initialization. Use the following code snippet as an example of sending a SHA256 hashed email: ```objc theme={null} NSDictionary *identityLinkDictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"CriteoKochavaTest", @"myInternalUserID", @"1235467890123456", @"service ID", @"en", @"language", @"46457bb078c674176a72c3a9ac40ba666244652f1b813f8bd839d529285cfa47", @"email_sha256", nil]; NSDictionary *initDict = [NSDictionary dictionaryWithObjectsAndKeys: @"komobile-in--app-events5565020f2e19b", @"kochavaAppId", @"USD", @"currency", // optional - usd is default @"0", @"limitAdTracking", // optional - 0 is default @"1", @"enableLogging", // optional - 0 is default identityLinkDictionary, @"identityLink", nil]; ``` Kochava's SDK also allows client apps an option to send email in clear text. Kochava servers will hash this email address before forwarding it to Criteo. Use the following code snippet as an example of how to send raw email addresses: ```objc theme={null} NSDictionary *identityLinkDictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"CriteoKochavaTest", @"myInternalUserID", @"1235467890123456", @"service ID", @"en", @"language", @"kochava@criteo.com", @"email_raw", nil]; NSDictionary *initDict = [NSDictionary dictionaryWithObjectsAndKeys: @"komobile-in--app-events5565020f2e19b", @"kochavaAppId", @"USD", @"currency", // optional - usd is default @"0", @"limitAdTracking", // optional - 0 is default @"1", @"enableLogging", // optional - 0 is default identityLinkDictionary, @"identityLink", nil]; ``` ## Kochava Dashboard Configuration ### Adding the 'Criteo New' Network To add 'Criteo New' as a partner on Kochava's dashboard: 1. Login to Kochava Dashboard 2. Select your App 3. Under App Configurations, go to the **Partner Configurations** tab 4. Click **Add Configuration** button Image Finally, input 'Criteo New' into the Media Partner text field and select the 'Criteo New' network option when it appears below the text field. To save Criteo as a partner, click on the Go button. Image ### Configuring Criteo Postbacks Once the partner is configured, postbacks can be set up for each event type. 1. Expand the 'Criteo New' module and go to the **Postbacks** tab. Image 2. *Install* is automatically listed and its status is **Configured Postback**, however, it still needs additional setup (please see step 4 below for details). *SessionBegin* and the other post-install events will be listed once received by Kochava. All the events (except Install) are initially in status **Active Event**, meaning the postback is available but is not sending to Criteo yet. Once a postback is configured, its status becomes **Configured Postback**. Image 3. Click the **+** icon next to an event to create a postback for it. * The postbacks need to be configured for: **Install**, **SessionBegin**, and all other relevant events for the campaign, such as post-install **KPI events**. * For Retargeting, it's highly recommended to also postback the key stages of the purchase funnel (for a retail app this would be events similar to SessionBegin, Search/Category Results, Item Details, Add to Cart, Basket View, Purchase Confirmation). Image 4. All the following settings are **required** for postbacks to function well: * **CRITEO BUNDLE ID**: Unique bundle ID of the app (this uniquely identifies the app to Criteo) * **SEND ALL EVENT DATA**: Switch the toggle **ON** to send all data to Criteo. Essential for harnessing Criteo's machine learning at its full potential (predictive bidding and product recommendations), and useful for other use cases such as audience segmentation and custom reporting. * **DELIVERY DELAY**: Select **Realtime Delivery** * **DELIVERY METHOD**: Select **All** to send attributed, unattributed and organic events to Criteo. Essential for the same machine learning purposes mentioned above, and also to better suppress installed users from your App Install campaigns. Then, click **Save**. Image For **Install**, there is no **Send All Event Data** option to toggle. ### Attribution Settings — Partner Level Keep in mind that the following settings are Criteo's recommendations but the ultimate goal is to match the options you want to take into account for your setup! Kochava attributes conversions through a fallback chain, from most to least precise: **Device Lookback** (deterministic, matches on a hard device ID) is tried first, then progressively looser probabilistic methods — **Fingerprint Lookback** (IP + user agent + other signals), **IP Lookback** (full IP address only), and **Partial IP Lookback** (first three octets of the IP) — to recover attribution for conversions that would otherwise go unmatched. 1. Under App Configurations, go to **Partner Configurations** 2. To the right side of the 'Criteo New' module, select the three-dots menu 3. Click **Reconciliation** Image 4. Configure the windows below according to your attribution model, or these suggested defaults: **\[Optional] Impression Reconciliation** Setting up Impression based attribution is optional. Enable these options ONLY if taken into account. The Impression Reconciliation settings control how Kochava attributes installs/conversions to impression (view-through) ads when no click is available. * **Device Lookback** — Uses a device identifier to match an ad impression to an install/conversion. If set to `24` hours: if the install/conversion happens within 24 hours after the impression, attribution is allowed. * **Modeled Lookback** — The maximum time before an install during which Kochava considers an impression for attribution when a modeled/probabilistic match is used. Modeled attribution is used when no usable device identifier is available and relies on probabilistic device information—primarily IP address and User Agent. If set to `24` hours: Attribution is allowed if the install/conversion occurs within 24 hours of the impression. * **IP Lookback** — The maximum time prior to an install during which Kochava considers impressions for attribution using a modeled IP-based match, where the impression and install are matched using the full IP address, without requiring the User Agent to match. If set to `24` hours: Attribution is allowed if the install/conversion occurs within 24 hours of the impression, when device/modeled matching aren't available. * **Partial IP Lookback** — Uses a less precise version of the IP address. If set to `24` hours: expands probabilistic matching coverage for impression attribution. * **Device Attribution Behavior** — Determines whether Kochava will attempt fingerprint matching when a Device ID is present on the engagement. The default is **Standard**, which means it will not attempt fingerprinting if the device ID is present. More info [here](https://support.kochava.com/articles/campaign-management/15961-partner-reconciliation-settings). **Click Reconciliation** The Click Reconciliation settings control how Kochava attributes installs/conversions to actual ad clicks. * **Device Lookback** — Uses device IDs to match clicks to installs/conversions. If set to `30` days: if the install/conversion happens within 30 days after clicking the ad, attribution is allowed. * **Modeled Lookback** — Modeled Lookback determines how far back, from the time of install, to consider engagements for attribution on a Modeled based match. If set to `7` days: Attribution is allowed if the install/conversion occurs within 7 days after the click. * **IP and Partial IP Lookback** — If set to `24` hours: Allows Kochava to use IP-only and partial-IP matching for click attribution when device/fingerprint matching aren't available. * **Device Attribution Behavior** — Determines whether Kochava will attempt fingerprint matching when a Device ID is present on the engagement. The default is **Standard**, which means it will not attempt fingerprinting if the device ID is present. * **Modeled Attribution Tier** — Modeled Attribution Tier determines the Modeled validation configuration. The Standard setting validates based on a combination of IP Address and User Agent. The Full IP Address setting validates based on IP Address regardless of User Agent. The Partial IP Address setting validates based on the first three stanzas of the IP Address. By default, Modeled Attribution is set to **Standard**. More info [here](https://support.kochava.com/articles/campaign-management/15961-partner-reconciliation-settings). ## Tracking Links ### Install Tracking 1. **Add Tracking to the Campaign** * Log in to Kochava * Select the desired App * Go to Engagement > Campaign Manager * Click 'Add a Tracker' or Select Segment > 'Add a Tracker' Image 2. **Set the Tracking** * **Required:** * Select Campaign * Select Segment * Set Tracker Name * Select Tracker Type: **Acquisition** * Select Media Partner: **Criteo New - iOS** * Check the box for **Share with Publisher** * Set Destination URL: Custom / Landing page / Google Referrer Image * **Optional:** * Agency Partner * UTM Parameters * Custom Parameters * Pricing 3. **Copy Click URL and Impression URL** Image ### Retargeting Tracking 1. **Add Tracking to the Campaign** * Log in to Kochava * Select the desired App * Go to Engagement > Campaign Manager * Click 'Add a Tracker' or Select Segment > 'Add a Tracker' Image 2. **Set the Tracking** * **Required:** * Select Campaign * Select Segment * Set Tracker name * Select Tracker Type: Reengagement * Select Media Partner: **Criteo New - iOS** * Check the box for **Share with Publisher** * Set Destination URL: Custom / Landing page / Google Referrer Image * Select Event(s) for Reengagement: 'All' (if All is not selected and an event is not in the list, Criteo will not be able to effectively optimize toward the KPI events). Image * **Optional:** * Agency Partner * UTM Parameters * Custom Parameters * Pricing 3. **Set a custom lookback window** * Tracker-level lookback windows can be set within Power Editor → Tracker Overrides, however this is a paid feature of Kochava. 4. **Copy Click URL and Impression URL and send to your Criteo contact** Image ## Catalog Feed A catalog feed is an XML or a CSV file containing product information (name, price, deep link, image link…) that allows Criteo to dynamically generate product-level banners tailored to each user. Therefore, it is important to keep this file up to date in order for Criteo to show the right data in your banners. The following points need to be kept in mind: * Each product must have a unique ID that must be identical to the one passed in the events. * The catalog feed must contain all or at least most of your apps' products for Retail apps, and hotels/airline routes for Travel apps. * Recommended image resolution is 300x300 pixels to 400x400 pixels. Note: In some instances (i.e. live campaigns on mobile web or desktop), Criteo will already have the catalog feed. For more information, please request the dedicated guide from your contact. ## Testing Process Once all events and postbacks have been implemented, you should contact your Criteo representative to begin the testing phase. If you are adding/updating Kochava app events, this will require a release to the app store. In this case, please allow sufficient time (at least a week) for testing **prior** to the app submission in order to ensure that the data you are sending is complete. Criteo requires the following elements: * App build to test the collection of events on Criteo side. * If testing remotely, the IDFA of the test device. * (For Retargeting) Deeplink and Universal Link examples — homepage & product details page. # Criteo Mobile Endpoint Specification Source: https://developers.criteo.com/mobile-integrations/docs/mobile-endpoint-specification The Criteo Mobile Endpoint Specification for user events integrations. This content can be used for: S2S integrations, direct endpoint integrations from the app and hybrid apps. ## Overview Criteo serves personalized ads to mobile app users who have a high probability of clicking through and engaging with the app. In order to make an accurate prediction on the user's intent and likelihood of conversion, Criteo captures app events and collects relevant data associated with each event from the mobile device. This document provides detailed specifications of the mobile app events, required parameters, and implementation guidelines for mobile data partners, so they can forward the relevant data in the correct format to Criteo. The table below describes what classifies as a product for various business verticals. Ultimately, the product ID sent to Criteo should match the product ID in the product catalog feed of the advertiser imported in our platform: | Business Vertical | Description of Product ID | | ------------------- | -------------------------------------------------------------------- | | Retail / Classified | Unique Product ID / SKU for the purchasable item | | Flights | Airport IATA codes for the flight route | | Hotels | Hotel ID – unique identifier for each hotel in the catalog | | Restaurant Booking | Restaurant ID – unique identifier for each restaurant in the catalog | | Cars | Vehicle ID – unique identifier defining car type and rental company | ## Implementation Mobile event data needs to be transmitted to Criteo endpoints as URL encoded JSON objects. The data should preferably be sent to the Criteo endpoint as an **HTTP POST** request with the body as a JSON data structure. **HTTP GET** requests are also supported. In this case, the JSON data should be sent as the value of the single query parameter `?data=` (in URL-encoded format — see cURL examples below). ### Criteo Endpoints All events should be sent to this endpoint: | Region | Criteo Endpoint URL | | ------ | ----------------------------------- | | ALL | `https://widget.criteo.com/m/event` | Depending on the region of the data center, it might respond with an HTTP `307` redirect. If you are not able to follow redirections, you need to determine the user's location and select the corresponding regional endpoint: | Region | Criteo Endpoint URL | | ------ | ------------------------------------- | | EMEA | `http://widget.eu.criteo.com/m/event` | | AMER | `http://widget.us.criteo.com/m/event` | | APAC | `http://widget.as.criteo.com/m/event` | For the list of countries associated with each region in the table above, see [Appendix B. Criteo Country to Geographic Region Mapping](#appendix-b-criteo-country-to-geographic-region-mapping). ### Event Parameters Following is the list of parameters required for each Criteo event. For a more detailed description of each event parameter, see [Appendix A. Criteo App Events Parameters Summary](#appendix-a-criteo-app-events-parameters-summary). | Parameter Name | Description | | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `account` | Account specific information. This parameter includes the following three elements:
`an`: Account Name or the name of the app bundle
`cn`: 2-letter country code, in lower case
`ln`: 2-letter language code, in lower case | | `site_type` | OS environment, `"aa"` for App Android or `"aios"` for App iOS | | `id` | JSON object with device IDs of the mobile device:

For **iOS**: IDFA (Apple Identifier For Advertisers) and IDFV (Identifier for Vendors — optional)
For **Android**: GAID (Google Advertising ID)

If any of the IDs above is not available, send an empty string instead, i.e.: `"id":{"gaid": ""}` | | `ci` (optional) | Customer ID. If the user is logged in to the advertiser's app, the user ID should be passed. Customer ID can be any string, as long as it does not contain any PII (name, email address, real address, phone number, etc.) | | `events` | Array of JSON objects, each containing the event name and required parameters associated with that event.
See below for the complete list of event types and required parameters for each event | | `ip` | User IP address (IPv4 only) | | `version` | Arbitrary integration version — example: `"s2s_v1.0.0"` | | `source` | Arbitrary integration source identifier — example: `"criteo"` | | `device_info` (optional) | JSON object with device information | | `device_manufacturer` (optional) | Device manufacturer — examples: `"Samsung"`, `"Apple"` | | `device_model` (optional) | Device model — examples: `"Galaxy A21s"`, `"iPhone11"` | | `os_name` (optional) | OS name — examples: `"Android"`, `"iOS"` | | `os_version` (optional) | OS version — examples: `"10"`, `"15.2.1"` | | `user_agent` (optional) | User-agent — example: `"Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)"` | Sample event data structure: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln ": "en" }, "site_type ": "aa", "id": { "gaid": "322fe8ee-4bb1-4718-beab-7b7ba5cd9399" }, "ci": "usr123", "events": [ { "event": "viewProduct", "product": "324334591" } ], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 34; SM-G780F Build/RP1A.200720.012)" } ``` ### HTTP Call Examples & Response Body Sample raw event call using the **HTTP POST** method (recommended): ```bash theme={null} curl -v -L 'http://widget.as.criteo.com/m/event' \ -X POST \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "account": { "an": "com.myapp", "cn": "au", "ln": "en" }, "site_type": "aios", "id": { "idfa": "00000000-0000-0000-0000-000000000000", "idfv": "E8616EC8-44C7-46D3-B267-87F67379FAAB" }, "ci": "74f1a9ad-abb1-427b-8600-2ab370842149", "alternate_ids": [ { "type": "email", "hash_method": "sha256", "value": "7c5db0085523a0e59085122bd9c40c9fc768c3ba9cccbe53895c216888ce6c4d" } ], "events": [ { "event": "viewHome", "timestamp": "2026-07-19T06:30:00Z" } ], "device_info": { "device_manufacturer": "Apple", "device_model": "iPhone16,2", "os_name": "iOS", "os_version": "26.5" }, "ip": "208.127.116.13", "version": "s2s_v1.0.0", "source": "criteo", "user_agent": "FootLocker/344 iPhone16,2 iOS/26.5 rudder-sdk-swift/1.2.1 Darwin" }' ``` A successful request should return HTTP 200 OK with the following response body: ```bash theme={null} HTTP 200 OK ``` ```bash theme={null} { "errors": [], "warnings": [] } ``` Sample raw event call using the **HTTP GET** method: ```bash theme={null} curl -L 'https://widget.criteo.com/m/event?data=%7B%22account%22%3A%7B%22an%22%3A%22com.myapp%22%2C%22cn%22%3A%22us%22%2C%22ln%22%3A%22en%22%7D%2C%22site_type%22%3A%22aa%22%2C%22id%22%3A%7B%22gaid%22%3A%22e16332c1-dd78-4288-a4e3-6190ed632b7e%22%7D%2C%22ci%22%3A%22usr123%22%2C%22events%22%3A%5B%7B%22event%22%3A%22viewHome%22%7D%5D%2C%22device_info%22%3A%7B%22device_manufacturer%22%3A%22Samsung%22%2C%22device_model%22%3A%22SM-G780F%22%2C%22os_name%22%3A%22Android%22%2C%22os_version%22%3A%2214%22%7D%2C%22ip%22%3A%22118.101.198.164%22%2C%22timestamp%22%3A%222024-04-10%2013%3A30%3A00Z%22%2C%22version%22%3A%22s2s_v1.0.0%22%2C%22source%22%3A%22criteo%22%2C%22user_agent%22%3A%22Dalvik%2F2.1.0%20%28Linux%3B%20U%3B%20Android%2024%3B%20SM-G780F%20Build%2FRP1A.200720.012%29%22%7D' ``` ## Event Specifications The following lists standard Criteo app events and required parameters associated with each event. ### View Home This event captures app launch or the default home page view of the mobile app: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "ci": "usr123", "events": [ { "event": "viewHome" } ], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)" } ``` | Attribute Name | Type | Description | | -------------- | ------ | ------------------------------ | | `event` | string | Event name, must be `viewHome` | ### App Deeplink This event captures app launches that were invoked through Native Deeplinks or Universal Link / Android App Links: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "ci": "usr123", "events": [ { "event": "appDeeplink", "deeplink_uri": "myapp://path/to/content?key1=val1&key2=val2" } ], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)" } ``` | Attribute Name | Type | Description | | -------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `event` | string | Event name, must be `appDeeplink` | | `deeplink_uri` | string | Should inform the entire link responsible for invoking the app (with custom URI scheme and query tracking parameters, if applicable).
For more info about App Deeplinking, check [Deep Linking Configuration and Requirements](/mobile-integrations/docs/deeplinks) | This is important to enrich Criteo's measurement capabilities, mostly in terms of Web + App cross-environment landings. ### View Listing This event captures the user's action of viewing a list of product items and should be fired, ideally, when the user accesses category or search screens: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "ci": "usr123", "events": [ { "event": "viewListing", "product": ["324219284", "324346544", "324242096"] } ], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)" } ``` | Attribute Name | Type | Description | | -------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `"viewListing"` | | `product` | array | List of the first 3 product IDs displayed on the screen (required — these should match the product IDs in the catalog feed imported into Criteo platform) | ### View Product This event captures the user's action of viewing a specific product: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "ci": "usr123", "events": [ { "event": "viewProduct", "product": "324219284" } ], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)" } ``` | Attribute Name | Type | Description | | -------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `viewProduct` | | `product` | string / integer | Product ID accessed (required — these should match the product IDs in the catalog feed imported into Criteo platform) | ### View Basket This event captures the user's action of visiting the basket/cart and reviewing the items before checkout: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "ci": "usr123", "events": [ { "event": "viewBasket", "currency": "USD", "product": [ { "id": "1234", "price": 10.2, "quantity": 1 }, { "id": "3456", "price": 1.1, "quantity": 2 }, { "id": "2345", "price": 9.3, "quantity": 5 } ] } ], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)" } ``` | Attribute Name | Type | Description | | --------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `viewBasket` | | `currency` (optional) | string | 3-letter ISO 4217 currency code (required for multi-currency apps)
For more details, check: [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) | | `product` | array | List of product attributes below | | product `id` | string / integer | Product ID from the product catalog imported into Criteo platform | | product `price` | double | Product unit price, final value applied in the basket (with discounts, etc.) | | product `quantity` | integer | Product items quantity in the transaction | ### Track Transaction This event should be fired when the user has completed the purchase: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [{ "event": "trackTransaction", "id": "b8dec919-d8b0-418b-bb95-988ab4870672", "dd": 1, "currency": "USD", "product": [ { "id": "1234", "price": 10.2, "quantity": 1 }, { "id": "2345", "price": 11.2, "quantity": 2 } ] }], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)" } ``` | Attribute Name | Type | Description | | --------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `trackTransaction` | | `id` | string | Client-side transaction/order ID, used for reporting and de-duplication purposes | | `dd` (optional) | integer | De-duplication flag indicating if the transaction should be attributed to Criteo: `"dd": 1` is attributed to Criteo, `"dd": 0` otherwise | | `currency` (optional) | string | 3-letter ISO 4217 currency code (required for multi-currency apps)
For more details, check: [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) | | `product` | array | List of product attributes below | | product `id` | string / integer | Product ID from the product catalog imported into Criteo platform | | product `price` | double | Product unit price, final value applied in the transaction (with discounts, etc.) | | product `quantity` | integer | Product items quantity in the transaction | ## Additional Data for the Travel Vertical Criteo recommends advertisers in the Travel vertical (Flights/Hotels/Car/Restaurant Booking sites) send check-in and check-out dates related to the booking search to help improve our optimization learnings. Those dates can be sent to Criteo as an additional event called `"vs"` in the events array, as in the View Product event example below: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "viewProduct", "product": "324334591" }, { "event": "vs", "din": "2024-06-20", "dout": "2024-07-30" } ], "device_info": { "device_manufacturer": "Samsung", "device_model": "SM-G780F", "os_name": "Android", "os_version": "14" }, "ip": "118.101.198.164", "timestamp": "2024-04-10 13:30:00Z", "version": "s2s_v1.0.0", "source": "s2s", "user_agent": "Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)" } ``` | Attribute Name | Type | Description | | -------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `din` | string | Check-in / departure date selected by the user in the booking search | | `dout` | string | Check-out / return date selected by the user in the booking search
Note: if the `dout` value is not available (i.e. one-way ticket), inform only `din` | Date values must be sent to Criteo in the format `YYYY-MM-DD`. ## Hashed Email for Cross-Device Targeting Mobile advertisers should send Criteo the email address of the app user whenever available, either in SHA-256 hashed format (recommended) or plain-text, to enable our cross-device targeting capabilities and allow for better cross-environment measurement. The hashed email can be added to any of the event types above. Following are the steps to generate a valid hashed email address: * Convert all characters to lower case * Remove any blank spaces * Ensure to use UTF-8 encoding * Hash using the SHA-256 algorithm There are two ways advertisers can append a hashed email to Criteo: * Using the `alternate_ids` structure, or * Using the dedicated `setEmail` event type SHA-256 is the industry standard hash algorithm and is currently the only hash method supported by Criteo. ### Sending Email as `alternate_ids` Following are examples of sending an email address as one of the alternate IDs, in the JSON root: SHA-256 hashed format: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "alternate_ids": [ { "type": "email", "hash_method": "sha256", "value": "66f933bcd8b699c746ce89757ec9b0ff8de9510b5f6e92ae8ccb26e0324ac8a0" } ], "events": [ /* events */ ], // ... } ``` Plain-text format: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "alternate_ids": [ { "type": "email", "hash_method": "none", "value": "test@mydomain.com" } ], "events": [ /* events */ ], // ... } ``` ### Sending Email as Event `setEmail` Following are examples of sending an email address in the dedicated `setEmail` event, as part of the events structure: SHA-256 hashed format: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "viewHome" }, { "event": "setEmail", "email": "66f933bcd8b699c746ce89757ec9b0ff8de9510b5f6e92ae8ccb26e0324ac8a0", "hash_method": "sha256" } ], // ... } ``` Plain-text format: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "alternate_ids": [ { "type": "email", "hash_method": "none", "value": "test@mydomain.com" } ], "events": [ { "event": "viewHome" }, { "event": "setEmail", "email": "test@mydomain.com", "hash_method": "none" } ], // ... } ``` ## Extra Data The Criteo Endpoint accepts generic extra data through the `"events"` structure in the format of key-value pairs. This extra data can be applied to different advanced purposes, like audience segmentation and special tracking needs, among others, and can be added to the events structure as below: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "viewHome", "generic_extra_data": "data_123" } ], // ... } ``` Discuss with your Criteo Technical Solutions Engineer about the usage and implementation of this extra data. ## New Event Taxonomy Specifications The event types above were designed primarily considering clients from the Retail, Travel, and Classified business verticals. For other verticals, it may be useful to collect additional event types to enrich our reporting capabilities. The event types above are our primary source for campaign optimization, so we recommend prioritizing their implementation over the additional event types below (as of today, used only for reporting purposes). ### Recommended Events per Vertical The recommendation is to send all events that describe the "user-flow" in the app. The table below shows the recommended events per vertical: | Event Name | Description | Retail | Travel | Classified | Gaming | Streaming Entertainment | Finance | Dating Social | RideHailing | | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | ------ | ---------- | ------ | ----------------------- | ------- | ------------- | ----------- | | app open/app launch | when user installs the app | Y | Y | Y | Y | Y | Y | Y | Y | | home page / App open | when user opens the app or arrives on the home page | Y | Y | Y | Y | Y | Y | Y | Y | | view item list / listing | when user sees list of items/products/offering | Y | Y | Y | | Y | | | Y | | view item | when user sees one specific item/products/offering | Y | Y | Y | Y | Y | Y | | | | add to cart | when user adds an item/product to the cart | Y | Y | | | | | | | | basket | when user is on the basket page | Y | Y | | | | | | | | purchase | when user makes a purchase | Y | Y | Y | Y | | Y | | Y | | add to wish list | when user adds an item/product to the wish list | Y | Y | | | | | | | | complete registration / sign up | when user creates an account, signs up, or completes registration | Y | Y | Y | Y | Y | Y | Y | Y | | login | when user logs in | Y | Y | Y | Y | Y | Y | Y | Y | | add payment info | when user adds payment info | Y | Y | | | | Y | | Y | | begin checkout | when user starts the purchase flow | Y | Y | | | | Y | | | | purchase cancelled / purchase refund | when user cancels a purchase or asks for a refund | Y | Y | | | | | | Y | | generate lead | when user generates a lead: asks for contact details / sends a message (classified / jobs app, Education, Local Deals, Real Estate) | | | Y | | | | | | | start trial | when user starts the trial version of the app | | | | Y | Y | Y | Y | | | subscribe | when user subscribes (recurring payment) | Y (subscribe to a prime membership program) | | | | Y | Y | Y | | | select item | when user has selected content in an app | | | | Y | | | | Y | | earn virtual currency | when user earns virtual currency (Gaming apps) | | | | Y | | | | | | level up | when user passes a level (Gaming apps) | | | | Y | | | | | | spend virtual currency/credit | when user spends virtual currency (Gaming apps) | | | | Y | | | | | | tutorial begin | when user starts the tutorial (Gaming app) | | | | Y | | | | | | tutorial complete | when user completes the tutorial (Gaming app) | | | | Y | | | | | | unlock achievement | when user unlocks an achievement (Gaming app) | | | | Y | | | | | | search | | | Y | | | | | | | | video/audio start or media play | when user starts to play media in the app (i.e. music/video streaming app...) | | | | | Y | | | | ### Complete Registration Event informing when user registers in the app: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "completeRegistration" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | ------------------------------------------ | | `event` | string | Event name, must be `completeRegistration` | ### Login Event informing when user logs in: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "login" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | --------------------------- | | `event` | string | Event name, must be `login` | ### Add Payment Info Event informing when user adds payment info: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "addPaymentInfo" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | ------------------------------------ | | `event` | string | Event name, must be `addPaymentInfo` | ### Select Product Event informing when user selects a specific product variant within the app: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "selectProduct", "item_id": "ABC1234" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | ----------------------------------------------------------------- | | `event` | string | Event name, must be `selectProduct` | | `item_id` | string | Product ID from the product catalog imported into Criteo platform | ### Begin Checkout Event informing when user starts the checkout: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "beginCheckout", "currency": "USD", "product": [{ "id": "1234", "price": 10.2, "quantity": 1 }, { "id": "2345", "price": 11.2, "quantity": 2 } ] } ], // ... } ``` | Attribute Name | Type | Description | | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `beginCheckout` | | `currency` | string | 3-letter ISO 4217 currency code (required for multi-currency apps)
For more details, check: [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) | | `product` | array | List of product attributes below | | product `id` | string | Product ID from the product catalog imported into Criteo platform | | product `price` | double | Product unit price, final value applied in the checkout (with discounts, etc.) | | product `quantity` | integer | Product items quantity in the transaction |
### Add to Cart Event informing when user adds an item/product to the cart: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "addToCart", "currency": "USD", "product": [ { "id": "1234", "price": 10.2, "quantity": 1 }, { "id": "3456", "price": 1.1, "quantity": 2 }, { "id": "2345", "price": 9.3, "quantity": 5 } ] } ], // ... } ``` | Attribute Name | Type | Description | | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `addToCart` | | `currency` | string | 3-letter ISO 4217 currency code (required for multi-currency apps)
For more details, check: [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) | | `product` | array | List of product attributes below | | product `id` | string | Product ID from the product catalog imported into Criteo platform | | product `price` | double | Product unit price, final value applied in the basket/transaction (with discounts, etc.) | | product `quantity` | integer | Product items quantity in the transaction |
### Add to Wishlist Event informing that user adds an item/product to the wishlist: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [{ "event": "addToWishList", "currency": "USD", "product": [ { "id": "1234", "price": 10.2, "quantity": 1 }, { "id": "3456", "price": 1.1, "quantity": 2 }, { "id": "2345", "price": 9.3, "quantity": 5 } ] }], // ... } ``` | Attribute Name | Type | Description | | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `addToWishList` | | `currency` | string | 3-letter ISO 4217 currency code (required for multi-currency apps)
For more details, check: [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) | | `product` | array | List of product attributes below | | product `id` | string | Product ID from the product catalog imported into Criteo platform | | product `price` | double | Product unit price, final value applied when added to the wishlist (with discounts, etc.) | | product `quantity` | integer | Product items quantity in the transaction |
### Cancel Transaction Event informing that the user cancels a transaction: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "cancelTransaction", "id": "23fe73be-61c0-4af2-a692-b0383eec9d22", "currency": "USD", "product": [ { "id": "1234", "price": 10.2, "quantity": 1 }, { "id": "2345", "price": 11.2, "quantity": 2 } ] } ], // ... } ``` | Attribute Name | Type | Description | | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `event` | string | Event name, must be `cancelTransaction` | | `id` | string | Client-side transaction/order ID, used for reporting and de-duplication purposes | | `currency` | string | 3-letter ISO 4217 currency code (required for multi-currency apps)
For more details, check: [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) | | `product` | array | List of product attributes below | | product `id` | string | Product ID from the product catalog imported into Criteo platform | | product `price` | double | Product unit price, final value applied in the transaction (with discounts, etc.) | | product `quantity` | integer | Product items quantity in the transaction |
### Start Trial Event informing that user starts a service trial: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "startTrial" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | -------------------------------- | | `event` | string | Event name, must be `startTrial` | ### Subscribe Event informing that user subscribes to a service: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "subscribe", "currency": "USD", "total_amount ": "100.50" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | ------------------------------- | | `event` | string | Event name, must be `subscribe` | | `item_id` | string | The value should be an item ID | ### Play Media Event informing when user achieves a new level within the game: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "playMedia", "item_id": "ABC1234" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | ------------------------------- | | `event` | string | Event name, must be `playMedia` | | `item_id` | string | The value should be an item ID | ### Begin Tutorial Event informing when user has completed the tutorial within the game: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "beginTutorial", "tutorial_id": "ab1234" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | ----------------------------------- | | `event` | string | Event name, must be `beginTutorial` | | `tutorial_id` | string | Tutorial ID | ### Complete Tutorial Event informing when user has completed the tutorial within the game: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "completeTutorial", "tutorial_id": "ab1234" } ], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------ | -------------------------------------- | | `event` | string | Event name, must be `completeTutorial` | | `tutorial_id` | string | Tutorial ID | ### Level-Up Event informing when user achieves a new level within the game: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [{ "event": "levelUp", "level_id": "10", "character_id": "A1234", "score": "10" }], // ... } ``` | Attribute Name | Type | Description | | -------------- | ------- | ------------------------------- | | `event` | string | Event name, must be `levelUp` | | `level_id` | string | The level in the game | | `score` | double | The score in the game | | `character_id` | integer | ID of the character in the game | ### Earn Virtual Currency Event informing when user earns virtual currency within the game: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "earnVirtualCurrency", "virtual_currency_name": "virtual_coin", "total_amount ": "10" } ], // ... } ``` | Attribute Name | Type | Description | | ----------------------- | ------ | ----------------------------------------- | | `event` | string | Event name, must be `earnVirtualCurrency` | | `virtual_currency_name` | string | Virtual currency name | | `total_amount` | string | Virtual currency total amount | ### Unlock Achievement Event informing when user has reached a key milestone within the game: ```json theme={null} { "account": { "an": "com.myapp", "cn": "us", "ln": "en" }, "site_type": "aa", "id": { "gaid": "e16332c1-dd78-4288-a4e3-6190ed632b7e" }, "events": [ { "event": "unlockAchievement", "achievement_id": "ab1234" } ], // ... } ``` | Attribute Name | Type | Description | | ---------------- | ------ | --------------------------------------- | | `event` | string | Event name, must be `unlockAchievement` | | `achievement_id` | string | Add an identifier for the achievement | ## Appendix A: Criteo App Events Parameters Summary | Parameter | Description | | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `an` | App name (client identifier), typically Bundle ID or Package Name of the App | | `cn` | Country of the user in ISO 3166 two-letter country code (empty string `""` if not available)
For more details, check: [List of ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) | | `ln` | Language of the app in ISO 639 two-letter language code (empty string `""` if not available)
For more details, check: [List of ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) | | `gaid` | Google Advertising Identifier, required in Android events (empty string `""` if not available) | | `idfa` | Apple Identifier For Advertisers, required for iOS events (for opt-in users, after ATT dialog consent — empty string `""` if not available) | | `idfv` | IDFV of the device (empty string `""` or omit this parameter if not available) | | `product` | Product ID from the product catalog imported into Criteo platform | | `price` | Product unit price, final value applied in the basket/transaction (with discounts, etc.) | | `quantity` | Product items quantity in the basket/transaction | | `site_type` | OS environment, `"aa"` for App Android or `"aios"` for App iOS | | `dd` | De-duplication flag indicating if the transaction should be attributed to Criteo: `"dd": 1` is attributed to Criteo, `"dd": 0` otherwise | | `id` | Client-side transaction/order ID, used for reporting and de-duplication purposes | | `currency` | 3-letter ISO 4217 currency code (required for multi-currency apps)
For more details, check: [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) | | `ip` | User IP address (IPv4 only) | | `version` | Arbitrary integration version — example: `"s2s_v1.0.0"` | | `source` | Arbitrary integration source identifier — example: `"s2s"` | | `timestamp` | Accepted format: `yyyy-MM-ddTHH:mm:ssZ`.
For more details, check: [.NET Standard date and time format strings](https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings) | | `ci` | Customer ID. If the user is logged in to the advertiser's app, the user ID should be passed. Customer ID can be any string, as long as it does not contain any PII (name, email address, real address, phone number, etc.) | | `email` | SHA-256 hashed (or plain-text) email collected whenever the user is logged in — example: `"66f933bcd8b699c746ce89757ec9b0ff8de9510b5f6e92ae8ccb26e0324ac8a0"` | | `din` | Check-in / departure date selected by the user in the booking search | | `dout` | Check-out / return date selected by the user in the booking search | | `user_agent` | User-agent — example: `"Dalvik/2.1.0 (Linux; U; Android 24; SM-G780F Build/RP1A.200720.012)"` | | `device_info` | JSON object with device information | | `device_manufacturer` | Device manufacturer — examples: `"Samsung"`, `"Apple"` | | `device_model` | Device model — examples: `"Galaxy A21s"`, `"iPhone11"` | | `os_name` | OS name — examples: `"Android"`, `"iOS"` | | `os_version` | OS version — examples: `"10"`, `"15.2.1"` | ## Appendix B: Criteo Country to Geographic Region Mapping | Country Code | Country Name | Criteo Datacenter Mapping | | ------------ | -------------------------------------------- | ------------------------- | | AP | Asia/Pacific Region | APAC | | EU | Europe | EMEA | | AD | Andorra | EMEA | | AE | United Arab Emirates | EMEA | | AF | Afghanistan | EMEA | | AG | Antigua and Barbuda | AMER | | AI | Anguilla | AMER | | AL | Albania | EMEA | | AM | Armenia | EMEA | | CW | Curacao | AMER | | AO | Angola | EMEA | | AQ | Antarctica | AMER | | AR | Argentina | AMER | | AS | American Samoa | APAC | | AT | Austria | EMEA | | AU | Australia | APAC | | AW | Aruba | AMER | | AZ | Azerbaijan | EMEA | | BA | Bosnia and Herzegovina | EMEA | | BB | Barbados | AMER | | BD | Bangladesh | APAC | | BE | Belgium | EMEA | | BF | Burkina Faso | EMEA | | BG | Bulgaria | EMEA | | BH | Bahrain | EMEA | | BI | Burundi | EMEA | | BJ | Benin | EMEA | | BM | Bermuda | AMER | | BN | Brunei Darussalam | APAC | | BO | Bolivia | AMER | | BR | Brazil | AMER | | BS | Bahamas | AMER | | BT | Bhutan | APAC | | BV | Bouvet Island | AMER | | BW | Botswana | EMEA | | BY | Belarus | EMEA | | BZ | Belize | AMER | | CA | Canada | AMER | | CC | Cocos (Keeling) Islands | APAC | | CD | Congo, The Democratic Republic of the | EMEA | | CF | Central African Republic | EMEA | | CG | Congo | EMEA | | CH | Switzerland | EMEA | | CI | Cote D'Ivoire | EMEA | | CK | Cook Islands | APAC | | CL | Chile | AMER | | CM | Cameroon | EMEA | | CN | China | China | | CO | Colombia | AMER | | CR | Costa Rica | AMER | | CU | Cuba | AMER | | CV | Cape Verde | EMEA | | CX | Christmas Island | APAC | | CY | Cyprus | EMEA | | CZ | Czech Republic | EMEA | | DE | Germany | EMEA | | DJ | Djibouti | EMEA | | DK | Denmark | EMEA | | DM | Dominica | AMER | | DO | Dominican Republic | AMER | | DZ | Algeria | EMEA | | EC | Ecuador | AMER | | EE | Estonia | EMEA | | EG | Egypt | EMEA | | EH | Western Sahara | EMEA | | ER | Eritrea | EMEA | | ES | Spain | EMEA | | ET | Ethiopia | EMEA | | FI | Finland | EMEA | | FJ | Fiji | APAC | | FK | Falkland Islands (Malvinas) | AMER | | FM | Micronesia, Federated States of | APAC | | FO | Faroe Islands | EMEA | | FR | France | EMEA | | SX | Sint Maarten (Dutch part) | AMER | | GA | Gabon | EMEA | | GB | United Kingdom | EMEA | | GD | Grenada | AMER | | GE | Georgia | EMEA | | GF | French Guiana | AMER | | GH | Ghana | EMEA | | GI | Gibraltar | EMEA | | GL | Greenland | AMER | | GM | Gambia | EMEA | | GN | Guinea | EMEA | | GP | Guadeloupe | AMER | | GQ | Equatorial Guinea | EMEA | | GR | Greece | EMEA | | GS | South Georgia and the South Sandwich Islands | AMER | | GT | Guatemala | AMER | | GU | Guam | APAC | | GW | Guinea-Bissau | EMEA | | GY | Guyana | AMER | | HK | Hong Kong | APAC | | HM | Heard Island and McDonald Islands | AMER | | HN | Honduras | AMER | | HR | Croatia | EMEA | | HT | Haiti | AMER | | HU | Hungary | EMEA | | ID | Indonesia | APAC | | IE | Ireland | EMEA | | IL | Israel | EMEA | | IN | India | APAC | | IO | British Indian Ocean Territory | EMEA | | IQ | Iraq | EMEA | | IR | Iran, Islamic Republic of | EMEA | | IS | Iceland | EMEA | | IT | Italy | EMEA | | JM | Jamaica | AMER | | JO | Jordan | EMEA | | JP | Japan | APAC | | KE | Kenya | EMEA | | KG | Kyrgyzstan | EMEA | | KH | Cambodia | APAC | | KI | Kiribati | APAC | | KM | Comoros | EMEA | | KN | Saint Kitts and Nevis | AMER | | KP | Korea, Democratic People's Republic of | APAC | | KR | Korea, Republic of | APAC | | KW | Kuwait | EMEA | | KY | Cayman Islands | AMER | | KZ | Kazakhstan | EMEA | | LA | Lao People's Democratic Republic | APAC | | LB | Lebanon | EMEA | | LC | Saint Lucia | AMER | | LI | Liechtenstein | EMEA | | LK | Sri Lanka | APAC | | LR | Liberia | EMEA | | LS | Lesotho | EMEA | | LT | Lithuania | EMEA | | LU | Luxembourg | EMEA | | LV | Latvia | EMEA | | LY | Libyan Arab Jamahiriya | EMEA | | MA | Morocco | EMEA | | MC | Monaco | EMEA | | MD | Moldova, Republic of | EMEA | | MG | Madagascar | EMEA | | MH | Marshall Islands | APAC | | MK | Macedonia | EMEA | | ML | Mali | EMEA | | MM | Myanmar | APAC | | MN | Mongolia | APAC | | MO | Macau | China | | MP | Northern Mariana Islands | APAC | | MQ | Martinique | AMER | | MR | Mauritania | EMEA | | MS | Montserrat | AMER | | MT | Malta | EMEA | | MU | Mauritius | EMEA | | MV | Maldives | APAC | | MW | Malawi | EMEA | | MX | Mexico | AMER | | MY | Malaysia | APAC | | MZ | Mozambique | EMEA | | NA | Namibia | EMEA | | NC | New Caledonia | APAC | | NE | Niger | EMEA | | NF | Norfolk Island | APAC | | NG | Nigeria | EMEA | | NI | Nicaragua | AMER | | NL | Netherlands | EMEA | | NO | Norway | EMEA | | NP | Nepal | APAC | | NR | Nauru | APAC | | NU | Niue | APAC | | NZ | New Zealand | APAC | | OM | Oman | EMEA | | PA | Panama | AMER | | PE | Peru | AMER | | PF | French Polynesia | APAC | | PG | Papua New Guinea | APAC | | PH | Philippines | APAC | | PK | Pakistan | EMEA | | PL | Poland | EMEA | | PM | Saint Pierre and Miquelon | AMER | | PN | Pitcairn Islands | APAC | | PR | Puerto Rico | AMER | | PS | Palestinian Territory | EMEA | | PT | Portugal | EMEA | | PW | Palau | APAC | | PY | Paraguay | AMER | | QA | Qatar | EMEA | | RE | Reunion | EMEA | | RO | Romania | EMEA | | RU | Russian Federation | EMEA | | RW | Rwanda | EMEA | | SA | Saudi Arabia | EMEA | | SB | Solomon Islands | APAC | | SC | Seychelles | EMEA | | SD | Sudan | EMEA | | SE | Sweden | EMEA | | SG | Singapore | APAC | | SH | Saint Helena | EMEA | | SI | Slovenia | EMEA | | SJ | Svalbard and Jan Mayen | EMEA | | SK | Slovakia | EMEA | | SL | Sierra Leone | EMEA | | SM | San Marino | EMEA | | SN | Senegal | EMEA | | SO | Somalia | EMEA | | SR | Suriname | AMER | | ST | Sao Tome and Principe | EMEA | | SV | El Salvador | AMER | | SY | Syrian Arab Republic | EMEA | | SZ | Swaziland | EMEA | | TC | Turks and Caicos Islands | AMER | | TD | Chad | EMEA | | TF | French Southern Territories | AMER | | TG | Togo | EMEA | | TH | Thailand | APAC | | TJ | Tajikistan | APAC | | TK | Tokelau | APAC | | TM | Turkmenistan | EMEA | | TN | Tunisia | EMEA | | TO | Tonga | APAC | | TL | Timor-Leste | APAC | | TR | Turkey | EMEA | | TT | Trinidad and Tobago | AMER | | TV | Tuvalu | APAC | | TW | Taiwan | APAC | | TZ | Tanzania, United Republic of | EMEA | | UA | Ukraine | EMEA | | UG | Uganda | EMEA | | UM | United States Minor Outlying Islands | APAC | | US | United States | AMER | | UY | Uruguay | AMER | | UZ | Uzbekistan | EMEA | | VA | Holy See (Vatican City State) | EMEA | | VC | Saint Vincent and the Grenadines | AMER | | VE | Venezuela | AMER | | VG | Virgin Islands, British | AMER | | VI | Virgin Islands, U.S. | AMER | | VN | Vietnam | APAC | | VU | Vanuatu | APAC | | WF | Wallis and Futuna | APAC | | WS | Samoa | APAC | | YE | Yemen | EMEA | | YT | Mayotte | EMEA | | RS | Serbia | EMEA | | ZA | South Africa | EMEA | | ZM | Zambia | EMEA | | ME | Montenegro | EMEA | | ZW | Zimbabwe | EMEA | | A1 | Anonymous Proxy | AMER | | A2 | Satellite Provider | AMER | | O1 | Other | AMER | | AX | Aland Islands | EMEA | | GG | Guernsey | EMEA | | IM | Isle of Man | EMEA | | JE | Jersey | EMEA | | BL | Saint Barthelemy | AMER | | MF | Saint Martin | AMER | | BQ | Bonaire, Saint Eustatius and Saba | AMER | # Retailer Integration Changelog Source: https://developers.criteo.com/retailer-integration/changelog/changelog Release notes and announcements for the Criteo Retailer Integration documentation. ## New Onsite Display Formats Five new formats have been released, replacing the Legacy Onsite Display ones. We strongly recommend using the new formats for any new integration, as the legacy ones will be progressively phased out. You can find the documentation for the new formats [here.](/retailer-integration/docs/onsite-display-new-formats) ## New Video Player Implementation (App: iOS) We have published a new, enhanced guide that introduces a ready-to-integrate video ad wrapper that handles VAST parsing, video playback, and Open Measurement SDK compatibility for viewability and verification. This guide helps retailers to easily render, track, and measure in-app Onsite Video ad placements with minimal code. You can view it [here](/retailer-integration/docs/video-player-implementation-ios-app). ## New Server-Side Beacons Guide In most cases, client-side beacons (from the browser or app) are the preferred and recommended method for tracking ad events. However, in cases where this is not possible — such as on the server side, inside a mobile app, or within privacy-constrained environments — a server-side beacon can be used as a fallback. You can view our dedicated guide [here](/retailer-integration/docs/server-side-beacons). ## Beacon SDK Update As the new BeaconSDK v5 launched, we updated our dedicated page with new features, a quick start section, and best practices. You can find the updated guide [here](/retailer-integration/docs/beacon-sdk). ## New Landing Page We have revamped our developer portal landing page to better showcase the Retailer Integration Documentation alongside our APIs for Retail Media and Performance Marketing. That's the page you see when going to [developers.criteo.com](/). ## New Video Format A new format is now available: the **Branding Video Standout**. This format combines a branded video with a branded image and a CTA. Learn more about it [on the dedicated page](/retailer-integration/docs/branding-video-standout). ## Commerce Video is Now in General Availability Commerce Video is no longer in beta. You can find the dedicated documentation [here](/retailer-integration/docs/commerce-video-integration). ## Update of the Feed Parameter Page We have adjusted the formatting of the [feed parameter page](/retailer-integration/docs/product-feed-parameters) for better readability. The Product Importer API documentation is now located in the Retail Media API documentation to avoid duplicates. ## New Implemented Examples Embedded examples of implemented ads are now available for [Flagship](/retailer-integration/docs/flagship#implementation-example), [Butterfly](/retailer-integration/docs/butterfly#implementation-example), [Branded Header](/retailer-integration/docs/branded-header#implementation-example), [Interactive Header](/retailer-integration/docs/interactive-header#implementation-example), and [Digital Shelf Talker](/retailer-integration/docs/digital-shelf-talker#implementation-example) at the end of each guide in the Ad rendering section. ## New Product Importer API Guides The Product Importer API enables users to upload, update, and manage product datasets on the Criteo platform. We have added an entire new section dedicated to the Product Importer API in our "Feed & Product Data" section, where you can now find: * [The list of product dataset parameters](/retailer-integration/docs/dataset-parameters) (for both onsite and offsite) * [Product dataset examples](/retailer-integration/docs/product-dataset-examples) ## New Google Ad Manager Section The GAM or Google Ad Manager is a comprehensive ad management platform that enables publishers to manage, sell, and optimize both direct and programmatic ad inventory across web, mobile, and app environments. Retailers already using GAM can now also integrate with Retail Media by adding custom creatives to their line items. Learn how by visiting the new [GAM guide](/retailer-integration/docs/gam-overview). ## Legacy vs. Universal Beacons We have worked on [clarifying the distinction between "legacy" and "universal/standard" beacons](/retailer-integration/docs/legacy-universal-beacons) in the Ad Tracking section. We strongly encourage all new integrations to use universal beacons. A [migration guide](/retailer-integration/docs/legacy-universal-beacons#migrating-from-legacy-to-universal-beacons) is also available. ## Integration Best Practices Integration best practices guides have been incorporated into each of the main sections of the documentation: [Product feed](/retailer-integration/docs/feed-best-practices), [Requesting Ads](/retailer-integration/docs/requesting-ads-best-practices), [Ad rendering](/retailer-integration/docs/ad-rendering-best-practices), and [Ad Tracking](/retailer-integration/docs/ad-tracking-best-practices). ## OneTag Offsite for Hybrid Apps We have added a complementary page to the main [OneTag for Retail Media Offsite page](/retailer-integration/docs/onetag-for-offsite) for hybrid apps, covering how to retrieve the advertising ID from Android and iOS and pass it to OneTag. A [Hybrid apps](/retailer-integration/docs/onetag-offsite-for-hybrid-apps) page has also been added. ## New Implementation Examples for Flagship & Butterfly New implementation examples are now available for [Flagship](/retailer-integration/docs/flagship#implementation-example) and [Butterfly](/retailer-integration/docs/butterfly#implementation-example), with code samples in HTML, CSS, and JavaScript. # Ad Rendering Best Practices Source: https://developers.criteo.com/retailer-integration/docs/ad-rendering-best-practices This page lists a set of best practices for Ad Rendering at Criteo. ## Validating SKUs in Criteo Response using Internal API Calls Since the product feed passed to Criteo may not always contain the most up-to-date information, the retailer should implement an internal API validation process to ensure accuracy before rendering products. The validation should focus on the following key aspects: * **Availability check**: Before rendering a product, verify its availability through the retailer’s internal API. If the product is out of stock, it should be excluded from the display to prevent a poor user experience. * **Real-time price validation**: Instead of relying on the price provided by Criteo (which may be outdated), fetch the most current price from the retailer’s internal system. This ensures that customers see accurate pricing, reducing the risk of checkout discrepancies. * **Rendering Attributes Validation**: Any essential rendering attributes (such as product images, descriptions, labels, or promotional tags) should be retrieved from the retailer’s internal API. This ensures consistency in branding and messaging, as Criteo’s feed might not always have the latest updates. *** ## Duplication between Organic & Sponsored Products In cases where Criteo returns ads for products already featured organically: * **Preferred Practice**: Render both the sponsored ad and the organic listing. * **Alternative**: Remove the organic SKU and display only the sponsored ad. **Benefit** This approach balances ad visibility and user experience while ensuring ad spend optimization. *** ## Multiple placements per page When multiple sponsored placements exist on a single page, **allow duplication of Sponsored Products**. **Benefit** If no other eligible campaigns are available, the same advertiser can fill multiple placements. This increases their share of voice and ensures ad relevance. ***
## What's next * [Introduction to Beacons](/retailer-integration/docs/introduction-to-beacons) * [Beacon Types](/retailer-integration/docs/beacon-types) * [Legacy & Universal beacons](/retailer-integration/docs/legacy-universal-beacons) * [BeaconSDK](/retailer-integration/docs/beacon-sdk) * [Server-Side Beacons](/retailer-integration/docs/server-side-beacons) * [Ad Tracking Best Practices](/retailer-integration/docs/ad-tracking-best-practices) # Ad Tracking Best Practices Source: https://developers.criteo.com/retailer-integration/docs/ad-tracking-best-practices ## Double Tracking Metrics * Ensuring data accuracy & performance insights: Since the retailer is responsible for firing all `load`, `view`, and `click` events to Criteo, they should also track these metrics internally. **Benefit** This allows for **cross-verification**, better **performance analysis**, and **independent optimization**. ***
# API calls Source: https://developers.criteo.com/retailer-integration/docs/api-calls-checklist # Introduction This page presents a breakdown of all the parameters needed for the API calls by common parameters (that can be used on all page calls) as well as by page type. *** ## Common parameters

Title

Name

To Check

Mandatory

Account ID

criteo-partner-id

Your Criteo Account ID, will be provided by your technical contact

Ex: criteo-partner-id=102302

Yes

Retailer Visitor ID

retailer-visitor-id

Unauthenticated User ID, consistent across sessions

Ex: retailer-visitor-id=c9623-aaaa

Yes

Customer ID

customer-id

After logging in, whether there is a unique user ID

Can also log in with a different device or log-in with the same account on another browser/incognito.

Ex: customer-id=c9621-bbbb

Yes

Email

email

Hash value of the user email address SHA256

Ex: 3786ae0aa4a0655c

Only if discussed with your Criteo team

Test call

nolog

To be used when the log of this call shouldn't be counted as a real page view. (used for our cached API response scenario)

Ex: nolog=1

Can be used on preprod accounts.

Only if discussed with your Criteo team

Item white list

item-whitelist

A parameter to be used to return the specific products that are set in the call, only for sponsored products. To be used with the cached API response scenario or to use the recommendation engine.

Only if discussed with your Criteo team

Region ID

regionId

The region IDs that are sent are accurate to the regions IDs that are shared in the daily feed.

If multiple region IDs are to be sent, then they need to be separated by the pipe symbol.

Ex: regionId=123-abc|456-def|789-ghi

Only if discussed with your Criteo team

*** ## Homepage You will find an example of test retailer [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewHomeApiDesktop\&event-type=viewHome).

Title

Name

To Check

Mandatory

viewHome

page-id

The page ID should follow the format of:

EMEA: viewHomeApi\[Environment]

AMER: viewHome\_API\_\[Environment]

Ex: viewHomeApiDesktop

Yes

viewHome

event-type

We are using the viewHome for the homepage

Yes

*** ## Category page You will find an example of test retailer [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewCategoryApiDesktop\&event-type=viewCategory\&category=Shoes).

Title

Name

To Check

Mandatory

viewCategory

page-id

The page ID should follow the format of:

EMEA: viewCategoryApi\[Enviornment]

AMER: viewCategory\_API\_\[Environment]

Ex: viewCategoryApiDesktop

Yes

viewCategory

event-type

We are using the viewCategory for the browse

Yes

viewCategory

item

IDs of the organic products visible. These IDs need to match the product IDs provided in the feed. They will be used for deduplication in the ad response

Ex: item=123|456|789

Yes

viewCategory

parent-item

The parent item ID of the organics products on the page, if the product has a parent ID.

Ex: 12345|NULL|NULL

This should only be used if parent/child SKUs have been set up.

Only if discussed with your Criteo team

viewCategory

page-number

The current page-number.

Ex: page-number=2

Recommended

viewCategory

category

The category path of the current category, either numerical or alphanumerical. The path provided in the tag needs to match "product\_type\_key" from the feed

Ex: category=1001

Yes

viewCategory

filters

Used to restrict the response to products which have a certain attribute with the exact value in the Feed

Ex: filters=(brand,eq,nike)

Only if discussed with your Criteo team

viewCategory

list-size

The total number of organic products that show on the page.

Ex: list-size=24

Recommended

*** ## Search page [Here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewSearchResultApiDesktop\&event-type=viewSearchResult\&keywords=drink) is an example of a test retailer.

Title

Name

To Check

Mandatory

viewSearchResult

page-id

The page ID should follow the format of:

EMEA: viewSearchResultApi\[Environment]

AMER: viewSearchResult\_API\_\[Environment]

Ex: viewSearchResultApiDesktop

Yes

viewSearchResult

event-type

We are using the viewSearchResult for the search

Yes

viewSearchResult

item

IDs of the organic products visible. These IDs need to match the product IDs provided in the feed. They will be used for deduplication in the ad response

Ex: item=123|456|789

Yes

viewSearchResult

parent-item

The parent item ID of the organics products on the page, if the product has a parent ID.

Ex: 12345|NULL|NULL

This should only be used if parent/child SKUs have been set up.

Only if discussed with your Criteo team

viewSearchResult

page-number

The current page-number.

Ex: page-number=2

Recommended

viewSearchResult

keywords

The keyword which was entered by the user

Ex: keywords=shoes

Yes

viewSearchResult

filters

Used to restrict the response to products which have a certain attribute with the exact value in the Feed

Ex: filters=(brand,eq,nike)

Only if discussed with your Criteo team

viewSearchResult

list-size

The total number of organic products that show on the page.

Ex: list-size=24

Recommended

*** ## Product page [Here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewItemApiDesktop\&event-type=viewItem\&item=19539\&price=1\&availability=1) is an example of a test retailer.

Title

Name

To Check

Mandatory

viewItem

page-id

The page ID should follow the format of:

EMEA: viewItemApi\[Environment]

AMER: viewItem\_API\_\[Environment]

Ex: viewItemApiDesktop

Yes

viewItem

event-type

We are using the viewItem for the search

Yes

viewItem

item

Item of the currently visited product. This ID needs to match with the ID provided in the feed

Ex: item=123

Yes

viewItem

parent-item

Parent Item of the currently visited product. This ID needs to match with the ID provided in the feed. We can only use this to update all the variants (child products)

Ex: parent-item=123

Only if discussed with your Criteo team

viewItem

price

The current price of the product. This price will be used to update the product price on criteo's side in real time

Ex: price=3.99

Yes

viewItem

list-price

Current non-discounted price / MSRP of the product.

Ex: list-price=5.99

Recommended

viewItem

availability

The current availability of the product, 1 for "in-stock", 0 for "out of stock". This value will be used to update the in-stock value of the product on Criteo's side in real time

Ex: availability=1

Yes

*** ## Add-to-cart You can find an example of a test retailer [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewSearchResultApiDesktop\&event-type=addToCart\&item=123\&price=1\&quantity=1\&page-uid=20d86a61-3f5f-4af1-9ecb-a594727f0743).

Title

Name

To Check

Mandatory

addToCart

page-id

For the page-id , you must use the ID of the page where the add-to-cart event took place. For example, if the user added a SKU to the cart directly from the product tile on a Search results page, the pageID for this call would be:

EMEA: viewSearchResultApi\[Environment]

AMER: viewSearchResult\_API\_\[Environment]

Ex: viewSearchResultApiDesktop

Yes

addToCart

event-type

We are using the addToCart for the add to cart page

Yes

addToCart

item

The ID of the product that was added to the basket, the SKU that has to match the ID provided in the feed.

Ex: item=123

Yes

addToCart

parent-item

Parent Item of the products currently in the users' basket. This ID needs to match with the ID provided in the feed. We can only use this to update all the variants (child products)

Ex: parent-item=123

Only if discussed with your Criteo team

addToCart

price

Array of products in the basket single unit price

Ex: price=3.99

Yes

addToCart

quantity

Array of quantity of each product in the basket

Ex: quantity=3

Yes

addToCart

page-uid

Unique ID present at the bottom of the API call of the current page.

Ex: page-uid=545d9a70-f096-4568-b4b9-8f2f32a452d4

Yes

*** ## Basket page You can find an example of a test retailer [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=viewBasketApiDesktop\&event-type=viewBasket\&item=19539\&price=1\&quantity=1).

Title

Name

To Check

Mandatory

viewBasket

page-id

The page ID should follow the format of:

EMEA: viewBasketApi\[Environment]

AMER: viewBasket\_API\_\[Enviornment]

Ex: viewBasketApiDesktop

Yes

viewBasket

event-type

We are using the viewBasket for the basket

Yes

viewBasket

item

Array of products in the basket, including SKU that has to match the ID provided in the feed.

Ex: item=123

Yes

viewBasket

parent-item

Parent Item of the products currently in the users' basket. This ID needs to match with the ID provided in the feed. We can only use this to update all the variants (child products)

Ex: parent-item=123

Only if discussed with your Criteo team

viewBasket

price

Array of products in the basket single unit price

Ex: price=3.99

Yes

viewBasket

quantity

Array of products in the basket overall quantity of the item

Ex: quantity=3

Yes

*** ## Order confirmation page You can find an example of a test retailer [here](https://d.eu.criteo.com/delivery/retailmedia?criteo-partner-id=108341\&retailer-visitor-id=456\&customer-id=789\&page-id=trackTransactionApiDesktop\&event-type=trackTransaction\&item=19539\&price=1\&quantity=1\&transaction-id=abc123).

Title

Name

To Check

Mandatory

trackTransaction

page-id

The page ID should follow the format of:

EMEA: trackTransactionApi\[Environment]

AMER: trackTransaction\_API\_\[Environment]

Ex: trackTransactionApiDesktop

Yes

trackTransaction

event-type

We are using the trackTransaction for the order confirmation

Yes

trackTransaction

transaction-id

Unique order / transaction ID

Ex: 51852389

Yes

trackTransaction

item

Array of products bought by the user, including ID, single unit price and overall quantity of the item. The ID has to match the ID provided in the feed.

Ex: item=123|456|789

Yes

trackTransaction

parent-item

Parent Item of the currently visited product. This ID needs to match with the ID provided in the feed. We can only use this to update all the variants (child products)

Ex: parent-item=123|456|NULL

Only if discussed with your Criteo team

trackTransaction

price

Array of products in the basket single unit price

Ex: price=3.99|10.00|0.99

Yes

trackTransaction

quantity

Array of products in the basket overall quantity of the item

Ex: quantity=3|1|5

Yes

trackTransaction

currency

The local currency of the retailer should be added here

Ex: GBP

This should only be used if discussed with your Criteo team

# API response structure Source: https://developers.criteo.com/retailer-integration/docs/api-response-structure ## Response Elements All formats share the same API response structure, which is described below: ### `Status` Type: `string` Values: `OK`(for successful responses) or an error type. In case of an error, an array will be added to the response with the list of applicable error message(s), such as: `Missing required parameter x` *** ### `Placements` Type: `array of placement objects` Each placement name is used as a key, like for example: `viewCategory_API_desktop-Video`. The value of each key is an array of ads. Each ad has the below properties: * **`format`**: indicates which format is returned. * **`products`**: is a list of SKUs that are included in the ad format, along with additional metadata about each SKU (image, product URL, parent SKU ID, etc.)
* **`products_order`**: some real time product substitutions are allowed based on availability of SKUs:
* **`products`**: an array of product IDs. The order of products returned by Criteo should match the order of SKUs displayed on the site, unless a SKU is unavailable or out of stock.
* **`isMandatory`**: If true, the overall ad unit should **not**be displayed if this product is not available. If false, the ad can be shown, but the button/product tile should be removed from the unit. *** ### `Rendering` * **`rendering`**: format-specific properties to use when rendering the ad, including image assets, colors, and custom labels. All video parameters in the rendering section **must not be used to render the video format**. Please refer to [the table below](/retailer-integration/docs/api-response-structure#rendering-fields) for more details. Criteo reserves the right to delete these video values at any time in the future. **Video formats** Please refer to the[ format specifications](/retailer-integration/docs/format-overview) (in the Ad rendering section) for more information on the rendering capability. You will also find in this section [the Commerce Video Spotlight specification.](/retailer-integration/docs/commerce-video-spotlight). Please refer to the `TagVideoVAST `field described below. *** ### `TAGVideoVAST` * \*\*`TagVideoVAST`\*\*or **`XmlVideoVAST`:** * **`TagVideoVAST`** *(by default)* **:** a URL to load a VAST XML via a video player that supports VAST; * **`XmlVideoVAST`** *(if retailer opt-out of doing an extra API call to retrieve the VAST definition)*: The VAST XML to provide a video player that supports the VAST standard. * **`OnViewBeacon`,`OnLoadBeacon`, `OnClickBeacon`, etc.**: the beacons to trigger/fire back to Criteo when specific actions take place. See the section for further information. *** ### VAST XML Example ```xml expandable theme={null} <VAST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="4.2"> <Ad id="733362817287327744"> <InLine> <AdSystem>Criteo</AdSystem> <AdTitle>OnsiteVideo</AdTitle> <Impression> </Impression> <Error> </Error> <Creatives> <Creative id="730786603482791936"> <Linear> <Duration>00:00:15.070</Duration> <TrackingEvents> <Tracking event="start"> </Tracking> <Tracking event="firstQuartile"> </Tracking> <Tracking event="midpoint"> </Tracking> <Tracking event="thirdQuartile"> </Tracking> <Tracking event="complete"> </Tracking> </TrackingEvents> <MediaFiles> <MediaFile id="c2bf93dcf6e4d6f9dd150c4e4f8c222_discover_miracle_moisture_boost_with_rose_water" delivery="progressive" width="640" height="360" type="video/mp4" scalable="true" maintainAspectRatio="true"> </MediaFile> <ClosedCaptionFiles> <ClosedCaptionFile type="text/vtt" language="en"> </ClosedCaptionFile> </ClosedCaptionFiles> </MediaFiles> </Linear> </Creative> </Creatives> <AdVerifications> <Verification vendor="criteo.com-omid"> <JavaScriptResource apiFramework="omid" browserOptional="true"> </JavaScriptResource> <VerificationParameters> </VerificationParameters> <TrackingEvents> <Tracking event="verificationNotExecuted"> </Tracking> </TrackingEvents> </Verification> </AdVerifications> </InLine> </Ad> </VAST> ``` *** ### Closed Caption Files in VAST XML When Closed Captioning is enabled, the VAST XML response will include a `ClosedCaptionFiles` element nested inside each `MediaFile` element within the `MediaFiles` section. Each `ClosedCaptionFiles` container holds one or more `ClosedCaptionFile` entries, representing closed captions in different languages and formats (currently, `text/vtt` is supported). These are not video assets themselves and must not be interpreted as part of the video `src`. **Example** ```xml theme={null} <MediaFiles> <MediaFile id="c2bf93dcf6e4d6f9dd150c4e4f8c222_discover_miracle_moisture_boost_with_rose_water" delivery="progressive" width="640" height="360" type="video/mp4" scalable="true" maintainAspectRatio="true"> <ClosedCaptionFiles> <ClosedCaptionFile type="text/vtt" language="en"> </ClosedCaptionFile> </ClosedCaptionFiles> </MediaFile> </MediaFiles> ``` *** ### Product Beacons ```json theme={null} { "OnViewBeacon": "//b.us5.us.criteo.com/rm?rm_e=s8ly6TMLiDfPTKFfXm_9jzkwZuAATAS9FwGwUZ5NvnDY6LnNvBC-8AFQtntlkS50apl_jVhQvRg0-u3hWpur4RF0HikgBSOlggUUkzoK6gg9E7yC-eas9rFlwoxTuvObWpo4Yv0uedvzqBKRk-BQgcCsPHzIURbtCi_Uf5InvFyWoUkbah_XRajDvrj7oLrV-RjcYeixGYTcBoi89hqLhak5FB7_2zPWNAZMVPUCw23MNX4t0OC70fDyIL68g7RUGtBtrVvbMkMafb30uMp_L1WlmSeGHdM-EP6aUYjKRS0VBwwZkaVStkauo1XrT5-dwiyB8zm2AlAVk0AwGMNdmFlCBac-MQWycvgjgOWm-p7cGLVi5Fq3gIrUGVI5Jqq&ev=4", "OnClickBeacon": "//b.us5.us.criteo.com/rm?rm_e=MrPLtLUJfBxGX1zJk2imKaKpINZcbhVh4D9KELEKwSgdZe8-YiW50o4eQvi4SQGyvk-qeuvO1GZCJkmhfpBHJYoxcNaFwMFqtBLjax-lgCevbaCxmjOQjxqFgBXAG0CAvZx4klriBNrRrVXKIk2NI8-jpplFURhS_hDuGcMgUICraKi4wi7x958r0VNKA7iE6f-N2yyQWLlILI4yNFgqZPp_0sP-b2ks72ZdxeiJQbDko0FVMJYPClVooJPRXBWJjOvph2OOrZyh0tY4LwGp6D2p8W_rD_5HN94RR5Cewl8ojB6WFjoq_PAaJGPptLjEUV9kx-EUMFhve6vGfAlHeJ7P-ILh44mp8nOKyIsoLSIwR9HYhghChXJ4M-3EVAs&ev=4", "OnBasketChangeBeacon": "//b.us5.us.criteo.com/rm?rm_e=mlh4P3Tin3uct-JUxYugi37w__lZ0FOoCZ06TrhlXtQKc2faGpFFiK6g4zKwyFmd2NwXBMhVZGVtFK5T9e9KvdteZRrqZxcVW08Y9i8ecjt9m1DbEQunU8uMblAIF8yZ3bqjt71Niurwrzm-iiF-B2av8zEd0lj-Lt5AGeX1dgyP3jJdO-5Ddmw6-H5L9JTAksWT8QWbKoVwOQtwYU8r2M4yzpCGGvcvvwu6QdoC_GCfazwEsIRt446HA0AVqOwss26id8ZDjTSrwbOjSVMu5JS92mGU_3wR3Fyb2w5M8AJcLUlIXTD8oaLc9CFyAQQrbkurtKsHFPfNWRyuZOxnZr0FgSgRvHIi55eP-yr5usr4of31iaYPQvKrdTbGiEX&ev=4", "OnWishlistBeacon": "//b.us5.us.criteo.com/rm?rm_e=F--9mZ6kqtpHdJjjowDoZJixm4BjF12sLm6qFd0fCcnunZ1oT-owxZowTezzt4Je3Q7MQiLTAyZNVlB7v-feDJHnczt4q-f43SEE67RxRFL-PWGl4jCW7F7CKBZ5WNMxBmU0eC4d88xec7diCgp-Ifhgs-Qp135jF8-BrQ7kVj9RlRan2QTtLKxCXTytdydHRhwaAsdCyOA-VStX4ZNRI297WGRTXfRepsCLAr6E5DTDdoccag4lx5v_LSUNO82i0D11y5O3xqs1QSKCIANY802UBDPdV89lEqbofgL1Gp7CYd0OSxM_545fzsFVA2RWG4ufFDIF71aXrbKhZuRencstNQ8xMWH0KMKACEk7DQWE9WObogGMEaoSf8t664O&ev=4" } ``` *** ### Placement / Format Beacon Placement and format beacons will typically be right under the `TagVideoVAST`: ```json theme={null} { "OnLoadBeacon": "//b.us5.us.criteo.com/rm?rm_e=OvODs4ECUFFfQHTXDM5FiIOKZruyseTgpUr_Xt4DVTUPBoNNtG8VsH3Jo21jPK_hMV6-9I89Az0ZP2H8yslVjFaeW_HqR0Tee4gUCZ-aJMGxpkz2bjGguRcAv-jd9ocPs2HOgk24DtDHJ_D4MJJ1b0I2bILdRCp2AyfGmrj1acfyvMqngJeS4eWiDOYOkNTaYmd0uIo3bAcGObFt4DALVQE-AJXUhBjo3lyY6Kcn7n6xS1bAkK_kqT6sBtSk2KRmX_dPNKucLowpkgsRwpr-XgfcmV1VVvkCH8uXbmYbEPTQVE103_4r7zHgvpZaiU8qbROlMwCHVqvx-aY1tNuDKa0uwoqyCm6JHC2yTo06XfnqZhJphbc50hjGbPZHa24ZAdMq7bBr3G9YpxycnMQ_B-7zyNFQeSNH_M_pYAgIvo6eXjgAYA376LoJostZTGhmEEKUvgrY-7hbU_ezG5D2_BCA7Yh2xkDQHmERLd4FgWyUxcSlkksvUmIlpd1S5-b&ev=4", "OnViewBeacon": "//b.us5.us.criteo.com/rm?rm_e=qjke4FNkDL1z46EuOhojBxciTQ6Xp09cJDentgGUVT0kah-rPIHg9DUOFugsUOiCrUvFnJtuj5yYXehZp5-Ryvzf5WLl9gmin_wz4ekX7Fu_ePZKpnpNgyBBR-1Jjuqzdvkq6aIktA4r5HGzyyPF9TQDrrhYgmldAW8QYjfTk6WiI7jlZmUZnIvVah3HJi4I6QzTCTTwRXBJrFNYgJKgt2M419DkJA1UyGsnCmld5E-q4Ms3znTBEIF4fgVj6ExNAM1O_HgmgcKrDYCpo9ZVkd037dHoDiYiZVfmymlSIcubD73ZB_sBl20rsUxIujMsbLt3jliMFEthtJ8oZ3mL5Ax2HwOA2Qm58M0InNlmQf88ulFpw_IWYI6iklgleE3GrvqHb-eNj7Fg77qvKRYrHmE1gLF66WVjyactaWqP0RsIpqcAGlrjHTI7I_lQxE6&ev=4", "OnClickBeacon": "//b.us5.us.criteo.com/rm?rm_e=xt13W_TJWbSrXdNa2RG3qhZiHotcnySWD0gLaHC_PbIZyrh_V_zxUVBnIP66uaFp58Y8R0Q6ALpYjkAac-2iecIRrcEVriwqPrGkjbDFHjBsGPD4q0JTEH1mZrp2oMndYCXQEOQjAzDIBR4e52DU-koOXViZcXi9_S-bLmQA_PFop4u0ilGtfJ2AJeCOtwyNnluCwE3INkF1AEN4HqMnOgtiHcm00o9DojZemXKd_B-4bRl3eRmFR_s0jVRjwbAYHegtP7WKujHi5iRiBYogpOpVhMCkg3DciZZpza9IcBxsQVgEonlADyJYzUtvEzMZpzBE1_x6NyjUPECJUSHrxvzSI7UKgPwSukP5sCvSxY6AFqTIXXHCXKjJKFH2uQwsvi0VtHobEv_c13tm3QaIg&ev=4", "OnFileClickBeacon": "//b.us5.us.criteo.com/rm?rm_e=3wgFCc5lMY0fItQj4jiSm37070kK2zoFJlbFRWEZd3CB9_0DjnEp1Iq7Q1xG5mTffdi1SAarVTiAILArYOPRbbyiJ3eB_t4Y29BWqAhUbIrP6nAFT0W2DxVbOdlRLFYoISPpbV-EhVsA-oh9kXPKSk53p7w1MZAm9LS45SVZ_tZQh7-SPz2MLF4hoJGteus6hkWyfsVbgTym2gpu7JobVmaFLGrc8CyymYkfH5Xf1JKiGeNa2ZPsQtZxpnt1Dzl4Bm_BAfKYjQZnOCyWt6peHIN-azNeYwe34M9H85x1SWn5y_PKpIQZYiB_1YvdBac2VSrkBqO6SO1OgB2NiveM923Ew4Npm2rgUYUZ5bjvgL3KufQJK4FucRbvjAxEQJS&ev=4", "OnBundleBasketChangeBeacon": "//b.us5.us.criteo.com/rm?rm_e=FSx1IlEiuPZ8UZ6-SLMpMc_icIPoxT57Ozjvievjn-9la70L5yC5VtSagxSUpBlat4BEQLu8hrqXDcNY8kUTLylv7fdvT2B7x-NkYCfYEGZZj1lJdRLhQxckVsgIk-PyjILwpnwEODcV1wvMmXnFH5ttrA5iSp847tgW-2fvZxS1w7YX30tbLYvAmZTvJxPnOXKPcmwnJz3BJ6d8CMLgdVoJN67AtgRKTpkb1s0eYk-ANM_gv7cgtEME2142W8vlv6-NayvCwGvw_CtH-OWVZoEJ52TJMMbj3Aa6jPHBRgw9P-LVsFWY3f_kxauVNl7mHTAyVvajrcPeYl7_8ygq6hFtqm9IBryXB8iMctEXDronoGT-VHfrAqet9nVvPYMyATWjm-X21M88YLAGoaDuQ&ev=4" } ``` *** ## Rendering Fields Below is an example of rendering fields in the API response: ```json theme={null} "rendering": { "background_video": "{\n \"url\": \"https://static.criteo.net/design/dt/commerce_max/retailer_06/d97eb13b8e3d496eaddef7b4c998d286_video.mp4\",\n \"width\": 720,\n \"height\": 1280,\n \"duration\": \"00:00:06\"\n}", "video_caption_file": "https://static.criteo.net/video/onsite_cc/laptop_vertical.vtt", "video_alt_text": "Laptop", "border_color": "#712329", "video_optional_redirect_url": "https://www.retailer.com/shop/search-results.html?q=laptop", "video_optional_redirect_url_app": "", "video_media_files": "[\"background_video\"]" }, ``` Below is the description of the API response fields for format rendering within the page. These fields are subject to change based on the video format.

Field

Description

video\_background (including all information within this field)

Do not use this field. It is reserved for Criteo purposes only. All video-related information, assets and tracking must be used from the VAST XML only.

video\_optional\_redirect\_url video\_optional\_redirect\_url\_app

Do not use these fields. It is reserved for Criteo purposes only. The optional redirection link to a landing page if the user clicks on the video player is available in the VAST definition (cf. \ node). As only one redirection link is supported in VAST, Criteo will automatically return the right URL based on the page requesting ads.

alternative\_text / background\_video\_alt\_text (or equivalent naming)

Text to display in an alt\_text div attribute for WCAG compliancy purposes.

optional\_legal\_text

Free text field to display a legal message upon user hover. This field is optional for the advertiser to complete.

video\_media\_files video\_firework\_id video\_caption\_file video\_captions

Do not use these fields. It is reserved for Criteo purposes only.

***
## What's next * [Video player specifications](/retailer-integration/docs/video-player-specifications) * [Tracking ad-related activity](/retailer-integration/docs/tracking-ad-related-activity) * [Criteo-Owned Video Player Integration](/retailer-integration/docs/criteo-owned-video-player-integration) # BeaconSDK Source: https://developers.criteo.com/retailer-integration/docs/beacon-sdk This guide details the process for automatic beacon tracking on web using our Criteo's BeaconSDK. # Introduction BeaconSDK is Criteo’s lightweight external JavaScript library that automates beacon tracking on web. It handles the entire beacon lifecycle (load, view, and click) so you don’t have to build or maintain a custom tracking logic. The result is faster integrations, cleaner data, and consistent measurement across all placements and products. Process overview integrating with the BeaconSDK For more information on the different levels of beacons, please check [the ad tracking introduction page.](/retailer-integration/docs/introduction-to-beacons) *** # Quick Start Criteo’s Delivery API returns unique beacon URLs for each placement and product (SKU). To start tracking with BeaconSDK using the new static JavaScript bundle, follow these steps: ## Add Beacon Attributes to your HTML tags Each beacon URL returned by the [Delivery API response](/retailer-integration/docs/api-responses) must be attached to the corresponding HTML element using a `data-` attribute in the format `data-criteo-[beacon-level]-[beacon-type]` ```html expandable theme={null} ``` `[beacon-level]` is one of `product` or `placement`, and `[beacon-type]` is one of `onloadbeacon`, `onviewbeacon`, `onclickbeacon`, `onbasketchangebeacon`, and `onwishlistbeacon`. ### Page Intelligence placements Placements returned from the [Page Intelligence `/optimize` endpoint](/retailer-integration/docs/page-intelligence) use a `StructuredBeacon` object for `onLoadBeacon` instead of a plain URL string. To pass the payload to BeaconSDK, set `data-criteo-placement-onloadbeacon` to the `url` value and add one `data-criteo-placement-onloadbeacon-payload-[key]` attribute per entry in the `payload` object: ```html expandable theme={null}
...
``` When `data-criteo-placement-onloadbeacon-payload-*` attributes are present, BeaconSDK fires the beacon using `navigator.sendBeacon(url, data)` where `data` is the `application/x-www-form-urlencoded` string of all payload parameters. The `data-criteo-placement-onloadbeacon-payload-*` attributes apply only to placements from the `/optimize` endpoint. For placements from the Delivery API, use the standard `data-criteo-placement-onloadbeacon` attribute with the plain URL. *** ## Load BeaconSDK At the end of your HTML document, before the closing the `` tag, include the BeaconSDK bundle using the script tag: ```html theme={null} ``` ### Implementation Examples Below are example implementations of BeaconSDK in different scenarios. #### Example 1: Basic integration Here's a simple example that uses only sponsored products and BeaconSDK to track `OnLoad`, `OnView`, and `OnClick` events. We also added a simple JavaScript function to handle add-to-cart (`OnBasketChange`) and add-to-wishlist (`OnWishlist`) beacons.