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

# Version 2025.07 Release Notes

<Info>
  Version **2025.07** of the Criteo Retail Media API is live as of **July 22nd, 2025** and will be supported until **July 28th, 2026**.  A new Postman collection for 2025.07 is also available in the [Criteo Postman workspace](https://www.postman.com/realcriteo/workspace/criteo/overview).
</Info>

<Info>
  **New SDK Release**

  A new SDK version will be available for the `2025.07` release.
</Info>

This version introduces new capabilities to Criteo Retail Media API and changes to existing endpoints. This page aims at listing all changes that happened endpoint per endpoint. Only endpoints with changes are listed here.

The changes of versions `2025.07` are:

* a new **base URL**,
* new endpoints to **Review Keywords** for retailers,
* new endpoints for **Catalog** to increase efficiency,
* a new **Brand Search** endpoint,
* new endpoints for  **Retailer Billing**
* new **Reporting Dimensions & Filters**  within the analytics endpoints,

***

# New Base URL

With the introduction of this new version, the base URL will now change from **the old base URL**:

```text URL theme={null}
https://api.criteo.com/2025-04/retail-media/{endpoint}
```

to the **new base URL**:

```text URL theme={null}
https://api.criteo.com/2025-07/retail-media/{endpoint}
```

***

# What's New

## Keyword Review & Approval

In version `2025.07`, we've introduced new endpoints that are used by retailers to review keywords that are desired 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 retailer guidelines.

<Info>
  You can find the documentation for the Keyword review endpoints [here](/retail-media/docs/keyword-review).
</Info>

***

### Updated Endpoints

The following new catalog endpoint can be found below:

<table>
  <thead>
    <tr>
      <th>
        <p>
          Verb
        </p>
      </th>

      <th>
        <p>
          Endpoint
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <b>
            GET
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /retail-media/accounts/:account-id/keywords/in-review-report
          </code>
        </p>
      </td>

      <td>
        <p>
          Generate a list of reports for line items which contain one or more actionable keyword reviews
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            GET
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /retail-media/line-items/:id/keywords
          </code>

          \*
        </p>
      </td>

      <td>
        <p>
          Fetch keywords associated with the specified line item
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /retail-media/line-items/:line-item-id/keywords/review
          </code>
        </p>
      </td>

      <td>
        <p>
          Update the status of keyword reviews under a line item
        </p>
      </td>
    </tr>
  </tbody>
</table>

<Warning>
  **NOTE**

  The asterisk next to the `/retail-media/line-items/:id/keywords` is because this endpoint is undergoing a **breaking change**, because this endpoint has been updated to allow for retailers to be able to view the keywords that are `inReview` status for line items targeting their inventory.

  Please see **[here](/retail-media/v2024.10/docs/versioning-policy#breaking-vs-non-breaking-changes)** for more information on breaking changes and please note that older versions of this endpoint will still be supported in alignment with their support window as defined in our Versioning Policy.
</Warning>

***

### Sample Request

For `/retail-media/accounts/:account-id/keywords/in-review-report`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X GET "https://api.criteo.com/2025-07/retail-media/accounts/368477770340928512/keywords/in-review-report?offset=0&limit=25" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
  ```

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

  url = "https://api.criteo.com/2025-07/retail-media/accounts/368477770340928512/keywords/in-review-report?offset=0&limit=25"

  payload={}
  headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer <MY_ACCESS_TOKEN>'
  }

  response = requests.request("GET", 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/2025-07/retail-media/accounts/368477770340928512/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 <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();
  }
  ```

  ```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/2025-07/retail-media/accounts/368477770340928512/keywords/in-review-report?offset=0&limit=25")
    .method("GET", body)
    .addHeader("Accept", "application/json")
    .addHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
    .build();

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

### Sample Response

For `/retail-media/accounts/:account-id/keywords/in-review-report`:

```json expandable theme={null}
{
    "meta": {
        "count": 2,
        "offset": 0,
        "limit": 25
    },
    "data": [
        {
            "id": "12475533336215680",
            "type": "LineItemKeywordReviewReport",
            "attributes": {
                "lineItemId": "124444617126215680",
                "lineItemName": "LI_Test12101403",
                "retailerId": "299",
                "retailerName": "z_CriteoTest_299",
                "campaignId": "12455551383269376",
                "campaignName": "Test12101403_Update",
                "accountId": "97397777059194368",
                "accountName": "Test Account",
                "countKeywords": 2
            }
        },
        {
            "id": "124773333405488128",
            "type": "LineItemKeywordReviewReport",
            "attributes": {
                "lineItemId": "124777703405488128",
                "lineItemName": "LI——Test12101403",
                "retailerId": "299",
                "retailerName": "z_CriteoTest_299",
                "campaignId": "124755555383269376",
                "campaignName": "Test12101403_Update",
                "accountId": "97393333059194368",
                "accountName": "Test Account",
                "countKeywords": 4
            }
        }
    ],
    "warnings": [],
    "errors": []
}
```

***

### Sample Request

For `/retail-media/line-items/:id/keywords`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X GET "https://api.criteo.com/2025-07/retail-media/line-items/358669999976373760/keywords" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
  ```

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

  url = "https://api.criteo.com/2025-07/retail-media/line-items/358669652999973760/keywords"

  payload={}
  headers = {
    'Accept': 'application/json',
    'Authorization': 'Bearer <MY_ACCESS_TOKEN>'
  }

  response = requests.request("GET", 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/2025-07/retail-media/line-items/358669999976373760/keywords');
  $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();
  }
  ```

  ```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/2025-07/retail-media/line-items/358669999976373760/keywords")
    .method("GET", body)
    .addHeader("Accept", "application/json")
    .addHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
    .build();

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

### Sample Response

For `/retail-media/line-items/:id/keywords`:

```json expandable theme={null}
{
    "data": {
        "id": "124755555126215680",
        "type": "RetailMediaKeywordsModel",
        "attributes": {
            "keywords": {
                "ww": {
                    "reviewState": "Approved",
                    "matchType": "PositiveExactMatch",
                    "bid": 2.00,
                    "inputKeywords": {
                        "positiveExact": [
                            "ww"
                        ]
                    },
                    "createdAt": "2024-07-30T02:16:57.1437069",
                    "updatedAt": "2025-03-27T17:57:29.81817"
                },
                "testaddallkeyword": {
                    "reviewState": "InReview",
                    "matchType": "PositiveExactMatch",
                    "bid": 1.30,
                    "inputKeywords": {
                        "positiveExact": [
                            "testaddallkeyword"
                        ]
                    },
                    "createdAt": "2024-07-30T06:55:40.5533984",
                    "updatedAt": "2024-07-30T06:55:41.3464883"
                },
                "testallkeyword0730": {
                    "reviewState": "InReview",
                    "matchType": "PositiveExactMatch",
                    "bid": 1.99,
                    "inputKeywords": {
                        "positiveExact": [
                            "testallkeyword0730"
                        ]
                    },
                    "createdAt": "2024-07-30T11:10:44.0215413",
                    "updatedAt": "2024-07-30T11:10:44.9437715"
                },
                "pasta": {
                    "reviewState": "Approved",
                    "matchType": "PositiveExactMatch",
                    "bid": null,
                    "inputKeywords": {
                        "positiveExact": [
                            "pasta",
                            "pastas"
                        ]
                    },
                    "createdAt": "2025-04-17T15:59:46.1603449",
                    "updatedAt": "2025-04-17T16:20:13.7929382"
                }
            }
        }
    }
}
```

***

### Sample Request

For `/retail-media/line-items/:line-item-id/keywords/review`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X POST "https://api.criteo.com/2025-07/retail-media/line-items/358669652976373760/keywords/review" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>" \
      -H "Content-Type: application/json" \
      -d '{
              "data": {
                  "attributes": {
                      "keywords": [
                          {
                              "phrase": "top",
                              "reviewState": "rejected"
                          },
                          {
                              "phrase": "t-shirt",
                              "reviewState": "approved"
                          }
                      ]
                  }
              }
          }'
  ```

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

  headers = {
      'Authorization': 'Bearer <MY_ACCESS_TOKEN>',
      'Content-Type': 'application/json',
  }

  json_data = {
      'data': {
          'attributes': {
              'keywords': [
                  {
                      'phrase': 'top',
                      'reviewState': 'rejected',
                  },
                  {
                      'phrase': 't-shirt',
                      'reviewState': 'approved',
                  },
              ],
          },
      },
  }

  response = requests.post(
      'https://api.criteo.com/2025-07/retail-media/line-items/358669652976373760/keywords/review',
      headers=headers,
      json=json_data,
  )
  ```

  ```java Java theme={null}
  import java.io.IOException;
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpRequest.BodyPublishers;
  import java.net.http.HttpResponse;

  HttpClient client = HttpClient.newBuilder()
      .followRedirects(HttpClient.Redirect.NORMAL)
      .build();

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.criteo.com/2025-07/retail-media/line-items/358669652976373760/keywords/review"))
      .POST(BodyPublishers.ofString("{\n            \"data\": {\n                \"attributes\": {\n                    \"keywords\": [\n                        {\n                            \"phrase\": \"top\",\n                            \"reviewState\": \"rejected\"\n                        },\n                        {\n                            \"phrase\": \"t-shirt\",\n                            \"reviewState\": \"approved\"\n                        }\n                    ]\n                }\n            }\n        }"))
      .setHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
      .setHeader("Content-Type", "application/json")
      .build();

  HttpResponse&lt;String&gt; response = client.send(request, HttpResponse.BodyHandlers.ofString());
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.criteo.com/2025-07/retail-media/line-items/358669652976373760/keywords/review');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer <MY_ACCESS_TOKEN>',
      'Content-Type: application/json',
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, "{\n            \"data\": {\n                \"attributes\": {\n                    \"keywords\": [\n                        {\n                            \"phrase\": \"top\",\n                            \"reviewState\": \"rejected\"\n                        },\n                        {\n                            \"phrase\": \"t-shirt\",\n                            \"reviewState\": \"approved\"\n                        }\n                    ]\n                }\n            }\n        }");
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

  curl_close($ch);
  ```
</CodeGroup>

### Sample Response

For `/retail-media/line-items/:line-item-id/keywords/review`:

```json theme={null}
{
    "data": {
        "type": "RetailMediaKeywordsReviewResult",
        "attributes": {
            "keywords": [
                {
                    "phrase": "top",
                    "reviewState": "Rejected"
                },
                {
                    "phrase": "t-shirt",
                    "reviewState": "Approved"
                },
                {
                    "phrase": "top woman",
                    "reviewState": "InReview"
                }
            ]
        }
    },
    "warnings": [],
    "errors": []
}
```

***

## Catalog Export

In version `2025.07`, we've introduced new catalog endpoints with the inclusion of new fields and features, such as the `includeFields`, `modifiedAfter`, and a new `retailerIdFilter` in the brand-catalog-export endpoint.

The `includeFields` is a **new filter** that gives users the option of focusing on what information you want in the catalog call, as some fields may be irrelevant to specific use cases and impacts the speed of the request.  The `modifiedAfter` is a way to focus further on SKUs that have been modified after a specified time for both seller and brand endpoints.  The upper limit of this field is set to -18 hours from the current time.  After this, a user will be asked to run a full export instead.

<Info>
  You can find the Catalog endpoints documentation [here](/retail-media/docs/catalog-endpoints).
</Info>

***

### Updated Endpoints

The following new catalog endpoint can be found below:

<table>
  <thead>
    <tr>
      <th>
        <p>
          Verb
        </p>
      </th>

      <th>
        <p>
          Endpoint
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /accounts/\{accountId}/brand-catalog-export
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a request to export existing catalogs from a Brand account
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /accounts/\{accountId}/seller-catalog-export
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a request to export existing catalogs from a Seller account
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            GET
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /catalogs/\{catalogId}/status
          </code>
        </p>
      </td>

      <td>
        <p>
          Retrieve the status of a specific catalog request.
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            GET
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /catalogs/\{catalogId}/output
          </code>
        </p>
      </td>

      <td>
        <p>
          Download the output of a specific catalog once it's ready.
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Sample Request

For `/accounts/{accountId}/brand-catalog-export`:

<CodeGroup>
  ```text Text theme={null}
  https://api.criteo.com/2025-07/retail-media/accounts/{accountId}/brand-catalog-export
  ```

  ```bash cURL theme={null}
  curl -L -X POST 'https://api.criteo.com/2025-07/retail-media/accounts/123/brand-catalog-export' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
  --data-raw '{
    "data": {
      "type": "CatalogRequest",
      "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/2025-07/retail-media/accounts/123/brand-catalog-export"

  payload = json.dumps({
    "data": {
      "type": "<string>",
      "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 <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   \"type\": \"<string>\",\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/2025-07/retail-media/accounts/123/brand-catalog-export")
    .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 expandable theme={null}
  <?php
  require_once 'HTTP/Request2.php';
  $request = new HTTP_Request2();
  $request->setUrl('https://api.criteo.com/2025-07/retail-media/accounts/123/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 <MY_ACCESS_TOKEN>'
  ));

  $request->setBody('{\n  "data": {\n   "type": "<string>",\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();
  }
  ```
</CodeGroup>

### Sample Response

For `/accounts/{accountId}/brand-catalog-export`:

```json theme={null}
{
    "data": {
        "type": "RetailMediaCatalogStatus",
        "id": "1122850670915847014",
        "attributes": {
            "status": "pending",
            "currency": null,
            "rowCount": null,
            "fileSizeBytes": null,
            "md5Checksum": null,
            "createdAt": "2025-01-22T23:10:12.21+00:00",
            "message": null
        }
    }
}
```

***

### Sample Request

For `/accounts/{accountId}/seller-catalog-export`:

<CodeGroup>
  ```text Text theme={null}
  https://api.criteo.com/2025-07/retail-media/accounts/{accountId}/seller-catalog-export
  ```

  ```bash cURL theme={null}
  curl -L -X POST 'https://api.criteo.com/2025-07/retail-media/accounts/123/seller-catalog-export' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
  --data-raw '{
    "data": {
      "type": "<string>",
      "attributes": {
        "sellers": [
          {
            "retailerId": "123",
            "sellerId": "5e0axxxxxxxxxx"
          }
        ],
        "modifiedAfter": "",
        "includeFields": [
          "ImageUrl",
          "Description"
        ]
      }
    }
  }'
  ```

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

  url = "https://api.criteo.com/2025-07/retail-media/accounts/123/seller-catalog-export"

  payload = json.dumps({
    "data": {
      "type": "<string>",
      "attributes": {
        "sellers": [
          {
            "retailerId": "123",
            "sellerId": "5e0axxxxxxxxxx"
          }
        ],
        "modifiedAfter": "",
        "includeFields": [
          "ImageUrl",
          "Description"
        ]
      }
    }
  })
  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   \"type\": \"<string>\",\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/2025-07/retail-media/accounts/123/seller-catalog-export")
    .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 expandable theme={null}
  <?php
  require_once 'HTTP/Request2.php';
  $request = new HTTP_Request2();
  $request->setUrl('https://api.criteo.com/2025-07/retail-media/accounts/123/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 <MY_ACCESS_TOKEN>'
  ));

  $request->setBody('{\n "data": {\n   "type": "<string>",\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();
  }
  ```
</CodeGroup>

### Sample Response

For  `/accounts/{accountId}/seller-catalog-export`:

```json theme={null}
{
    "data": {
        "type": "RetailMediaCatalogStatus",
        "id": "1122850670915847014",
        "attributes": {
            "status": "pending",
            "currency": null,
            "rowCount": null,
            "fileSizeBytes": null,
            "md5Checksum": null,
            "createdAt": "2025-01-22T23:10:12.21+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`

### Sample Request

For `/catalogs/{catalogId}/status`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.criteo.com/2025-07/retail-media/catalogs/1122888880915847014/status" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
  ```

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

  url = "https://api.criteo.com/2025-07/retail-media/catalogs/357957888889011328/status"

  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/2025-07/retail-media/catalogs/35795788888011328/status")
    .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/2025-07/retail-media/catalogs/357957888889011328/status');
  $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

For `/catalogs/{catalogId}/status`:

```json theme={null}
{
    "data": {
        "type": "RetailMediaCatalogStatus",
        "id": "1122850670915847014",
        "attributes": {
            "status": "success",
            "currency": "USD",
            "rowCount": 1001,
            "fileSizeBytes": 353293,
            "md5Checksum": "2c15b77740028435ca476823df7fb4f8",
            "createdAt": "2020-04-06T05:11:41.351+00:00",
            "message": null
        }
    }
}
```

***

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

<Warning>
  The limit will be capped at **100 000 rows**. If a user reaches this limit, they will need to revise their request to fall within the limit.
</Warning>

### Sample Request

For `/catalogs/{catalogId}/output`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.criteo.com/2025-07/retail-media/catalogs/1122850670915847014/output" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("api.criteo.com")
  payload = ''
  headers = {
    'Accept': 'application/x-json-stream',
    'Authorization': 'Bearer <MY_ACCESS_TOKEN>'
  }
  conn.request("GET", "/2025-07/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/2025-07/retail-media/catalogs/357957813719011328/output")
    .method("GET", body)
    .addHeader("Accept", "application/x-json-stream")
    .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/2025-07/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 <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

For `/catalogs/{catalogId}/output`:

```json Newline-Delimited JSON expandable theme={null}
{ \
    "id": "sku_1", \
    "name": "Product Name", \
    "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \
    "categoryId": "1234xxxx", \
    "brandId": "123456xxxxxx", \
    "brandName": "Brand Name", \
    "retailerId": "54321xxxxxx", \
    "retailerName": "Retailer Name", \
    "price": 1.00, \
    "isInStock": true, \
    "minBid": 0.30, \
    "gtin": "abc12xx", \
    "mpn": "34abxxx", \
    "imageUrl": "/image1.jpg", \
    "updatedAt": "2020-04-06T02:23:07Z", \
    "sellerId": "60axxxxxxxxxxxxxxxx", \
    "sellerName": "Seller Name", \
    "googleCategory": null, \
    "description": "Product's Description" \
}
 
// ... newline-delimited, no comma
 
{ \
    "id": "sku_2", \
    "name": "Product Name", \
    "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \
    "categoryId": "1234xxxx", \
    "brandId": "567890xxxxxx", \
    "brandName": "Brand Name", \
    "retailerId": "098765xxxxxx", \
    "retailerName": "Retailer Name", \
    "price": 1.00, \
    "isInStock": true, \
    "minBid": 0.30, \
    "gtin": "xyz12xx", \
    "mpn": "78asdxxx", \
    "imageUrl": "/image1.jpg", \
    "updatedAt": "2020-04-06T02:23:07Z", \
    "sellerId": null, \
    "sellerName": "Seller Name", \
    "googleCategory": null, \
    "description": "Product's Description" \
}

// ... newline-delimited, no comma
 
{ \
    "id": "sku_3", \
    "name": "Product Name", \
    "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \
    "categoryId": "4568xxxx", \
    "brandId": "96385xxxxxx", \
    "brandName": "Brand Name", \
    "retailerId": "412587xxxxxx", \
    "retailerName": "Retailer Name", \
    "price": 1.00, \
    "isInStock": true, \
    "minBid": 0.30, \
    "gtin": "xyz12xx", \
    "mpn": "56wsdxxx", \
    "imageUrl": "/image1.jpg", \
    "updatedAt": "2020-04-06T02:23:07Z", \
    "sellerId": null, \
    "sellerName": null, \
    "googleCategory": null, \
    "description": "Product's Description" \
}
```

***

## Brand Search

In version `2025.07`, we've introduced a **new brand search endpoint** that offers an enhanced experience to the brand lookup operation.

In the initial brand lookup workflow, users were required to search for brands specific to the account ID of interest.  This endpoint offers an experience which enables users to search for the brand by name, with the ability to indicate if this is a brand from our universal catalog (for brands) or a retailer brand (for retailers) or both.

<Info>
  You can find the Brand Search endpoint documentation [here](/retail-media/docs/brands#search-for-brands-by-name).
</Info>

***

### Updated Endpoints Includes

The following new catalog endpoint can be found below:

<table>
  <thead>
    <tr>
      <th>
        <p>
          Verb
        </p>
      </th>

      <th>
        <p>
          Endpoint
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /brands/search
          </code>
        </p>
      </td>

      <td>
        <p>
          Search for Brands by name in Retailer(s)

          <a href="/retail-media/docs/catalogs">
            Catalogs
          </a>
        </p>
      </td>
    </tr>
  </tbody>
</table>

For other related endpoints, check our stable version in [Brands](/retail-media/docs/brands)

***

### Sample Request

For*Brand Search*:

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X POST 'https://api.criteo.com/2025-07/retail-media/brands/search?offset=0&limit=25' \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
      -d '{
              "data": {
                  "type": "<string>",
                  "attributes": {
                      "retailerIds": [
                          "123",
                          "456"
                      ],
                      "name": "brand abc",
                      "brandType": "all"
                  }
              }
          }'
  ```

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

  url = "https://api.criteo.com/2025-07/retail-media/brands/search?offset=0&limit=25"

  payload = json.dumps({
      "data": {
          "type": "<string>",
          "attributes": {
              "retailerIds": [
                  "123",
                  "456"
              ],
              "name": "brand abc",
              "brandType": "all"
          }
      }
  })
  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, "{\"data\":{\"type\":\"<string>\",\"attributes\":{\"retailerIds\":[\"123\",\"456\"],\"name\":\"brand abc\",\"brandType\":\"all\"}}}");

  Request request = new Request.Builder()
    .url("https://api.criteo.com/2025-07/retail-media/brands/search?offset=0&limit=25")
    .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/2025-07/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 <MY_ACCESS_TOKEN>'
  ));
  $request->setBody('{"data":{"type":"<string>","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();
  }
  ```
</CodeGroup>

### Sample Response

For *Brand Search*:

```json 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": []
}
```

***

## Partner Billing Report

In version `2025.07`, we've introduced the **Partner Billing Report (PBR) endpoints** which enable 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.

<Info>
  You can find the Partner Billing Report documentation [here](/retail-media/docs/partner-billing-report).
</Info>

***

### Updated Endpoints Include

The following new catalog endpoint can be found below:

<table>
  <thead>
    <tr>
      <th>
        <p>
          Verb
        </p>
      </th>

      <th>
        <p>
          Endpoint
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /billing/partner-report
          </code>
        </p>
      </td>

      <td>
        <p>
          Request a partner billing report creation
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            GET
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /billing/partner-report/\{reportId}/status
          </code>
        </p>
      </td>

      <td>
        <p>
          Get status of a specific report
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            GET
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /billing/partner-report/\{reportId}/output
          </code>
        </p>
      </td>

      <td>
        <p>
          Download output of a specific report
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Sample Request

For `/billing/partner-report`:

<CodeGroup>
  ```text Text theme={null}
  https://api.criteo.com/2025-07/retail-media/billing/partner-report
  ```

  ```bash cURL theme={null}
  curl -L -X POST 'https://api.criteo.com/2025-07/retail-media/billing/partner-report' \
      -H 'Content-Type: application/json' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
      -d '{
              "data": {
                  "type": "<string>",
                  "attributes": {
                      "accountIds": [
                          "4257354444567401216"
                      ],
                      "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/2025-07/retail-media/billing/partner-report"

  payload = json.dumps({
      "data": {
          "type": "<string>",
          "attributes": {
              "accountIds": [
                  "4257354444567401216"
              ],
              "retailerIds": [
                  "1234",
                  "5678"
              ],
              "startDate": "2025-01-01",
              "endDate": "2025-01-31",
              "format": "json"
          }
      }
  })
  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, "{\"data\":{\"type\":\"<string>\",\"attributes\":{\"accountIds\":[\"4257354444567401216\"],\"retailerIds\":[\"1234\",\"5678\"],\"startDate\":\"2025-01-01\",\"endDate\":\"2025-01-31\",\"format\":\"json\"}}}");

  Request request = new Request.Builder()
    .url("https://api.criteo.com/2025-07/retail-media/billing/partner-report")
    .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/2025-07/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 <MY_ACCESS_TOKEN>'
  ));
  $request->setBody('{"data":{"type":"<string>","attributes":{"accountIds":["4257354444567401216"],"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();
  }
  ```
</CodeGroup>

***

### Sample Response

For `/billing/partner-report`:

```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": []
}
```

***

### Sample Request

For `/billing/partner-report/{reportId}/status`:

<CodeGroup>
  ```text Text theme={null}
  https://api.criteo.com/2025-07/retail-media/billing/partner-report/{reportId}/status
  ```

  ```bash cURL theme={null}
  curl -L 'https://api.criteo.com/2025-07/retail-media/billing/partner-report/c19ed799-6747-4815-aa09-d3e04898xxxx/status' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer <MY_ACCESS_TOKEN>'
  ```
</CodeGroup>

### Sample Response

For `/billing/partner-report/{reportId}/status`:

```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": []
}
```

***

### Sample Request

For `/billing/partner-report/{reportId}/output`:

Once the report creation is completed (`"status": "success"` in response above), the report output will be available to download in this endpoint.

```text theme={null}
https://api.criteo.com/2025-07/retail-media/billing/partner-report/{reportId}/output
```

### Sample Response

For `/billing/partner-report/{reportId}/output`:

```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": 0.0000000,
        "RetailerManagedFeeRate": 0.0,
        "RetailerManagedFeeAmount": 0.0,
        "RetailerAudienceDataFeeAmount": null,
        "CriteoRetailerDataFeeAmount": null,
        "UtcOffset": "-05:00"
    },
    // ...
    {
        "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": 0.00000000,
        "RetailerManagedFeeRate": 0.0,
        "RetailerManagedFeeAmount": 0.0,
        "RetailerAudienceDataFeeAmount": null,
        "CriteoRetailerDataFeeAmount": null,
        "UtcOffset": "-05:00"
    }
]
```

***

## New Reporting Dimensions & Filters

In version 2025.07, we've introduced **new reporting dimensions & filters** within the analytics endpoints.

The updated analytics endpoints provide users with deeper, more comprehensive insights, enabling them to explore data more effectively. Additionally, the introduction of new report types empowers users to make more informed, data-driven decisions by offering tailored, actionable insights that better align with your strategic goals.

In the latest version, you now have the flexibility to generate reporting with a focus on **Media Type**  to allow users to more precisely identify performance against Display or Video.  The Media Type dimension is **available across the DSP & SSP endpoints** and is available not only as a dimension but a filter as well.

There are also new filters with a focus on **Attribution** designed to provide deeper insights into our performance according to the **click match level and view match level** for post-click and post-impression attribution levels.  These metrics are available in **the SSP API only**.

***

### Updated Endpoints Includes

The following new reporting changes apply for both the asynchronous campaign and line-item endpoints for report generation:

<table>
  <thead>
    <tr>
      <th>
        <p>
          Verb
        </p>
      </th>

      <th>
        <p>
          Endpoint
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /reports/campaigns
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a Campaign Report Request
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /reports/line-items
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a Line Item Report Request
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            POST
          </b>
        </p>
      </td>

      <td>
        <p>
          <code>
            /reports/revenue
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a Revenue Report Request
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Sample Request with `mediaType` Attribute & Dimension

For *Campaign Report*:

<CodeGroup>
  ```bash cURL expandable theme={null}
  curl --location 'https://api.criteo.com/2025-07/retail-media/reports/campaigns' \
  --header 'Content-Type: application/json' \
  --header 'Accept: text/plain' \
  --header 'Authorization: Bearer ****' \
  --data '{
    "data": {
      "attributes": {
        "endDate": "2025-04-22",
        "startDate": "2025-04-01",
        "campaignType": "all",
        "clickAttributionWindow": "none",
        "dimensions": [
          "campaignName",
          "campaignId",
  				"mediaType"
        ],
        "format": "csv",
        "id": "1234",
        "metrics": [
          "impressions",
          "clicks",
          "winRate"
        ],
        "reportType": "summary",
        "salesChannel": "all",
  			"mediaType": "all"
        "timezone": "UTC",
        "viewAttributionWindow": "none"
      },
      "type": "AsyncCampaignsReportRequest"
    }
  }'
  ```

  ```python Python expandable theme={null}
  import http.client
  import json

  conn = http.client.HTTPSConnection('api.criteo.com')
  headers = {
      'Content-Type': 'application/json',
      'Accept': 'text/plain',
      'Authorization': '••••••',
  }
  json_data = {
      'data': {
          'attributes': {
              'endDate': '2025-03-31',
              'startDate': '2025-03-01',
              'accountIds': [
                  '1234',
              ],
              'advertiserTypes': [
                  'brand',
                  'seller',
              ],
              'buyType': 'auction',
              'campaignIds': [
                  '123',
              ],
              'campaignType': 'all',
              'clickAttributionWindow': 'none',
              'clickMatchLevel': 'campaign',
              'dimensions': [
                  'retailerCategoryName',
                  'brandId',
              ],
              'format': 'json',
              'id': '1234567890',
              'lineItemIds': [
                  '12345',
              ],
              'metrics': [
                  'impressions',
                  'roas',
              ],
              'retailerIds': [
                  '111',
              ],
              'revenueType': 'auction',
              'salesChannel': 'all',
              'skuRelations': [
                  'sameBrand',
                  'sameCategory',
              ],
              'soldBy': 'directSold',
              'timezone': 'UTC',
              'viewAttributionWindow': 'none',
              'viewMatchLevel': 'campaign',
          },
          'type': 'RevenueReportRequest',
      },
  }
  conn.request(
      'POST',
      '/2025-07/retail-media/reports/revenue',
      json.dumps(json_data),
      headers
  )
  response = conn.getresponse()
  ```

  ```java Java theme={null}
  import java.io.IOException;
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpRequest.BodyPublishers;
  import java.net.http.HttpResponse;

  HttpClient client = HttpClient.newBuilder()
      .followRedirects(HttpClient.Redirect.NORMAL)
      .build();

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.criteo.com/2025-07/retail-media/reports/campaigns"))
      .POST(BodyPublishers.ofString("{\n  \"data\": {\n    \"attributes\": {\n      \"endDate\": \"2025-04-22\",\n      \"startDate\": \"2025-04-01\",\n      \"campaignType\": \"all\",\n      \"clickAttributionWindow\": \"none\",\n      \"dimensions\": [\n        \"campaignName\",\n        \"campaignId\",\n\t\t\t\t\"mediaType\"\n      ],\n      \"format\": \"csv\",\n      \"id\": \"1234\",\n      \"metrics\": [\n        \"impressions\",\n        \"clicks\",\n        \"winRate\"\n      ],\n      \"reportType\": \"summary\",\n      \"salesChannel\": \"all\",\n\t\t\t\"mediaType\": \"all\"\n      \"timezone\": \"UTC\",\n      \"viewAttributionWindow\": \"none\"\n    },\n    \"type\": \"AsyncCampaignsReportRequest\"\n  }\n}"))
      .setHeader("Content-Type", "application/json")
      .setHeader("Accept", "text/plain")
      .setHeader("Authorization", "Bearer ****")
      .build();

  HttpResponse&lt;String&gt; response = client.send(request, HttpResponse.BodyHandlers.ofString());
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.criteo.com/2025-07/retail-media/reports/campaigns');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Content-Type: application/json',
      'Accept: text/plain',
      'Authorization: Bearer ****',
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, "{\n  \"data\": {\n    \"attributes\": {\n      \"endDate\": \"2025-04-22\",\n      \"startDate\": \"2025-04-01\",\n      \"campaignType\": \"all\",\n      \"clickAttributionWindow\": \"none\",\n      \"dimensions\": [\n        \"campaignName\",\n        \"campaignId\",\n\t\t\t\t\"mediaType\"\n      ],\n      \"format\": \"csv\",\n      \"id\": \"1234\",\n      \"metrics\": [\n        \"impressions\",\n        \"clicks\",\n        \"winRate\"\n      ],\n      \"reportType\": \"summary\",\n      \"salesChannel\": \"all\",\n\t\t\t\"mediaType\": \"all\"\n      \"timezone\": \"UTC\",\n      \"viewAttributionWindow\": \"none\"\n    },\n    \"type\": \"AsyncCampaignsReportRequest\"\n  }\n}");
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

  curl_close($ch);
  ```
</CodeGroup>

***

### Sample Request with `clickMatchLevel` and `viewMatchLevel` Attributes

For*Revenue Report*:

<CodeGroup>
  ```bash cURL expandable theme={null}
  curl --location 'https://api.criteo.com/2025-07/retail-media/reports/revenue' \
  --header 'Content-Type: application/json' \
  --header 'Accept: text/plain' \
  --header 'Authorization: ••••••' \
  --data '{
    "data": {
      "attributes": {
        "endDate": "2025-03-31",
        "startDate": "2025-03-01",
        "accountIds": [
          "1234"
        ],
        "advertiserTypes": [
          "brand",
          "seller"
        ],
        "buyType": "auction",
        "campaignIds": [
          "123"
        ],
        "campaignType": "all",
        "clickAttributionWindow": "none",
        "clickMatchLevel": "campaign",
        "dimensions": [
          "retailerCategoryName",
          "brandId"
        ],
        "format": "json",
        "id": "1234567890",
        "lineItemIds": [
          "12345"
        ],
        "metrics": [
          "impressions",
          "roas"
        ],
        "retailerIds": [
          "111"
        ],
        "revenueType": "auction",
        "salesChannel": "all",
        "skuRelations": [
          "sameBrand",
          "sameCategory"
        ],
        "soldBy": "directSold",
        "timezone": "UTC",
        "viewAttributionWindow": "none",
        "viewMatchLevel": "campaign"
      },
      "type": "RevenueReportRequest"
    }
  }'
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection('api.criteo.com')
  headers = {
      'Content-Type': 'application/json',
      'Accept': 'text/plain',
      'Authorization': 'Bearer ****',
  }
  conn.request(
      'POST',
      '/2025-07/retail-media/reports/campaigns',
      '{\n  "data": {\n    "attributes": {\n      "endDate": "2025-04-22",\n      "startDate": "2025-04-01",\n      "campaignType": "all",\n      "clickAttributionWindow": "none",\n      "dimensions": [\n        "campaignName",\n        "campaignId",\n\t\t\t\t"mediaType"\n      ],\n      "format": "csv",\n      "id": "1234",\n      "metrics": [\n        "impressions",\n        "clicks",\n        "winRate"\n      ],\n      "reportType": "summary",\n      "salesChannel": "all",\n\t\t\t"mediaType": "all"\n      "timezone": "UTC",\n      "viewAttributionWindow": "none"\n    },\n    "type": "AsyncCampaignsReportRequest"\n  }\n}',
      headers
  )
  response = conn.getresponse()
  ```

  ```java Java theme={null}
  import java.io.IOException;
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpRequest.BodyPublishers;
  import java.net.http.HttpResponse;

  HttpClient client = HttpClient.newBuilder()
      .followRedirects(HttpClient.Redirect.NORMAL)
      .build();

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.criteo.com/2025-07/retail-media/reports/revenue"))
      .POST(BodyPublishers.ofString("{\n  \"data\": {\n    \"attributes\": {\n      \"endDate\": \"2025-03-31\",\n      \"startDate\": \"2025-03-01\",\n      \"accountIds\": [\n        \"1234\"\n      ],\n      \"advertiserTypes\": [\n        \"brand\",\n        \"seller\"\n      ],\n      \"buyType\": \"auction\",\n      \"campaignIds\": [\n        \"123\"\n      ],\n      \"campaignType\": \"all\",\n      \"clickAttributionWindow\": \"none\",\n      \"clickMatchLevel\": \"campaign\",\n      \"dimensions\": [\n        \"retailerCategoryName\",\n        \"brandId\"\n      ],\n      \"format\": \"json\",\n      \"id\": \"1234567890\",\n      \"lineItemIds\": [\n        \"12345\"\n      ],\n      \"metrics\": [\n        \"impressions\",\n        \"roas\"\n      ],\n      \"retailerIds\": [\n        \"111\"\n      ],\n      \"revenueType\": \"auction\",\n      \"salesChannel\": \"all\",\n      \"skuRelations\": [\n        \"sameBrand\",\n        \"sameCategory\"\n      ],\n      \"soldBy\": \"directSold\",\n      \"timezone\": \"UTC\",\n      \"viewAttributionWindow\": \"none\",\n      \"viewMatchLevel\": \"campaign\"\n    },\n    \"type\": \"RevenueReportRequest\"\n  }\n}"))
      .setHeader("Content-Type", "application/json")
      .setHeader("Accept", "text/plain")
      .setHeader("Authorization", "••••••")
      .build();

  HttpResponse&lt;String&gt; response = client.send(request, HttpResponse.BodyHandlers.ofString());
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.criteo.com/2025-07/retail-media/reports/revenue');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Content-Type: application/json',
      'Accept: text/plain',
      "Authorization: ••••••",
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, "{\n  \"data\": {\n    \"attributes\": {\n      \"endDate\": \"2025-03-31\",\n      \"startDate\": \"2025-03-01\",\n      \"accountIds\": [\n        \"1234\"\n      ],\n      \"advertiserTypes\": [\n        \"brand\",\n        \"seller\"\n      ],\n      \"buyType\": \"auction\",\n      \"campaignIds\": [\n        \"123\"\n      ],\n      \"campaignType\": \"all\",\n      \"clickAttributionWindow\": \"none\",\n      \"clickMatchLevel\": \"campaign\",\n      \"dimensions\": [\n        \"retailerCategoryName\",\n        \"brandId\"\n      ],\n      \"format\": \"json\",\n      \"id\": \"1234567890\",\n      \"lineItemIds\": [\n        \"12345\"\n      ],\n      \"metrics\": [\n        \"impressions\",\n        \"roas\"\n      ],\n      \"retailerIds\": [\n        \"111\"\n      ],\n      \"revenueType\": \"auction\",\n      \"salesChannel\": \"all\",\n      \"skuRelations\": [\n        \"sameBrand\",\n        \"sameCategory\"\n      ],\n      \"soldBy\": \"directSold\",\n      \"timezone\": \"UTC\",\n      \"viewAttributionWindow\": \"none\",\n      \"viewMatchLevel\": \"campaign\"\n    },\n    \"type\": \"RevenueReportRequest\"\n  }\n}");
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

  curl_close($ch);
  ```
</CodeGroup>
