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

# Insights - Digital Shelf Intelligence

> Programmatic access to weekly aggregated shelf performance, visibility, and competitive benchmark data for brands and 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>;
};

## Overview

The Digital Shelf Intelligence API gives brands and advertisers programmatic access to weekly aggregated performance data for products sold through supported retailers. It enables automated retrieval of:

* **Sales performance data** — units sold, sales, and listing prices at brand or SKU level
* **Visibility and ranking data** — PDP views and category-level sales rank
* **Competitive benchmark indices** — relative performance vs. category benchmarks for consideration and sales conversion

The API is designed for users who need to pull shelf intelligence data at scale — integrating it into internal reporting pipelines, BI tools, or automated alerting workflows — without relying on manual dashboard exports.

All data is aligned to the retailer's local time zone and reported in **weekly intervals (Monday–Sunday)**.

The report supports two aggregation levels:

* **Brand-level** — metrics grouped across all SKUs belonging to a brand (portfolio tracking, brand vs. category benchmarking, retailer comparisons)
* **SKU-level** — metrics reported per individual product (performance diagnostics, assortment optimization, PDP traffic and conversion analysis)

<Info>
  You can find the Digital Shelf Intelligence endpoints in the API Reference under Insights.
</Info>

***

## Endpoints

| Verb   | Endpoint                                                    | Description                                        |
| :----- | :---------------------------------------------------------- | :------------------------------------------------- |
| `POST` | `/preview/retail-media/insights/digital-shelf-intelligence` | Submit a Digital Shelf Intelligence report request |
| `GET`  | `/preview/retail-media/insights/{reportId}/status`          | Poll the status of a submitted report              |
| `GET`  | `/preview/retail-media/insights/{reportId}/output`          | Retrieve the output of a completed report          |

***

## Dimensions

Dimensions describe how report data is grouped. The dimension set is fixed by `aggregationLevel` — clients do not provide a custom dimensions list.

### Time dimensions

| Dimension   | Description                                            |
| ----------- | ------------------------------------------------------ |
| `startDate` | Start of the reporting week (always a Monday)          |
| `endDate`   | End of the reporting week (always a Sunday, inclusive) |

### Retailer dimensions

| Dimension      | Description                        |
| -------------- | ---------------------------------- |
| `retailerId`   | Unique identifier for the retailer |
| `retailerName` | Display name of the retailer       |

### Product & taxonomy dimensions

| Dimension   | Availability | Description                      |
| ----------- | ------------ | -------------------------------- |
| `category`  | Brand & SKU  | Product category                 |
| `brandId`   | Brand only   | Unique identifier for the brand  |
| `brandName` | Brand only   | Brand name                       |
| `skuId`     | SKU only     | Retailer-specific SKU identifier |
| `skuName`   | SKU only     | Retailer-specific product name   |

***

## Metrics

Metrics represent performance, sales, and visibility indicators. Availability varies by aggregation level.

### Commercial performance

| Metric                 | Availability | Description                                         |
| ---------------------- | ------------ | --------------------------------------------------- |
| `totalSalesOnline`     | Brand & SKU  | Total online sales, in the account's local currency |
| `totalSoldUnitsOnline` | Brand & SKU  | Total number of units sold online                   |
| `listingPrice`         | SKU only     | Product listing price from the retailer catalog     |

### Visibility & ranking

| Metric              | Availability | Description                                         |
| ------------------- | ------------ | --------------------------------------------------- |
| `totalPdpPageViews` | Brand & SKU  | Total product detail page (PDP) views               |
| `pdpViewRank`       | Brand & SKU  | Rank of products by PDP views within the category   |
| `salesRank`         | Brand & SKU  | Rank of products by total sales within the category |

### Performance indices

| Metric               | Availability | Description                                                                             |
| -------------------- | ------------ | --------------------------------------------------------------------------------------- |
| `considerationIndex` | Brand & SKU  | Relative PDP views per SKU vs. category benchmark. Values >1 indicate above benchmark.  |
| `salesIndex`         | Brand & SKU  | Relative sales per PDP view vs. category benchmark. Values >1 indicate above benchmark. |

