> ## 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.10 Release Notes

<Info>
  Version **`2025.10`** of the Criteo Retail Media API is live as of **October 21st, 2025** and will be supported until **October 27th, 2026**.  A new Postman collection for `2025.10` 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.10` 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.10` are:

* a new **base URL**,
* updated **API Troubleshooting Guides**,
* updates to **Authorization Code** application rate limiting,
* updates to endpoints according to **Retailer Configuration**,
* new endpoints in that of **recommend keywords & categories** that support Sponsored Products & Display,
* new endpoints for **Category Search** to increase efficiency,
* new **Account Fees** endpoints to support Retailers,
* an update to the  **keyword bid** endpoint,
* updates to **the Reporting Cache, Report Types, & dimensions**  within the analytics endpoints, and
* changes coming to the **catalog** endpoints in 2026.

***

# 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-07/retail-media/{endpoint}
```

to the **new base URL**:

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

***

# What's New

## API Troubleshooting Guides

We’re pleased to introduce a new set of API Troubleshooting resources designed to help you efficiently identify and resolve API-related issues. The following pages offer detailed guidance and descriptions:

* The [Troubleshooting Guide](/retail-media/docs/api-troubleshooting-guide#/) offers users a concise, structured approach to diagnosing API issues by walking through common error scenarios and checks (e.g. connectivity, request format, server vs client).
* The [Escalation Guidelines](/retail-media/docs/escalation-guidelines#/) aims to guide users on when and how to escalate API issues to Criteo—defining the thresholds, required information, and escalation paths to streamline support.
* The [API Error Codes](/retail-media/docs/api-error-codes#/) page explains the various API error codes that developers might encounter—providing both the numeric/identifier codes and descriptive messages. It helps developers interpret responses from the API accurately and take the appropriate corrective action.

***

## Authorization Code Rate Limiting

We've introduced an updated logic to rate limiting on Authorization Code applications, which focuses on the below:

* The new capability is **Auto Scaling**, and this capability is exclusively for Auth Code apps, not Client Credentials.
* **Accounts** will have a rate limit of 10 calls per minute *per account*.  The number of accounts consented to is also taken into account, which means that the rate limit can increase according to the amount of accounts a single consent granter gave an application consent to.  For example:
  * **Bob** consented to **account 1,2,3** -> the app can call "in the name of Bob" at max rate of 3\*10=**30calls/min**
    * Bob would have the ability to use all 30 calls on a single account, but that would impact their ability to call other accounts.
  * **Alice** consented to **account 4** but **Jen** consented to **account 5** -> the app can call "in the name of Alice" at a max rate of 1\_10=10 calls/min and can call "in the name of Jen" at a max rate of 1\_10=10 calls/min.
* **Consent granters** and **application owners** are encouraged to have similar consenters grant consent to accounts to scale the rate limit according to the operations expected on the accounts.

<Info>
  You can find the documentation for the update to Authorization Code rate limits [here](/retail-media/docs/rate-limits).
</Info>

***

## Retailer Configuration Updates

We've introduced an updated logic to the governance layer that determines which parts of a retailer’s inventory (campaign types such as Sponsored Products and buy types such as Auction) are accessible through different demand entry points.  This means that in the event that a retailer opts out of receiving demand from Commerce Max, the following will take place:

* The ability to run **create or edit** operations will be impacted, and a validation error can be expected should a retailer opt out of receiving Commerce Max demand.
* The ability to run **read only** operations will remain unimpacted, as there may be line items that are existing against retailer inventory that may need to be accessed.  Users who want to fetch information against impacted campaigns/line items can expect to still be able to access information associated to these campaigns/line items and still pull reporting for them as well.

***

## Recommended Keywords

In version `2025.10`, we've introduced new endpoints that are used by advertisers & retailers to fetch recommended keywords that are desired to be used for targeting on retailer inventory.

You may be wondering how this is different from the `/retail-media/line-items/:externalLineItemId/keywords/recommended` and it would be a fair question.  The key difference is that the endpoint referenced only indicates recommended keywords *after* they have bee added to a line item.  In the new iteration, advertisers & retailers will have the ability to input `product IDs`, and the endpoint will analyze your products and return the top 100 keywords that your Sponsored Product and/or Onsite Display line items would serve on when shoppers search for related terms.

This means that you will have the ability to preview what the targeting would be *before* a product is added to a line item. This data-driven approach ensures your campaigns target the most effective keywords based on actual search behavior and product relevance.

<Info>
  You can find the documentation for the Recommended Keywords endpoint [here](/retail-media/docs/recommended-keywords#/).
</Info>

***

### Updated Endpoints

The following new 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>
            /retail-media/retailers/:retailerId/recommend-keywords
          </code>
        </p>
      </td>

      <td>
        <p>
          Gets the top 100 recommended keywords for specified products
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Sample Request

For `/retail-media/retailers/:retailerId/recommend-keywords`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X POST "https://api.criteo.com/2025-10/retail-media/retailers/{retailerId}/recommend-keywords" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
  ```

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

  headers = {
      'Authorization': 'Bearer <MY_ACCESS_TOKEN>',
  }

  response = requests.post(
      'https://api.criteo.com/preview/retail-media/retailers/{retailerId}/recommend-keywords',
      headers=headers,
  )
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.criteo.com/preview/retail-media/retailers/{retailerId}/recommend-keywords');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer <MY_ACCESS_TOKEN>',
  ]);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

  curl_close($ch);
  ```

  ```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.HttpResponse;

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

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.criteo.com/preview/retail-media/retailers/{retailerId}/recommend-keywords"))
      .GET()
      .setHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
      .build();

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

