Retailer Budgets - Criteo Docs

Introduction

Commerce Max Retailer Budgets introduces a buying model in which campaign budgets are funded by the retailer rather than the advertiser.

This guide covers the API changes required for third-party buying platforms to create and manage Retailer Budgets Sponsored Products campaigns end-to-end.

Business Context

Prior to this release, the Retail Media API did not expose retailer scoping on balances, campaigns, or line items. Retailer-budgets buying requires platforms to associate balances, campaigns, and line items to the same retailer — the API now enforces these constraints explicitly.

Prerequisites

Key Concepts

Backward compatibility for balance endpoints:

Endpoints Overview

All endpoints changes related to Retailer Budgets are also documented in the following pages:

Verb Endpoint Description
GET /retail-media/balances/{balanceId} Get a single balance. Now includes retailerId, retailerPoNumber, criteoPoNumber.
GET /retail-media/accounts/{accountId}/balances List balances. Now includes retailer fields. Retailer-budgets balances hidden on prior versions.
GET /retail-media/balances/{balanceId}/history Get balance change history. Now includes retailerPoNumber, criteoPoNumber.
POST /retail-media/balances/{balanceId}/campaigns/append Add campaigns to a balance. Validates retailer consistency.
POST /retail-media/balances/{balanceId}/campaigns/delete Remove campaigns from a balance. Returns error for retailer-billed balances.
POST /retail-media/accounts/{accountId}/campaigns Create a campaign. Now accepts and validates retailerId.
GET /retail-media/campaigns List campaigns. Now returns retailerId; supports filtering by retailer.
GET /retail-media/campaigns/{campaignId} Get a campaign. Now returns retailerId.
POST /retail-media/campaigns/{campaignId}/auction-line-items Create a line item. Enforces targetRetailerId matches campaign retailer.
POST /retail-media/accounts/{accountId}/retailers/search Search retailers. Now returns budgetModel in campaignAvailabilities.

Attributes

New and Changed Fields on Balances

Attribute Data Type Mutable Description
retailerId string? init Retailer this balance is scoped to.
Present only on retailer-budgets balances.
Nullable? Y (null for non-retailer-billed)
retailerPoNumber string? always Retailer purchase order number. Replaces the removed poNumber field.
Nullable? Y
criteoPoNumber string? always Criteo purchase order number.
Replaces the removed poNumber field.
Nullable? Y
privateMarketBillingType enum init Billing type for Private Market. Values: NotApplicable, BillByRetailer, BillByCriteo, Unknown
poNumber string Removed in 2026-01. Replaced by retailerPoNumber and criteoPoNumber.

New Field on Campaigns

A new field retailerId has been added to the following endpoints:

Attribute Data Type Description
retailerId string The retailer this campaign is associated with.
Required when using a retailer-budgets balance.
Writeable? Y (at create)
Nullable? Y (for non-retailer-budgets campaigns)

New Fields on Retailer Search

The new fields are added to the following endpoint:

Attribute Data Type Description
budgetModel string Budget model(s) supported for the given buyType/campaignType combination at this retailer.
Values: capped, uncapped, retailerBudgets, criteoBudgets
Writeable? N
Nullable? N

New Error Codes

Error code Endpoint Meaning
RetailerBilledBalanceImmutable DELETE /balances/{balanceId}/campaigns Cannot remove a retailer-budgets balance from a campaign.
RetailerMismatchWithBalance POST /accounts/{accountId}/campaigns Campaign RetailerId does not match the balance’s RetailerId.
RetailerMismatchWithCampaign POST /campaigns/{campaignId}/auction-line-items Line item targetRetailerId does not match the campaign’s RetailerId.

Endpoint Changes

Get List of Balances for an Account

This endpoint returns a paginated list of balances for an account. On API version 2026-01 and later, retailer-budgets balances are included and retailerId, retailerPoNumber, and criteoPoNumber are returned. The old poNumber field is removed.

Query parameters

Sample Request

curl -L -X GET 'https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/balances' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>'

Sample Response