***

## Endpoint: Submit report request

Submit a Digital Shelf Intelligence report job. The API is **asynchronous** — this call returns a `reportId` to poll for results.

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/preview/retail-media/insights/digital-shelf-intelligence
  ```
</EndpointBadge>

### Request attributes

| Attribute          | Type            | Required | Description                                                                                                                                                                           |
| ------------------ | --------------- | :------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `accountId`        | `string`        |    Yes   | External Retail Media account ID. Must be numeric.                                                                                                                                    |
| `startDate`        | `string` (date) |    Yes   | Inclusive start date. If not a Monday, the report is accepted and shifted back to the Monday of that week, with a warning.                                                            |
| `endDate`          | `string` (date) |    Yes   | Inclusive end date. If not a Sunday, the report is accepted and shifted forward to the Sunday of that week, with a warning.                                                           |
| `aggregationLevel` | `string`        |    Yes   | One of `brand` or `sku`.                                                                                                                                                              |
| `metrics`          | `string[]`      |    Yes   | At least one metric. Allowed values: `considerationIndex`, `listingPrice`, `pdpViewRank`, `salesIndex`, `salesRank`, `totalPdpPageViews`, `totalSalesOnline`, `totalSoldUnitsOnline`. |
| `retailerIds`      | `string[]`      |    No    | Retailer IDs to filter on. Must be numeric internal IDs.                                                                                                                              |
| `brandIds`         | `string[]`      |    No    | Brand IDs to filter on. Must be numeric external IDs.                                                                                                                                 |
| `skuIds`           | `object[]`      |    No    | SKU filters grouped by retailer. Ignored with a warning when `aggregationLevel` is `brand`. Each entry requires `retailerId` (string) and `retailerSkuIds` (string\[]).               |
| `categories`       | `string[]`      |    No    | Category names to filter on.                                                                                                                                                          |
| `format`           | `string`        |    No    | Output format. One of `json`, `json-compact`, `json-newline`, `csv`. Default: `json-compact`.                                                                                         |

<Note>
  `startDate` must not be after `endDate`, and the requested interval must be **100 days or less**.
</Note>

### Sample request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.criteo.com/preview/retail-media/insights/digital-shelf-intelligence' \
    --header 'Authorization: Bearer <ACCESS_TOKEN>' \
    --header 'Content-Type: application/json' \
    --data '{
      "data": {
        "attributes": {
          "accountId": "123",
          "startDate": "2025-08-11",
          "endDate": "2025-08-17",
          "aggregationLevel": "sku",
          "metrics": ["totalSalesOnline", "totalSoldUnitsOnline", "listingPrice"],
          "retailerIds": ["101", "102"],
          "brandIds": ["2001", "2002"],
          "skuIds": [
            {
              "retailerId": "101",
              "retailerSkuIds": ["sku-001", "sku-002"]
            }
          ],
          "categories": ["Beverages", "Snacks"],
          "format": "json-compact"
        }
      }
    }'
  ```

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

  url = "https://api.criteo.com/preview/retail-media/insights/digital-shelf-intelligence"
  headers = {
      "Authorization": "Bearer <ACCESS_TOKEN>",
      "Content-Type": "application/json",
  }
  payload = {
      "data": {
          "attributes": {
              "accountId": "123",
              "startDate": "2025-08-11",
              "endDate": "2025-08-17",
              "aggregationLevel": "sku",
              "metrics": ["totalSalesOnline", "totalSoldUnitsOnline", "listingPrice"],
              "retailerIds": ["101", "102"],
              "brandIds": ["2001", "2002"],
              "skuIds": [{"retailerId": "101", "retailerSkuIds": ["sku-001", "sku-002"]}],
              "categories": ["Beverages", "Snacks"],
              "format": "json-compact",
          }
      }
  }

  response = requests.post(url, headers=headers, json=payload)
  print(response.json())
  ```

  ```java Java theme={null}
  OkHttpClient client = new OkHttpClient();

  MediaType mediaType = MediaType.parse("application/json");
  RequestBody body = RequestBody.create(mediaType, """
  {
    "data": {
      "attributes": {
        "accountId": "123",
        "startDate": "2025-08-11",
        "endDate": "2025-08-17",
        "aggregationLevel": "sku",
        "metrics": ["totalSalesOnline", "totalSoldUnitsOnline", "listingPrice"],
        "retailerIds": ["101", "102"],
        "brandIds": ["2001", "2002"],
        "skuIds": [{"retailerId": "101", "retailerSkuIds": ["sku-001", "sku-002"]}],
        "categories": ["Beverages", "Snacks"],
        "format": "json-compact"
      }
    }
  }
  """);

  Request request = new Request.Builder()
    .url("https://api.criteo.com/preview/retail-media/insights/digital-shelf-intelligence")
    .post(body)
    .addHeader("Authorization", "Bearer <ACCESS_TOKEN>")
    .addHeader("Content-Type", "application/json")
    .build();

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

  ```php PHP theme={null}
  $request = new HTTP_Request2();
  $request->setUrl('https://api.criteo.com/preview/retail-media/insights/digital-shelf-intelligence');
  $request->setMethod(HTTP_Request2::METHOD_POST);
  $request->setHeader(['Authorization' => 'Bearer <ACCESS_TOKEN>', 'Content-Type' => 'application/json']);
  $request->setBody(json_encode([
      'data' => [
          'attributes' => [
              'accountId' => '123',
              'startDate' => '2025-08-11',
              'endDate' => '2025-08-17',
              'aggregationLevel' => 'sku',
              'metrics' => ['totalSalesOnline', 'totalSoldUnitsOnline', 'listingPrice'],
              'retailerIds' => ['101', '102'],
              'brandIds' => ['2001', '2002'],
              'skuIds' => [['retailerId' => '101', 'retailerSkuIds' => ['sku-001', 'sku-002']]],
              'categories' => ['Beverages', 'Snacks'],
              'format' => 'json-compact',
          ],
      ],
  ]));

  echo $request->send()->getBody();
  ```