### Sample Response

For `/retail-media/retailers/:retailerId/recommend-keywords`:

```json theme={null}
{
    "data": {
        "type": "RecommendedKeywordsResponseV1",
        "attributes": {
            "recommendedKeywords": [
                "keyword 1",
                "keyword 2",
                "keyword 3",
                "keyword 4",
                "keyword 5"
            ]
        }
    },
    "warnings": [],
    "errors": []
}
```

***

## Recommended Categories

In version `2025.10`, we've introduced new endpoints that are used by advertisers & retailers to fetch recommended categories that are desired to be used for targeting on retailer inventory.

The Recommended Categories endpoint helps you discover the most relevant product categories for your advertising campaigns by leveraging a retailer's taxonomy structure. This endpoint analyzes your specified products and returns up to 50 recommended categories that align with where your products naturally fit within the retailer's inventory organization.

<Info>
  You can find the documentation for the Recommended Categories endpoint [here](/retail-media/docs/recommended-categories#/).
</Info>

***

### Updated Endpoints

The following new 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>
            /retail-media/retailers/:retailerId/recommend-categories
          </code>
        </p>
      </td>

      <td>
        <p>
          Gets the top 50 recommended categories for specified products
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Sample Request

For `retail-media/retailers/:retailerId/recommend-categories`:

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X POST "https://api.criteo.com/2025-10/retail-media/retailers/{retailerId}/recommend-categories" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
  ```

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

  headers = {
      'Authorization': 'Bearer <MY_ACCESS_TOKEN>',
  }

  response = requests.post('https://api.criteo.com/preview/retail-media/retailers/100/recommend-categories', headers=headers)
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.criteo.com/preview/retail-media/retailers/100/recommend-categories');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer <MY_ACCESS_TOKEN>',
  ]);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

  curl_close($ch);
  ```

  ```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.HttpResponse;

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

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.criteo.com/preview/retail-media/retailers/100/recommend-categories"))
      .GET()
      .setHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
      .build();

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

### Sample Response

For `retail-media/retailers/:retailerId/recommend-categories`:

```json theme={null}
{
    "data": [
        {
            "id": "12345",
            "type": "CategoryV1",
            "attributes": {
                "text": "taxonmy 1|taxonomy 2|taxobnomy 3",
                "name": "taxonomy 3",
                "parentId": "12"
            }
        },
        {
            "id": "67890",
            "type": "CategoryV1",
            "attributes": {
                "text": "taxonmy 1|taxonomy 2|taxobnomy 3",
                "name": "taxonomy 3",
                "parentId": "12"
            }
        }
        }
    ],
    "warnings": [],
    "errors": []
}
```

***

## Category Search

In version `2025.10`, we've introduced new Category Search endpoint enables you to explore and discover available product categories within a retailer's hierarchical taxonomy structure.

This endpoint provides the ability to see what categories are available to serve against a retailer's inventory, making it an essential tool for understanding targeting options and campaign planning. Unlike recommendation endpoints, Category Search allows you to actively explore the retailer's category structure through flexible search parameters.

<Info>
  You can find the Category Search endpoint documentation [here](/retail-media/docs/category-search#/).
</Info>

***

### Updated Endpoints

The following new 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>
            /retail-media/retailers/:retailerId/categories/search
          </code>
        </p>
      </td>

      <td>
        <p>
          Searches for available categories within a retailer's taxonomy
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Sample Request

For `/retail-media/retailers/:retailerId/categories/search`:

<br />

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X POST "https://api.criteo.com/2025-10/retail-media/retailers/{retailerId}/categories/search?limit=50&offset=0" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
  ```

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

  headers = {
      'Authorization': 'Bearer <MY_ACCESS_TOKEN>',
  }

  params = {
      'limit': '50',
      'offset': '0',
  }

  response = requests.post(
      'https://api.criteo.com/2025-10/retail-media/retailers/{retailerId}/categories/search',
      params=params,
      headers=headers,
  )
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.criteo.com/2025-10/retail-media/retailers/{retailerId}/categories/search?limit=50&offset=0');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer <MY_ACCESS_TOKEN>',
  ]);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

  curl_close($ch);
  ```

  ```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.HttpResponse;

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

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.criteo.com/2025-10/retail-media/retailers/{retailerId}/categories/search?limit=50&offset=0"))
      .POST(HttpRequest.BodyPublishers.noBody())
      .setHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
      .build();

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