{
  "metadata": {
    "totalItemsAcrossAllPages": 135,
    "currentPageSize": 25,
    "currentPageIndex": 0,
    "totalPages": 6
  },
  "data": [
    {
      "id": "100000000000000001",
      "type": "BalanceV1",
      "attributes": {
        "name": "Sample Name",
        "retailerPoNumber": null,
        "criteoPoNumber": "PO-CRITEO-123",
        "retailerId": null,
        "memo": "Sample memo",
        "deposited": 10.0,
        "spent": 10.0,
        "remaining": 0.0,
        "startDate": "2020-04-13",
        "endDate": null,
        "status": "ended",
        "createdAt": "2020-04-13T15:39:48+00:00",
        "updatedAt": "2023-06-13T13:35:53+00:00",
        "balanceType": "capped",
        "spendType": "onsite",
        "privateMarketBillingType": "notApplicable"
      }
    },
    {
      "id": "100000000000000002",
      "type": "BalanceV1",
      "attributes": {
        "name": "Sample Name",
        "retailerPoNumber": "PO-RETAILER-123",
        "criteoPoNumber": "PO-CRITEO-123",
        "retailerId": 123,
        "memo": "Sample memo",
        "deposited": 100.0,
        "spent": 0.16,
        "remaining": 99.84,
        "startDate": "2026-03-24",
        "endDate": null,
        "status": "active",
        "createdAt": "2026-03-24T18:15:58+00:00",
        "updatedAt": "2026-05-20T17:17:40+00:00",
        "balanceType": "capped",
        "spendType": "onsite",
        "privateMarketBillingType": "notApplicable"
      }
    }
  ],
  "warnings": [],
  "errors": []
}

Add Campaigns to a Balance

This endpoint adds one or more campaigns to a balance. It validates that campaigns are retailer-native when the balance is retailer-budget.

Sample Request

curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/balances/814886589256347648/campaigns/append' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
-d '{
  "data": {
    "attributes": {
      "ids": ["718038552188952576", "234105251251242423"]
    },
    "type": "AppendCampaignsRequest"
  }
}'

Sample Response

{
  "data": {
    "attributes": {
      "ids": ["718038552188952576", "234105251251242423"]
    },
    "type": "BalanceCampaignsV1"
  },
  "warnings": [],
  "errors": []
}

Sample Response — Error (non-retailer-native campaign)

{
  "errors":[
    {
      "message": "Only retailer-sold campaigns are allowed to be mapped to a retailer-budget balance.",
      "status": 400
    }
  ]
}

Remove Campaign(s) from a Balance

This endpoint removes one or more campaigns from a balance.

Sample Request

curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/balances/814886589256347648/campaigns/delete' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
-d '{
  "data": {
    "attributes": {
      "ids": ["234105251251242423"]
    },
    "type": "DeleteCampaignsRequest"
  }
}'

Sample Response

{
  "data": {
    "attributes": {
      "ids": ["718038552188952576"]
    },
    "type": "BalanceCampaignsV1"
  },
  "warnings": [],
  "errors": []
}

Create New Campaigns

This endpoint creates a new campaign. For retailer-budgets campaigns, retailerId is required and must match the retailerId on the drawable balance.

Sample Request

curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/campaigns' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
-d '{
  "data": {
    "type": "Campaign",
    "attributes": {
      "name": "Retailer Budgets Campaign Q2",
      "startDate": "2026-07-01T00:00:00+00:00",
      "clickAttributionWindow": "30D",
      "viewAttributionWindow": "None",
      "retailerId": "1298",
      "drawableBalanceIds": ["814886589256347648"]
    }
  }
}'

Sample Response

{
  "data": {
    "id": "718038552188952576",
    "type": "Campaign",
    "attributes": {
      "name": "Retailer Budgets Campaign Q2",
      "accountId": "625702934721171442",
      "type": "auction",
      "status": "inactive",
      "retailerId": "1298",
      "drawableBalanceIds": ["814886589256347648"],
      "budget": null,
      "budgetSpent": 0.0,
      "budgetRemaining": null,
      "startDate": "2026-07-01T00:00:00+00:00",
      "endDate": null,
      "clickAttributionWindow": "30D",
      "viewAttributionWindow": "None",
      "createdAt": "2026-05-08T00:00:00+00:00",
      "updatedAt": "2026-05-08T00:00:00+00:00"
    }
  }
}

Get Campaigns by Account ID and Campaign ID

Both endpoints now return retailerId in the campaign attributes. The list endpoint supports filtering by retailerId.

Sample Request — Get a Single Campaign

