Account Fees (Private Market)
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
| Verb | Endpoint | Description |
|---|---|---|
| POST | /accounts/fees/search | This endpoint allows users to retrieve fee settings for one or more accounts they have access to. |
| POST | /accounts/fees/update | This endpoint allows Private Market retailers to update fees for child seller or demand accounts. |
Search Account Fees

https://api.criteo.com/{version}/retail-media/accounts/fees/search
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.
This endpoint does not require
Account Managescope nor consent to the parent supply account.
Attributes
Attribute | Data Type | Description |
|---|---|---|
|
| Account ID Accepted values: string of |
Optional Query Parameters
Query Parameters | Data Type | Description |
|---|---|---|
|
| Pagination parameter, see API Response |
|
| Pagination parameter, see API Response |
|
| Comma-separated list of optional attributes to include in the response. |
Sample request
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"
}
}'
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"))
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
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();
}
Please note that:
accountIdsis 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
{
"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)

https://api.criteo.com/{version}/retail-media/accounts/fees/update
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.
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
Attribute | Data Type | Description | Writable | Nullable |
|---|---|---|---|---|
|
| Account ID | Y | N |
|
| Defines the set of fees you can set on the Account. Possible values:
| N | N |
|
| Value to apply as the | Y | N |
|
| The managed service fee that is applied to the account.
| N | N |
|
| Indicates if | Y | N |
|
| Indicates if | Y | N |
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
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"
}
}'
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"))
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
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();
}
Validation Rules
accountIdsis required — omitting it returns a 400 error.demandManaged.ratemust be a decimal between 0 and 1.managedService.onsiteDisplayEnabledandonsiteSponsoredProductsEnabledmust be boolean (trueorfalse).
Sample Response
{
"data": {
"type": "AccountFeesUpdateResult",
"attributes": {
"successfullyUpdatedAccountIds": [
"618738804747743232"
],
"failedUpdateAccountIds": []
}
},
"warnings": [],
"errors": []
}Responses
Response | Title |
|---|---|
🟢
| Success |
🔴
| Bad Request: Model Validation Error. Check that the acceptable values for the attributes are correct. |
🔴
| API user does not have the authorization to make requests to the account ID. For an authorization request, follow the authorization request steps . |
Error responses examples
Invalid permission
{
"warnings": [],
"errors": [
{
"type": "authorization",
"title": "Authorization error",
"detail": "Resource access forbidden: does not have permissions"
}
]
}Rate value is missing
{
"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."
}
]
}Updated about 17 hours ago