> ## Documentation Index
> Fetch the complete documentation index at: https://developers.criteo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Promoted Products

export const EndpointBadge = ({method = "GET", children}) => {
  const METHOD_STYLES = {
    GET: {
      bg: "mint-bg-[#2AB673]"
    },
    POST: {
      bg: "mint-bg-[#3064E3]"
    },
    PUT: {
      bg: "mint-bg-[#C28C30]"
    },
    PATCH: {
      bg: "mint-bg-[#DA622B]"
    },
    DELETE: {
      bg: "mint-bg-[#CB3A32]"
    },
    API: {
      bg: "mint-bg-black"
    }
  };
  const key = method.toUpperCase();
  const styles = METHOD_STYLES[key] ?? METHOD_STYLES.API;
  return <div className="relative mt-7">
      <span className={`absolute -top-2 -left-2 z-10 ${styles.bg} text-white px-2.5 py-0.5 rounded-full text-xs font-bold tracking-wide`}>
        {key}
      </span>
      {children}
    </div>;
};

<Info>
  **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](/retail-media/v2025.01/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.
  * Each line item is limited to a maximum of 500 promoted products.
</Info>

 

## **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](/retail-media/v2025.01/docs/retailers) catalog and obtained from the account [Catalog](/retail-media/v2025.01/docs/catalogs)Accepted values: up to 500-chars string Writeable? N / Nullable? N                                                                                                                                            |
| `lineItemId`\* | string    | [Line Item](/retail-media/v2025.01/docs/line-items) ID, in which the product is to be promoted; required in the endpoints' path to define in which line item to perform the actionAccepted values: string of int64 Writeable? N / Nullable? N                                                                                                                                             |
| `bidOverride`  | decimal   | Bid value for the specific product; overrides `targetBid` specified on the [Line Item](/retail-media/v2025.01/docs/line-items) and must satisfy `minBid` from [Catalog](/retail-media/v2025.01/docs/catalogs) (input excludes platform fees)Accepted values: `bidOverride` ≥ 0.0 Default: `0.0` Writeable? Y / Nullable? Y                                                                |
| `status`       | enum      | Status of Promoted Product; can only be updated to active or paused using the pause/un-pause endpoints below. For more details about each state, check out [Campaign, Line Item & Products Status](/retail-media/v2025.01/docs/campaign-lineitem-status)Accepted values: `active`, `paused`, `scheduled`, `ended`, `budgetHit`, `noFunds`, `draft`, `archived` Writeable? Y / Nullable? N |

*\*Required*

 

## **Get All Products on a Specific Line Item**

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

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products
  ```
</EndpointBadge>

**Optional Query Parameters**

| Query Param | Data Type | Description                                                                                                                       |
| ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `offsite`   | integer   | Pagination parameter, see [API Response](/retail-media/v2025.01/docs/api-response)                                                |
| `limit`     | integer   | Pagination parameter, see [API Response](/retail-media/v2025.01/docs/api-response)                                                |
| `fields`    | list      | Comma-separated list of optional attributes to include in the response - can be used to optimize response time and payload length |

**Sample Request**

<CodeGroup>
  ```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 <MY_ACCESS_TOKEN>"
  ```

  ```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 <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/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 PHP theme={null}
  <?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();
  }
  ```
</CodeGroup>

**Sample Response**

🔵 HTTP code `200`:

<CodeGroup>
  ```json JSON theme={null}
  {
      "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"
              }
          }
      ]
  }
  ```
</CodeGroup>

## **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.

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/append
  ```
</EndpointBadge>

**Sample Request**

<CodeGroup>
  ```bash cURL expandable theme={null}
  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"
                  }
              ]
          }'
  ```

  ```python Python theme={null}
  import requests
  import json

  url = "https://api.criteo.com/{version}/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)
  ```

  ```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\": \"RetailMediaProductAppend\",\n      \"attributes\": {\n        \"bidOverride\": \"0.50\"\n      }\n    }\n  ]\n}");

  Request request = new Request.Builder()
    .url("https://api.criteo.com/{version}/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 PHP theme={null}
  <?php
  require_once 'HTTP/Request2.php';
  $request = new HTTP_Request2();
  $request->setUrl('https://api.criteo.com/{version}/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();
  }
  ```
</CodeGroup>

**Sample Response**

<CodeGroup>
  ```json JSON expandable theme={null}
  {
      "meta": {
          "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": []
  }
  ```
</CodeGroup>

## **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.

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/delete
  ```
</EndpointBadge>

**Sample Request**

<CodeGroup>
  ```bash cURL theme={null}
  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"
                  }
              ]
          }'
  ```

  ```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 <MY_ACCESS_TOKEN>'
  }

  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 <MY_ACCESS_TOKEN>")
    .build();

  Response response = client.newCall(request).execute();
  ```

  ```php PHP theme={null}
  <?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();
  }
  ```
</CodeGroup>

**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:

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/pause
  ```
</EndpointBadge>

**Sample Request**

<CodeGroup>
  ```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 <MY_ACCESS_TOKEN>' \
      -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 <MY_ACCESS_TOKEN>'
  }

  response = requests.request("POST", url, headers=headers, data=payload)

  print(response.text)
  ```

  ```php PHP theme={null}
  <?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();
  }
  ```

  ```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 <MY_ACCESS_TOKEN>")
    .build();

  Response response = client.newCall(request).execute();
  ```
</CodeGroup>

**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:

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/{version}/retail-media/line-items/{lineItemId}/products/unpause
  ```
</EndpointBadge>

**Sample Request**

<CodeGroup>
  ```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 <MY_ACCESS_TOKEN>' \
  -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 <MY_ACCESS_TOKEN>'
  }

  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 <MY_ACCESS_TOKEN>")
    .build();

  Response response = client.newCall(request).execute();
  ```

  ```php PHP theme={null}
  <?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();
  }
  ```
</CodeGroup>

**Sample Response**

🔵 HTTP code `204` (no body content)

## **Responses**

<table>
  <thead>
    <tr>
      <th>
        Response
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        🟢 `200`
      </td>

      <td>
        Call completed with success
      </td>
    </tr>

    <tr>
      <td>
        🟢 `204`
      </td>

      <td>
        Promoted product paused or un-paused with success (no body content returned)
      </td>
    </tr>

    <tr>
      <td>
        🔴 `400`
      </td>

      <td>
        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.
      </td>
    </tr>

    <tr>
      <td>
        🔴 `403`
      </td>

      <td>
        API user does not have authorization to make requests for the account ID. For authorization, follow the [authorization request](https://developers.criteo.com/retail-media/docs/authorization-requests) steps.
      </td>
    </tr>

    <tr>
      <td>
        🔴 `404`
      </td>

      <td>
        Line item ID not found
      </td>
    </tr>
  </tbody>
</table>
