GuidesAPI ReferenceChangelog
GuidesAPI ReferenceChangelogLog In
Guides

Promoted Products

📝

Getting Started

1 - A promoted product specifies the product to promote on a line item
2 - Identify eligible products to promote through your account catalog
3 - Each product may be optionally configured with a specific amount to bid with
4 - Line items are each limited to 500 promoted products

 

Enpoints

VerbEndpointDescription
GET/line-items/{lineItemId}/productsGet All Products on a Specific Line Item
POST/line-items/{lineItemId}/products/appendAdd Products to a Specific Line Item, or update a bid override
POST/line-items/{lineItemId}/products/deleteRemove Products from a Specific Line Item
POST/line-items/{lineItemId}/products/pausePause Products on a Specific Line Item
POST/line-items/{lineItemId}/products/unpauseReactivate Paused Products on a Specific Line Item

 

Request Parameters

lineItemId Required

    Data Type: number

    Accepted Value: int64

    Read or Write Write

    Nullable? No

    Description: The line item id that the API call should reference


accountId Required

    Data Type: string

    Accepted Value: int64

    Read or Write Write

    Nullable? No

    Description: Account ID that line items belong to


Response Attributes

id Required for POST calls

    Data Type: string

    Accepted Value: 500 char limit

    Write? Yes

    Nullable? No

    Description: Retailer product ID unique to the retailer; obtained from the account catalog


bidOverride

    Data Type: number

    Accepted Value: at least minBid

    Write? No, only available with GET calls. For pause/unpause POST calls promoted does not make use of bidOverride attribute

    Nullable? Yes

    Description: Amount used to bid for the specific product; overrides targetBid specified on the line item and behaves similarly; must meet minBid, which is retrieved through the catalogs; input excludes platform fees


status

    Data Type: string

    Accepted Value:active or paused

    Write? Yes for pausing/un-pausing POST calls. All other calls are read only

    Nullable? No

    Description: Promoted product status; can only be updated by a user to active or paused using the pause/un-pause endpoints

      GET calls can return
      active,paused,scheduled, ended,budgetHit, noFunds, draft, archived
      note: GET calls for promoted products can only return active or paused

      POST calls can only use
      active or paused

 

Add Products to a Specific Line Item, or Update a Bid Override

This endpoint adds one or more products to promote on the specified line item. The resulting state of the line item is returned as a single page. 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 -X POST "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products/append" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>" \
    -H "Content-Type: application/json" \
    -d '{
            "data": [
                {
                    "type": "RetailMediaPromotedProduct",
                    "id": "sku1",
                    "attributes": {
                        "bidOverride": 3.50
                    }
                },
                {
                    "type": "RetailMediaPromotedProduct",
                    "id": "sku3",
                    "attributes": {
                        "bidOverride": 2.00
                    }
                },
                {
                    "type": "RetailMediaPromotedProduct",
                    "id": "sku41",
                    "attributes": {
                        "bidOverride": 1.50
                    }
                },
                {
                    "type": "RetailMediaPromotedProduct",
                    "id": "sku67"
                }
            ]
        }'
import requests
import json

url = "https://api.criteo.com/2023-07/retail-media/line-items/325713346766241792/products/append"

payload = json.dumps({
  "data": [
    {
      "id": "be5a3dbc8eaf46608d58ce68107a5854",
      "type": "RetailMediaProductAppend",
      "attributes": {
        "bidOverride": "0.50"
      }
    }
  ]
})
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\": \"RetailMediaProductAppend\",\n      \"attributes\": {\n        \"bidOverride\": \"0.50\"\n      }\n    }\n  ]\n}");

Request request = new Request.Builder()
  .url("https://api.criteo.com/2023-07/retail-media/line-items/325713346766241792/products/append")
  .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/2023-07/retail-media/line-items/325713346766241792/products/append');
$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": "RetailMediaProductAppend",\n      "attributes": {\n        "bidOverride": "0.50"\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