### Sample Response

For `/retail-media/retailers/:retailerId/categories/search`:

```json theme={null}
{
    "metadata": {
        "count": 2,
        "offset": 0,
        "limit": 50
    },
    "data": [
        {
            "id": "12345",
            "type": "CategoryV1",
            "attributes": {
                "text": "taxonmy 1|taxonomy 2|taxobnomy 3",
                "name": "taxobnomy 3",
                "parentId": "12"
            }
        },
        {
            "id": "67890",
            "type": "CategoryV1",
            "attributes": {
                "text": "taxonmy 1|taxonomy 2|taxobnomy 3",
                "name": "taxobnomy 3",
                "parentId": "12"
            }
        }
        }
    ],
    "warnings": [],
    "errors": []
}
```

<Warning>
  NOTE

  The addition of the Category Search endpoints will prompt the removal of some existing endpoints in this stable version release as well as future versions due to redundancy since the new endpoint achieves what the below endpoints aim to accomplish:
</Warning>

**Endpoints to be removed:**

<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/categories/:categoryId
          </code>
        </p>
      </td>

      <td>
        <p>
          Get categories of the retailer by specific category Id
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/categories
          </code>
        </p>
      </td>

      <td>
        <p>
          Get all categories of the retailer
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

## Account Fees

In version `2025.10`, we've introduced **new account fees endpoints** that offer Private Marketplace retailers the ability to search and manage fees for one of more accounts.

<Info>
  You can find the Account Fees endpoint documentation [here](/retail-media/docs/account-fees#/).
</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>
            /retail-media/accounts/fees/search
          </code>
        </p>
      </td>

      <td>
        <p>
          This endpoint allows users to retrieve fee settings for one or more accounts they have access to.
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/accounts/fees/update
          </code>
        </p>
      </td>

      <td>
        <p>
          This endpoint allows Private Market retailers to update fees for child seller or demand accounts.
        </p>
      </td>
    </tr>
  </tbody>
</table>

### Sample Request

For *Account Fees Search*:

<CodeGroup>
  ```bash cURL theme={null}
  curl --location 'https://api.criteo.com/2025-10/retail-media/accounts/fees/search?limit=50&offset=0' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Authorization: ••••••' \
  --data '{
    "data": {
      "attributes": {
        "accountIds": [
          "123",
          "456"
        ]
      },
      "type": "AccountFeesSearchRequest"
    }
  }'
  ```

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

  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': '••••••',
  }

  params = {
      'limit': '50',
      'offset': '0',
  }

  json_data = {
      'data': {
          'attributes': {
              'accountIds': [
                  '123',
                  '456',
              ],
          },
          'type': 'AccountFeesSearchRequest',
      },
  }

  response = requests.post(
      'https://api.criteo.com/2025-10/retail-media/accounts/fees/search',
      params=params,
      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-10/retail-media/accounts/fees/search?limit=50&offset=0"))
      .POST(BodyPublishers.ofString("{\n  \"data\": {\n    \"attributes\": {\n      \"accountIds\": [\n        \"123\",\n        \"456\"\n      ]\n    },\n    \"type\": \"AccountFeesSearchRequest\"\n  }\n}"))
      .setHeader("Content-Type", "application/json")
      .setHeader("Accept", "application/json")
      .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-10/retail-media/accounts/fees/search?limit=50&offset=0');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Content-Type: application/json',
      'Accept: application/json',
      "Authorization: ••••••",
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, "{\n  \"data\": {\n    \"attributes\": {\n      \"accountIds\": [\n        \"123\",\n        \"456\"\n      ]\n    },\n    \"type\": \"AccountFeesSearchRequest\"\n  }\n}");
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

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

