Promoted Products
Getting Started
- A promoted product specifies the product that will be advertised on a line item.
- Identify eligible products to promote by accessing your account catalog.
- Each product can optionally be configured with a specific bid amount, allowing you to control how much you are willing to pay per click.
- Each line item is limited to a maximum of 500 promoted products.
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 of 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)Accepted values: bidOverride ≥ 0.0Default: 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
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
, respective - see API Response
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

https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products?offset={offset}&limit={limit}&fields={attributeList}
Sample Request
curl -X GET "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products?offset=0&limit=10&fields=bidOverride,status" \
-H "Authorization: Bearer <MY_ACCESS_TOKEN>"
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 <MY_ACCESS_TOKEN>'
}
response = requests.request("GET", url, headers=headers, data=payload)
print(response.text)
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 <MY_ACCESS_TOKEN>")
.build();
Response response = client.newCall(request).execute();
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->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 <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
🔵 HTTP code 200
:
{
"meta": {
"offset": 0,
"limit": 10,
"count": 34,
"responseCount": 34
},
"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.

https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/append
Sample Request
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 <MY_ACCESS_TOKEN>' \
-d '{
"data": [
{
"id": "492731",
"type": "RetailMediaPromotedProduct",
"attributes": {
"id": "492731",
"status": "paused",
"bidOverride": "0.0"
}
}
]
}'
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 <MY_ACCESS_TOKEN>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
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 <MY_ACCESS_TOKEN>")
.build();
Response response = client.newCall(request).execute();
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->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 <MY_ACCESS_TOKEN>'
));
$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.

https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/delete
Sample Request
curl -X POST "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products/delete" \
-H "Authorization: Bearer <MY_ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"data": [
{
"id": "sku1",
"type": "RetailMediaPromotedProduct"
}
]
}'
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 <MY_ACCESS_TOKEN>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
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 <MY_ACCESS_TOKEN>")
.build();
Response response = client.newCall(request).execute();
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->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 <MY_ACCESS_TOKEN>'
));
$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:

https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/pause
Sample Request
curl -X POST 'https://api.criteo.com/{version}/retail-media/line-items/311990577399115776/products/pause' \
-H 'Content-Type: application/json' \
-H'Authorization: Bearer <MY_ACCESS_TOKEN>' \
-d '{
"data": [
{
"id": "4f5c49fce3c94542b5023e7cc1e1f5ca",
"type": "RetailMediaPromotedProduct"
}
]
}'
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 <MY_ACCESS_TOKEN>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->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 <MY_ACCESS_TOKEN>'
));
$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();
}
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 <MY_ACCESS_TOKEN>")
.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:

https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/unpause
Sample Request
curl -L -X POST 'https://api.criteo.com/{version}/retail-media/line-items/311990577399115776/products/unpause' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
-d '{
"data": [
{
"id": "4f5c49fce3c94542b5023e7cc1e1f5ca",
"type": "RetailMediaPromotedProduct"
}
]
}'
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 <MY_ACCESS_TOKEN>'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
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 <MY_ACCESS_TOKEN>")
.build();
Response response = client.newCall(request).execute();
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->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 <MY_ACCESS_TOKEN>'
));
$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 un-paused 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/Un-pausing 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 |
Updated 18 days ago