</CodeGroup>

### Sample response

```json theme={null}
{
  "data": {
    "id": "87a8e280-9cc9-47f3-9bf9-b68e947cade5",
    "type": "InsightStatusResponse",
    "attributes": {
      "status": "Pending",
      "message": null,
      "createdAt": "2026-06-12T14:57:07.336Z",
      "expiresAt": null,
      "rowCount": null,
      "md5CheckSum": null,
      "fileSizeBytes": null
    }
  },
  "warnings": [],
  "errors": []
}
```

***

## Endpoint: Poll report status

Check whether a submitted report job has completed. Returns `status: "Pending"` while processing, or HTTP `410` if the report failed, expired, or was invalidated.

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/preview/retail-media/insights/{reportId}/status
  ```
</EndpointBadge>

### Sample request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/status' \
    --header 'Authorization: Bearer <ACCESS_TOKEN>'
  ```

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

  response = requests.get(
      "https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/status",
      headers={"Authorization": "Bearer <ACCESS_TOKEN>"},
  )
  print(response.json())
  ```

  ```java Java theme={null}
  Request request = new Request.Builder()
    .url("https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/status")
    .get()
    .addHeader("Authorization", "Bearer <ACCESS_TOKEN>")
    .build();

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

  ```php PHP theme={null}
  $request = new HTTP_Request2();
  $request->setUrl('https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/status');
  $request->setMethod(HTTP_Request2::METHOD_GET);
  $request->setHeader(['Authorization' => 'Bearer <ACCESS_TOKEN>']);
  echo $request->send()->getBody();
  ```
</CodeGroup>

### Sample response