{
    "metadata": {
        "totalItemsAcrossAllPages": 3,
        "currentPageSize": 2147483647,
        "currentPageIndex": 0,
        "totalPages": 1
    },
    "data": [
        {
            "attributes": {
                "bidOverride": null,
                "status": "active",
                "id": "06d3049c3e1642ec92479dbeca1fc39f"
            },
            "id": "06d3049c3e1642ec92479dbeca1fc39f",
            "type": "RetailMediaPromotedProduct"
        },
        {
            "attributes": {
                "bidOverride": null,
                "status": "active",
                "id": "156a8cb56faf4e6a9c2eb0451255f13c"
            },
            "id": "156a8cb56faf4e6a9c2eb0451255f13c",
            "type": "RetailMediaPromotedProduct"
        },
        {
            "attributes": {
                "bidOverride": 0.35000000,
                "status": "active",
                "id": "926097"
            },
            "id": "926097",
            "type": "RetailMediaPromotedProduct"
        }
    ],
    "warnings": [],
    "errors": []
}

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": [
                {
                    "type": "RetailMediaPromotedProduct",
                    "id": "sku1"
                }
            ]
        }'
import requests
import json

url = "https://api.criteo.com/2023-07/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/2023-07/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/2023-07/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

{
    "metadata": {
        "totalItemsAcrossAllPages": 2,
        "currentPageSize": 2147483647,
        "currentPageIndex": 0,
        "totalPages": 1
    },
    "data": [
        {
            "attributes": {
                "bidOverride": null,
                "status": "active",
                "id": "06d3049c3e1642ec92479dbeca1fc39f"
            },
            "id": "06d3049c3e1642ec92479dbeca1fc39f",
            "type": "RetailMediaPromotedProduct"
        },
        {
            "attributes": {
                "bidOverride": null,
                "status": "active",
                "id": "156a8cb56faf4e6a9c2eb0451255f13c"
            },
            "id": "156a8cb56faf4e6a9c2eb0451255f13c",
            "type": "RetailMediaPromotedProduct"
        }
    ],
    "warnings": [],
    "errors": []
}

Get All Products on a Specific Line Item

This endpoint lists all products on the specified line item. Results are paginated.

https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products

Sample Request

curl -X GET "https://api.criteo.com/{version}/retail-media/line-items/2465695028166499188/products" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
import requests

url = "https://api.criteo.com/2023-07/retail-media/line-items/325713346766241792/products"

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/2023-07/retail-media/line-items/325713346766241792/products")
  .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/2023-07/retail-media/line-items/325713346766241792/products');
$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

{
    "metadata": {
        "totalItemsAcrossAllPages": 3,
        "currentPageSize": 20,
        "currentPageIndex": 0,
        "totalPages": 1
    },
    "data": [
        {
            "attributes": {
                "bidOverride": null,
                "status": "active",
                "id": "06d3049c3e1642ec92479dbeca1fc39f"
            },
            "id": "06d3049c3e1642ec92479dbeca1fc39f",
            "type": "RetailMediaPromotedProduct"
        },
      
      //...

        {
            "attributes": {
                "bidOverride": null,
                "status": "active",
                "id": "926097"
            },
            "id": "926097",
            "type": "RetailMediaPromotedProduct"
        }
    ],
    "warnings": [],
    "errors": []
}

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/2023-07/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/2023-07/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/2023-07/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

{
    "warnings": [],
    "errors": []
}

Reactivate Paused Products on a Specific Line Item

This endpoint allows pausing 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/2023-07/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/2023-07/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/2023-07/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

// Sample Response
{
    "warnings": [],
    "errors": []
}

Responses

ResponseDescription
🔵 200Call completed with success
🔵 201Promoted product paused or un-paused with success.
🔴 400Bad 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 - Pause and unpause requests do not use BidOverride or Status attributes; only the Id is required.
🔴 403API user does not have the authorization to make requests to the account ID. For an authorization request, follow the authorization request steps
🔴 404Line item ID not found