### Sample Response

For *Account Fees Search*:

```json JSON expandable theme={null}
{
    "metadata": {
        "count": 2,
        "offset": 0,
        "limit": 50
    },
    "data": [
        {
            "type": "PrivateMarketAccountFees",
            "attributes": {
                "accountId": "123",
                "fees": {
                    "demandManaged": {
                        "rate": 0.01
                    },
                    "managedService": {
                        "rate": 0.01,
                        "onsiteSponsoredProductsEnabled": true,
                        "onsiteDisplayEnabled": true
                    }
                }
            }
        },
        {
            "type": "PrivateMarketAccountFees",
            "attributes": {
                "accountId": "456",
                "fees": {
                    "demandManaged": {
                        "rate": 0.00
                    },
                    "managedService": {
                        "rate": 0.00,
                        "onsiteSponsoredProductsEnabled": false,
                        "onsiteDisplayEnabled": false
                    }
                }
            }
        }
    ],
    "warnings": [],
    "errors": []
}
```

### Sample Request

For *Updating Account Fees*:

<CodeGroup>
  ```bash cURL theme={null}
  curl --location 'https://api.criteo.com/2025-10/retail-media/accounts/fees/update' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: ••••••' \
  --data '{
    "data": {
      "attributes": {
        "accountIds": [
          "123"
        ],
        "fees": {
          "demandManaged": {
            "rate": "0.1"
          },
          "managedService": {
            "onsiteDisplayEnabled": "true",
            "onsiteSponsoredProductsEnabled": "true",
            "rate": "0.1"
          }
        }
      },
      "type": "AccountFeesUpdateRequest"
    }
  }'
  ```

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

  headers = {
      'Content-Type': 'application/json',
      'Authorization': '••••••',
  }

  json_data = {
      'data': {
          'attributes': {
              'accountIds': [
                  '123',
              ],
              'fees': {
                  'demandManaged': {
                      'rate': '0.1',
                  },
                  'managedService': {
                      'onsiteDisplayEnabled': 'true',
                      'onsiteSponsoredProductsEnabled': 'true',
                      'rate': '0.1',
                  },
              },
          },
          'type': 'AccountFeesUpdateRequest',
      },
  }

  response = requests.post('https://api.criteo.com/2025-10/retail-media/accounts/fees/update', 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-10/retail-media/accounts/fees/update"))
      .POST(BodyPublishers.ofString("{\n  \"data\": {\n    \"attributes\": {\n      \"accountIds\": [\n        \"123\"\n      ],\n      \"fees\": {\n        \"demandManaged\": {\n          \"rate\": \"0.1\"\n        },\n        \"managedService\": {\n          \"onsiteDisplayEnabled\": \"true\",\n          \"onsiteSponsoredProductsEnabled\": \"true\",\n          \"rate\": \"0.1\"\n        }\n      }\n    },\n    \"type\": \"AccountFeesUpdateRequest\"\n  }\n}"))
      .setHeader("Content-Type", "application/json")
      .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-10/retail-media/accounts/fees/update');
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Content-Type: application/json',
      "Authorization: ••••••",
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, "{\n  \"data\": {\n    \"attributes\": {\n      \"accountIds\": [\n        \"123\"\n      ],\n      \"fees\": {\n        \"demandManaged\": {\n          \"rate\": \"0.1\"\n        },\n        \"managedService\": {\n          \"onsiteDisplayEnabled\": \"true\",\n          \"onsiteSponsoredProductsEnabled\": \"true\",\n          \"rate\": \"0.1\"\n        }\n      }\n    },\n    \"type\": \"AccountFeesUpdateRequest\"\n  }\n}");
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

  $response = curl_exec($ch);

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