```json theme={null}
{
  "data": {
    "id": "87a8e280-9cc9-47f3-9bf9-b68e947cade5",
    "type": "InsightStatusResponse",
    "attributes": {
      "status": "Success",
      "message": null,
      "createdAt": "2026-06-12T15:00:43.000Z",
      "expiresAt": "2026-06-19T15:00:43.000Z",
      "rowCount": 0,
      "md5CheckSum": "d41d8cd98f00b204e9800998ecf8427e",
      "fileSizeBytes": 0
    }
  },
  "warnings": [],
  "errors": []
}
```

***

## Endpoint: Retrieve report output

Download the results of a completed report. Only succeeds when report status is `Success`. Returns HTTP `400` with code `insight-not-ready` if the report is still `Pending`.

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/preview/retail-media/insights/{reportId}/output
  ```
</EndpointBadge>

### Sample request

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/output' \
    --header 'Authorization: Bearer <ACCESS_TOKEN>' \
    --header 'Accept: text/plain'
  ```

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

  response = requests.get(
      "https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/output",
      headers={"Authorization": "Bearer <ACCESS_TOKEN>", "Accept": "text/plain"},
  )
  print(response.text)
  ```

  ```java Java theme={null}
  Request request = new Request.Builder()
    .url("https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/output")
    .get()
    .addHeader("Authorization", "Bearer <ACCESS_TOKEN>")
    .addHeader("Accept", "text/plain")
    .build();

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

  ```php PHP theme={null}
  $request = new HTTP_Request2();
  $request->setUrl('https://api.criteo.com/preview/retail-media/insights/<REPORT_ID>/output');
  $request->setMethod(HTTP_Request2::METHOD_GET);
  $request->setHeader(['Authorization' => 'Bearer <ACCESS_TOKEN>', 'Accept' => 'text/plain']);
  echo $request->send()->getBody();
  ```
</CodeGroup>

### Sample response

```json theme={null}
{"columns":["startDate","endDate","retailerId","retailerName","category","skuId","skuName","considerationIndex"],
"data":[],
"rows":0}
```

***

## Responses

| HTTP status        | Code                  | Description                                                                                          | Troubleshooting                                               |
| ------------------ | --------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `200 OK`           | —                     | Report accepted. Response contains `reportId` in `data.id`.                                          | Poll `/insights/{reportId}/status` until status is `Success`. |
| `200 OK`           | —                     | `status: "Pending"` — report is still processing.                                                    | Retry the status call later.                                  |
| `200 OK`           | —                     | `status: "Success"` — output is ready.                                                               | Call `/insights/{reportId}/output` to download.               |
| `200 OK` + warning | `invalid-date`        | `startDate` not a Monday or `endDate` not a Sunday. Request accepted and shifted to week boundaries. | Send Monday–Sunday dates to avoid auto-adjustment warnings.   |
| `200 OK` + warning | `incompatible-filter` | `skuIds` sent with `aggregationLevel: brand` — filter ignored.                                       | Use `aggregationLevel: sku` when filtering by SKU.            |
| `200 OK` + warning | `invalid-metric`      | `listingPrice` requested with `aggregationLevel: brand` — metric omitted.                            | Use `aggregationLevel: sku` when requesting `listingPrice`.   |
| `400 Bad Request`  | `attribute-required`  | Missing required attribute, invalid ID format, `startDate > endDate`, or interval > 100 days.        | Validate the request body before submitting.                  |
| `400 Bad Request`  | `insight-not-ready`   | Output endpoint called before report reached `Success`.                                              | Poll the status endpoint first.                               |
| `403 Forbidden`    | `forbidden`           | Caller not allowed to access the requested account or endpoint.                                      | Confirm account permissions and feature enablement.           |
| `404 Not Found`    | `insight-not-found`   | Report ID does not exist.                                                                            | Verify the `reportId` and try again.                          |
| `410 Gone`         | `insight-failed`      | Report execution failed.                                                                             | Submit a new report request.                                  |
| `410 Gone`         | `insight-invalidated` | Report invalidated and no longer available.                                                          | Submit a new report request.                                  |
| `410 Gone`         | `insight-expired`     | Report expired and no longer available.                                                              | Submit a new report request.                                  |