curl -L -X GET 'https://api.criteo.com/2026-01/retail-media/campaigns/718038552188952576' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>'

Sample Response

{
  "data": {
    "id": "718038552188952576",
    "type": "Campaign",
    "attributes": {
      "name": "Retailer Budgets Campaign Q2",
      "accountId": "625702934721171442",
      "type": "auction",
      "status": "active",
      "retailerId": "1298",
      "drawableBalanceIds": ["814886589256347648"],
      "budget": null,
      "budgetSpent": 1250.00,
      "budgetRemaining": null,
      "startDate": "2026-07-01T00:00:00+00:00",
      "endDate": null,
      "clickAttributionWindow": "30D",
      "viewAttributionWindow": "None",
      "createdAt": "2026-05-08T00:00:00+00:00",
      "updatedAt": "2026-07-01T00:00:00+00:00"
    }
  }
}

Create an Auction Line Item

Creates an auction line item. For retailer-budgets campaigns, targetRetailerId is required and must match the campaign’s retailerId. Only one retailer is allowed per retailer-billed campaign.

Sample Request

curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/campaigns/718038552188952576/auction-line-items' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
-d '{
  "data": {
    "type": "SponsoredProductsLineItem",
    "attributes": {
      "name": "Retailer Budget Line Item",
      "targetRetailerId": "1298",
      "startDate": "2026-07-01",
      "bidStrategy": "automated",
      "optimizationStrategy": "conversion",
      "keywordStrategy": "genericAndBranded"
    }
  }
}'

Sample Response

{
  "data": {
    "id": "234105251251242423",
    "type": "SponsoredProductsLineItem",
    "attributes": {
      "name": "Retailer Budget Line Item",
      "campaignId": "718038552188952576",
      "targetRetailerId": "1298",
      "startDate": "2026-07-01T00:00:00+00:00",
      "endDate": null,
      "status": "inactive",
      "budget": null,
      "budgetSpent": 0.0,
      "budgetRemaining": null,
      "targetBid": 0.3,
      "maxBid": null,
      "monthlyPacing": null,
      "dailyPacing": null,
      "isAutoDailyPacing": false,
      "bidStrategy": "automated",
      "optimizationStrategy": "conversion",
      "keywordStrategy": "genericAndBranded",
      "flightSchedule": null,
      "createdAt": "2026-05-08T00:00:00+00:00",
      "updatedAt": "2026-05-08T00:00:00+00:00"
    }
  },
  "warnings": [],
  "errors": []
}

Sample Response — Error (retailer mismatch)

{
  "errors": [
    {
      "message": "The line item targetRetailerId must match the campaign retailerId.",
      "status": 400
    }
  ]
}

Search Retailer for an Account

This endpoint allows searching for available retailers for an account. The campaignAvailabilities object now includes budgetModel, allowing platforms to determine which budget models are supported at a given retailer before creating a campaign.

Sample Request

curl -L -X POST 'https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/retailers/search' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
-d '{}'

Sample Response

{
  "data": [
    {
      "id": "retailer-789",
      "type": "Retailer",
      "attributes": {
        "name": "Example Retailer",
        "campaignAvailabilities": [
          {
            "buyType": "auction",
            "campaignType": "sponsoredProducts",
            "isAvailable": true,
            "budgetModel": "retailerBilled",
            "validCombinations": [
              {
                "pageType": "search",
                "pageEnvironmentType": "offsite"
              }
            ]
          }
        ]
      }
    }
  ]
}

Responses

Response Title Detail Troubleshooting
🟢 200 Success Request executed successfully.
🔴 400 Retailer-budget balance mapping “Only retailer-sold campaigns are allowed to be mapped to a retailer-billed balance.” Only campaigns scoped to the same retailer as the balance can be appended via /campaigns/append.
🔴 400 RetailerMismatchWithBalance Campaign retailerId does not match the balance retailerId. Ensure the retailerId in campaign settings matches the retailerId on the balance you are associating.
🔴 400 RetailerMismatchWithCampaign Line item targetRetailerId does not match the campaign retailerId. Ensure targetRetailerId on the line item matches the retailerId set on the parent campaign.
🔴 400 Error deserializing request A required field is missing or has an invalid value. Review the request body against the attributes table above.
🔴 403 Unauthorized Verify your access token and that your account has access to the retailer in question.