### Sample Response

For *Updating Account Fees*:

<Warning>
  NOTE

  A successful response on the `Update Account Fees` endpoint will result in an empty `204` response.
</Warning>

***

## Keyword Bid Endpoint Update

In version `2025.10`, we have made updates to our keyword bidding endpoints to enhance the keyword targeting experience.

Originally, keyword bid overrides used to only be able to be applied to *manually targeted* keywords.  Now, users will have the ability to apply keyword bid overrides on not only manually targeted keywords but also *automatically targeted* keywords that have been derived from our keyword relevancy model.  The functionality of the impacted endpoints remains the same, the difference will be that when you attempt to apply a keyword bid to an automatically targeted keyword, you will now receive a successful response.

<Info>
  You can find the Keyword Bid endpoint documentation [here](/retail-media/docs/keywords#/).
</Info>

***

### Updated Endpoints

See below for the impacted endpoints:

**Impacted Endpoint:**

<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>
            /retail-media/line-items/\{lineItemId}/keywords/set-bid
          </code>
        </p>
      </td>

      <td>
        <p>
          Set a bid override at keyword level
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

## New Reporting Dimensions & Filters

In version `2025.10`, we've introduced **updates to the Reporting cache as well as updates to existing Report Types** within the analytics endpoints.

The reporting cache behavior has been improved to take steps towards enhancing performance and consistency:

* While reports with an end date equal to the current date have been cached for **1 hour**,
* Reports with an end date earlier than the current date are cached for **24 hours**.

This update ensures faster response times for commonly requested reports while maintaining data accuracy for current-date reporting.

The updated analytics endpoints provide users with deeper, more comprehensive insights, enabling them to explore data more effectively. Additionally, the enhancements to the 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, there have been updates to the **capout report type**.  Now, the **`capoutMissedTraffic`** dimension has had it's calculation updated to align with the support of the release of the Adaptive CPC launch in Preview.  It is now defined as *the percent of traffic events that the advertiser did not participate in throughout the day, weighted based on the number of traffic events throughout the day*.

You also now have the flexibility to generate reporting with a focus on the **advertised Product Category**  dimension to more precisely identify the category the advertised product is associated to.

Lastly, we have added new dimensions to the **Attributed Transactions** report.  The following dimensions can now be found when calling for the `reportType`:

<table>
  <thead>
    <tr>
      <th>
        <p>
          Key-Values
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <b>
            <code>
              saleSellerId
            </code>
          </b>
        </p>
      </td>

      <td>
        <p>
          The ID of the seller responsible for the sale
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            <code>
              saleSellerName
            </code>
          </b>
        </p>
      </td>

      <td>
        <p>
          The name of the seller responsible for the sale
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            <code>
              activitySellerId
            </code>
          </b>
        </p>
      </td>

      <td>
        <p>
          The ID of the seller responsible for the advertising event
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <b>
            <code>
              activitySellerName
            </code>
          </b>
        </p>
      </td>

      <td>
        <p>
          The name of the seller responsible for the advertising event
        </p>
      </td>
    </tr>
  </tbody>
</table>

These Report Types & dimensions are **available across the DSP endpoints**.

### 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>
            /retail-media/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>
  </tbody>
</table>

***

## Updates To Catalog Endpoints in 2026

With the release of the Catalog Export endpoints in version `2025-07`, we want to provide an early announcement that older versions of the catalog endpoints will no longer be released in stable versions scheduled for release after the second half of 2026.

This change reflects our commitment to providing a more flexible and user-friendly API experience. The new endpoint versions offer enhanced functionality and usability, making the older versions redundant.

See below for the impacted endpoints:

**Impacted Endpoints (in 2H 2026):**

<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>
            /retail-media/accounts/:accountId/catalogs
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a catalog request to generate a new catalog for Brand account
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/accounts/:accountId/catalogs/sellers
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a catalog request to generate a new catalog for Seller account
        </p>
      </td>
    </tr>
  </tbody>
</table>

We ask that you begin migration to the below endpoints:

<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>
  </tbody>
</table>
