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

# Account Fees (Private Market)

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

# Introduction

The **Account Fees API** allows Private Market retailers to manage fee settings for their accounts through the external API.\
This includes retrieving fees for one or more accounts and updating those fees where permitted.

***

# 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/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>
            /accounts/fees/update
          </code>
        </p>
      </td>

      <td>
        <p>
          This endpoint allows

          <b>
            Private Market retailers
          </b>

          to update fees for child seller or demand accounts.
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

## Search Account Fees

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/{version}/retail-media/accounts/fees/search
  ```
</EndpointBadge>

This endpoint allows users to retrieve fee settings for one or more accounts they have access to.

You can find more details in the API reference for this endpoint [here](/retail-media/v2025.10/reference/accounts/account-fees-search).

<Info>
  This endpoint does not require `Account Manage` scope nor consent to the parent supply account.
</Info>

***

## Attributes

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

      <th>
        <p>
          Data Type
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <code>
            accountIds
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            list
          </code>
        </p>
      </td>

      <td>
        <p>
          Account ID
        </p>

        <p>
          Up to

          <b>
            25 account IDs
          </b>

          can be queried at once.
        </p>

        <p>
          Accepted values: string of

          <code>
            int64
          </code>
        </p>

        <p>
          Writeable: Y/ Nullable: N
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Optional Query Parameters

<table>
  <thead>
    <tr>
      <th>
        <p>
          Query Parameters
        </p>
      </th>

      <th>
        <p>
          Data Type
        </p>
      </th>

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

  <tbody>
    <tr>
      <td>
        <p>
          <code>
            offsite
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            integer
          </code>
        </p>
      </td>

      <td>
        <p>
          Pagination parameter, see <a href="/retail-media/docs/api-response">API Response</a>
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            limit
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            integer
          </code>
        </p>
      </td>

      <td>
        <p>
          Pagination parameter, see <a href="/retail-media/docs/api-response">API Response</a>
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            fields
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            list
          </code>
        </p>
      </td>

      <td>
        <p>
          Comma-separated list of optional attributes to include in the response.
        </p>

        <p>
          Used to optimize response time and payload length.
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Sample request

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X POST "https://api.criteo.com/{version}/retail-media/accounts/fees/search" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
          "data": {
              "attributes": {
                  "accountIds": [
                      "667131474078658560",
                      "680116036401160192"
                  ]
              },
              "type": "AccountFeesSearchRequest"
          }
      }'

  ```

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

  conn = http.client.HTTPSConnection("api.criteo.com")

  payload = json.dumps({
      "data": {
          "attributes": {
              "accountIds": [
                  "667131474078658560",
                  "680116036401160192"
              ]
          },
          "type": "AccountFeesSearchRequest"
      }
  })

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

  conn.request(
      "POST",
      "/{version}/retail-media/accounts/fees/search",
      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("application/json");

  RequestBody body = RequestBody.create(mediaType, """
  {
      "data": {
          "attributes": {
              "accountIds": [
                  "667131474078658560",
                  "680116036401160192"
              ]
          },
          "type": "AccountFeesSearchRequest"
      }
  }
  """);

  Request request = new Request.Builder()
      .url("https://api.criteo.com/{version}/retail-media/accounts/fees/search")
      .method("POST", body)
      .addHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
      .addHeader("Content-Type", "application/json")
      .addHeader("Accept", "application/json")
      .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/{version}/retail-media/accounts/fees/search');
  $request->setMethod(HTTP_Request2::METHOD_POST);
  $request->setConfig([
      'follow_redirects' => TRUE
  ]);
  $request->setHeader([
      'Authorization' => 'Bearer <MY_ACCESS_TOKEN>',
      'Content-Type' => 'application/json',
      'Accept' => 'application/json'
  ]);

  $request->setBody(json_encode([
      "data" => [
          "attributes" => [
              "accountIds" => [
                  "667131474078658560",
                  "680116036401160192"
              ]
          ],
          "type" => "AccountFeesSearchRequest"
      ]
  ], JSON_PRETTY_PRINT));

  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>

Please note that:

* `accountIds` is optional.
* `accountIds: [""]` → returns an **empty response**.
* `accountIds: []` → returns **all accounts the user has consent to**.
* Up to **25 account IDs** can be queried at once in the request.
* Must be sent as **an array** — not as a comma-separated string.

***

### Sample Response

```json expandable theme={null}
{
    "metadata": {
        "count": 2,
        "offset": 0,
        "limit": 50
    },
    "data": [
        {
            "type": "PrivateMarketAccountFees",
            "attributes": {
                "accountId": "667131474078658560",
                "fees": {
                    "demandManaged": {
                        "rate": 0.40
                    },
                    "managedService": {
                        "rate": 0.20,
                        "onsiteSponsoredProductsEnabled": false,
                        "onsiteDisplayEnabled": false
                    }
                }
            }
        },
        {
            "type": "PrivateMarketAccountFees",
            "attributes": {
                "accountId": "680116036401160192",
                "fees": {
                    "demandManaged": {
                        "rate": 0.10
                    },
                    "managedService": {
                        "rate": 0.15,
                        "onsiteSponsoredProductsEnabled": true,
                        "onsiteDisplayEnabled": false
                    }
                }
            }
        }
    ],
    "warnings": [],
    "errors": []
}
```

***

## Update Account Fees (Retailers Only)

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/{version}/retail-media/accounts/fees/update
  ```
</EndpointBadge>

This endpoint allows **Private Market retailers** to update fees for child seller or demand accounts. You can find more details about this endpoint in our API reference [here](/retail-media/v2025.10/reference/accounts/update-account-fees).

To use this endpoint, users must meet the following requirements:

* **OAuth Scope**: `Account Manage`
* **Consent**:
  * To the **parent supply account**
  * To the **child accounts** for which fees are being managed

***

### Attributes

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

      <th>
        <p>
          Data Type
        </p>
      </th>

      <th>
        <p>
          Description
        </p>
      </th>

      <th>
        <p>
          Writable
        </p>
      </th>

      <th>
        <p>
          Nullable
        </p>
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        <p>
          <code>
            accountIds
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            list
          </code>
        </p>
      </td>

      <td>
        <p>
          Account ID
        </p>

        <p>
          Accepted values: string of

          <code>
            int64
          </code>
        </p>
      </td>

      <td>
        <p>
          Y
        </p>
      </td>

      <td>
        <p>
          N
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            fees
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            enum
          </code>
        </p>
      </td>

      <td>
        <p>
          Defines the set of fees you can set on the Account. Possible values:
        </p>

        <ul>
          <li>
            <code>
              demandManaged
            </code>

            : DSP fee on private market demand account
          </li>

          <li>
            <code>
              managedService
            </code>

            : Managed Service fee on private market demand account
          </li>
        </ul>
      </td>

      <td>
        <p>
          N
        </p>
      </td>

      <td>
        <p>
          N
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            rate
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            decimal
          </code>
        </p>
      </td>

      <td>
        <p>
          Value to apply as the

          <code>
            demandManaged
          </code>

          and/or

          <code>
            managedService
          </code>

          fee.
        </p>

        <p>
          Accepted range:

          <b>
            0.00 to 1.00
          </b>
        </p>

        <p>
          Max precision:

          <b>
            2 decimal places
          </b>
        </p>
      </td>

      <td>
        <p>
          Y
        </p>
      </td>

      <td>
        <p>
          N
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            managedService
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            enum
          </code>
        </p>
      </td>

      <td>
        <p>
          The managed service fee that is applied to the account.
        </p>

        <p>
          Options:
        </p>

        <ul>
          <li>
            <code>
              onsiteDisplayEnabled
            </code>
          </li>

          <li>
            <code>
              onsiteSponsoredProductsEnabled
            </code>
          </li>
        </ul>
      </td>

      <td>
        <p>
          N
        </p>
      </td>

      <td>
        <p>
          N
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            onsiteDisplayEnabled
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            boolean
          </code>
        </p>
      </td>

      <td>
        <p>
          Indicates if

          <code>
            Managed Service fee
          </code>

          is enabled for Onsite Display.
        </p>
      </td>

      <td>
        <p>
          Y
        </p>
      </td>

      <td>
        <p>
          N
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            onsiteSponsoredProductsEnabled
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            boolean
          </code>
        </p>
      </td>

      <td>
        <p>
          Indicates if

          <code>
            Managed Service fee
          </code>

          is enabled for Sponsored Products.
        </p>
      </td>

      <td>
        <p>
          Y
        </p>
      </td>

      <td>
        <p>
          N
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Feature flag

This functionality is available only to retailers who have the **Private Market Fees** setting enabled in their UI. If you do not see this feature in your account, please contact your support team or account representative.

To have access to this functionality, retailers must:

* Have access to the fee configuration UI,
* Enable either or both fee types:
* **Managed Service Fee**
* **Demand Managed Fee**

***

### Sample Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -L -X POST "https://api.criteo.com/{version}/retail-media/accounts/fees/update" \
      -H "Authorization: Bearer <MY_ACCESS_TOKEN>" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
          "data": {
              "attributes": {
                  "accountIds": [
                      "618738804747743232"
                  ],
                  "fees": {
                      "demandManaged": {
                          "rate": "0"
                      },
                      "managedService": {
                          "onsiteDisplayEnabled": "true",
                          "onsiteSponsoredProductsEnabled": "true",
                          "rate": "0.01"
                      }
                  }
              },
              "type": "AccountFeesUpdateRequest"
          }
      }'

  ```

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

  conn = http.client.HTTPSConnection("api.criteo.com")

  payload = json.dumps({
      "data": {
          "attributes": {
              "accountIds": [
                  "618738804747743232"
              ],
              "fees": {
                  "demandManaged": {
                      "rate": "0"
                  },
                  "managedService": {
                      "onsiteDisplayEnabled": "true",
                      "onsiteSponsoredProductsEnabled": "true",
                      "rate": "0.01"
                  }
              }
          },
          "type": "AccountFeesUpdateRequest"
      }
  })

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

  conn.request(
      "POST",
      "/{version}/retail-media/accounts/fees/update",
      payload,
      headers
  )

  res = conn.getresponse()
  data = res.read()
  print(data.decode("utf-8"))

  ```

  ```java Java expandable theme={null}
  OkHttpClient client = new OkHttpClient().newBuilder().build();

  MediaType mediaType = MediaType.parse("application/json");

  RequestBody body = RequestBody.create(mediaType, """
  {
      "data": {
          "attributes": {
              "accountIds": [
                  "618738804747743232"
              ],
              "fees": {
                  "demandManaged": {
                      "rate": "0"
                  },
                  "managedService": {
                      "onsiteDisplayEnabled": "true",
                      "onsiteSponsoredProductsEnabled": "true",
                      "rate": "0.01"
                  }
              }
          },
          "type": "AccountFeesUpdateRequest"
      }
  }
  """);

  Request request = new Request.Builder()
      .url("https://api.criteo.com/{version}/retail-media/accounts/fees/update")
      .method("POST", body)
      .addHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
      .addHeader("Content-Type", "application/json")
      .addHeader("Accept", "application/json")
      .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/{version}/retail-media/accounts/fees/update');
  $request->setMethod(HTTP_Request2::METHOD_POST);
  $request->setConfig([
      'follow_redirects' => TRUE
  ]);
  $request->setHeader([
      'Authorization' => 'Bearer <MY_ACCESS_TOKEN>',
      'Content-Type' => 'application/json',
      'Accept' => 'application/json'
  ]);

  $request->setBody(json_encode([
      "data" => [
          "attributes" => [
              "accountIds" => [
                  "618738804747743232"
              ],
              "fees" => [
                  "demandManaged" => [
                      "rate" => "0"
                  ],
                  "managedService" => [
                      "onsiteDisplayEnabled" => "true",
                      "onsiteSponsoredProductsEnabled" => "true",
                      "rate" => "0.01"
                  ]
              ]
          ],
          "type" => "AccountFeesUpdateRequest"
      ]
  ], JSON_PRETTY_PRINT));

  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>

***

### Validation Rules

* `accountIds` is **required** — omitting it returns a **400 error**.
* `demandManaged.rate` must be a **decimal between 0 and 1**.
* `managedService.onsiteDisplayEnabled` and `onsiteSponsoredProductsEnabled` must be **boolean** (`true` or `false`).

***

### Sample Response

```json theme={null}
{
  "data": {
    "type": "AccountFeesUpdateResult",
    "attributes": {
      "successfullyUpdatedAccountIds": [
        "618738804747743232"
      ],
      "failedUpdateAccountIds": []
    }
  },
  "warnings": [],
  "errors": []
}
```

***

## Responses

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

      <th>
        <p>
          Title
        </p>
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        <p>
          🟢
        </p>

        <p>
          <code>
            200
          </code>
        </p>
      </td>

      <td>
        <p>
          Success
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          🔴
        </p>

        <p>
          <code>
            400
          </code>
        </p>
      </td>

      <td>
        <p>
          Bad Request: Model Validation Error. Check that the acceptable values for the attributes are correct.
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          🔴
        </p>

        <p>
          <code>
            403
          </code>
        </p>
      </td>

      <td>
        <p>
          API user does not have the authorization to make requests to the account ID. For an authorization request, follow
        </p>

        <p>
          <a href="/retail-media/v2025.10/docs/authorization-requests">
            the authorization request steps
          </a>
        </p>

        <p>
          .
        </p>
      </td>
    </tr>
  </tbody>
</table>

***

### Error responses examples

#### Invalid permission

```json theme={null}
{
    "warnings": [],
    "errors": [
        {
            "type": "authorization",
            "title": "Authorization error",
            "detail": "Resource access forbidden: does not have permissions"
        }
    ]
}
```

#### Rate value is missing

```json theme={null}
{
    "warnings": [],
    "errors": [
        {
            "traceId": "bb1c3376097f47934484ea67bf8e2755",
            "type": "validation",
            "code": "model-validation-error",
            "title": "Model validation error",
            "detail": "Error converting value {null} to type 'System.Decimal'. Path 'data.attributes.fees.demandManaged.rate', line 9, position 20."
        },
        {
            "traceId": "bb1c3376097f47934484ea67bf8e2755",
            "type": "validation",
            "code": "model-validation-error",
            "title": "Model validation error",
            "detail": "Required property 'rate' expects a value but got null. Path 'data.attributes.fees.demandManaged', line 10, position 9."
        }
    ]
}
```
