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

# Retailer Billed

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

<Info>
  **Commerce Max Retailer Billed** introduces a buying model in which campaign budgets are funded by the retailer rather than the advertiser.
</Info>

This guide covers the API changes required for third-party buying platforms to create and manage retailer-billed 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-billed buying requires platforms to associate balances, campaigns, and line items to the same retailer — the API now enforces these constraints explicitly.

### Prerequisites

* API version `2026-01` or later is required to see retailer-billed balances. On prior versions, retailer-billed balances are hidden by default to prevent integration surprises during rollout.
* Platforms must use the supply account ID when querying balances if they wish to discover retailer-billed balances.

### Key Concepts

* **Retailer-billed balance** — a budget object funded by the retailer, scoped to a specific `RetailerId`. Cannot be created via API; must be retrieved via `GET /balances`.
* **`RetailerId`** — the identifier of the retailer that funds the balance and scopes the campaign. Must be consistent across balance → campaign → line item.
* **`budgetModel`** — a new field on the retailer search response indicating which budget models (e.g., `retailerBilled`, `capped`, `uncapped`) are supported at a given retailer.

<Warning>
  **Backward compatibility for balance endpoints:**

  * The `poNumber` field on balance responses is **removed** in `2026-01` and replaced by two separate fields: `retailerPoNumber` and `criteoPoNumber`. This is a breaking change for consumers of `GET /balances` on prior versions who rely on `poNumber`.
  * All other new fields (`retailerId`, `privateMarketBillingType`) are additive. Retailer-billed balances are hidden by default on prior API versions.
</Warning>

***

## Endpoints Overview

<Info>
  All endpoints changes related to Retailer Billed are also documented in the following pages:

  * [Balances Endpoint Guide](/retail-media/docs/balances-endpoints)
  * [Campaigns Endpoint Guide](/retail-media/docs/campaigns-endpoints)
  * [Auction Line Items Endpoint Guide](/retail-media/docs/onsite-sponsored-products-line-items)
  * [Retailer Search Endpoint Guide](/retail-media/docs/retailer-search)
</Info>

<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/balances/\{balanceId}
          </code>
        </p>
      </td>

      <td>
        <p>
          Get a single balance. Now includes

          <code>
            retailerId
          </code>

          ,

          <code>
            retailerPoNumber
          </code>

          ,

          <code>
            criteoPoNumber
          </code>

          .
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/accounts/\{accountId}/balances
          </code>
        </p>
      </td>

      <td>
        <p>
          List balances. Now includes retailer fields. Retailer-billed balances hidden on prior versions.
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/balances/\{balanceId}/history
          </code>
        </p>
      </td>

      <td>
        <p>
          Get balance change history. Now includes

          <code>
            retailerPoNumber
          </code>

          ,

          <code>
            criteoPoNumber
          </code>

          .
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/balances/\{balanceId}/campaigns/append
          </code>
        </p>
      </td>

      <td>
        <p>
          Add campaigns to a balance. Validates retailer consistency.
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/balances/\{balanceId}/campaigns/delete
          </code>
        </p>
      </td>

      <td>
        <p>
          Remove campaigns from a balance. Returns error for retailer-billed balances.
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/accounts/\{accountId}/campaigns
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a campaign. Now accepts and validates

          <code>
            retailerId
          </code>

          .
        </p>
      </td>
    </tr>

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

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

      <td>
        <p>
          List campaigns. Now returns

          <code>
            retailerId
          </code>

          ; supports filtering by retailer.
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/campaigns/\{campaignId}
          </code>
        </p>
      </td>

      <td>
        <p>
          Get a campaign. Now returns

          <code>
            retailerId
          </code>

          .
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/campaigns/\{campaignId}/auction-line-items
          </code>
        </p>
      </td>

      <td>
        <p>
          Create a line item. Enforces

          <code>
            targetRetailerId
          </code>

          matches campaign retailer.
        </p>
      </td>
    </tr>

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

      <td>
        <p>
          <code>
            /retail-media/accounts/\{accountId}/retailers/search
          </code>
        </p>
      </td>

      <td>
        <p>
          Search retailers. Now returns

          <code>
            budgetModel
          </code>

          in

          <code>
            campaignAvailabilities
          </code>

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

***

## Attributes

### New and Changed Fields on Balances

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

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

      <th>
        <p>
          Mutable
        </p>
      </th>

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

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

      <td>
        <p>
          <code>
            string?
          </code>
        </p>
      </td>

      <td>
        <p>
          init
        </p>
      </td>

      <td>
        <p>
          Retailer this balance is scoped to.
        </p>

        <p>
          Present only on retailer-billed balances.
        </p>

        <p>
          *Nullable?* Y (null for non-retailer-billed)
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            retailerPoNumber
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            string?
          </code>
        </p>
      </td>

      <td>
        <p>
          always
        </p>
      </td>

      <td>
        <p>
          Retailer purchase order number.

          <b>
            Replaces
          </b>

          the removed

          <code>
            poNumber
          </code>

          field.
        </p>

        <p>
          *Nullable?* Y
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            criteoPoNumber
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            string?
          </code>
        </p>
      </td>

      <td>
        <p>
          always
        </p>
      </td>

      <td>
        <p>
          Criteo purchase order number.
        </p>

        <p>
          <b>
            Replaces
          </b>

          the removed

          <code>
            poNumber
          </code>

          field.
        </p>

        <p>
          *Nullable?* Y
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            privateMarketBillingType
          </code>
        </p>
      </td>

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

      <td>
        <p>
          init
        </p>
      </td>

      <td>
        <p>
          Billing type for Private Market. Values:

          <code>
            NotApplicable
          </code>

          ,

          <code>
            BillByRetailer
          </code>

          ,

          <code>
            BillByCriteo
          </code>

          ,

          <code>
            Unknown
          </code>
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          \~\~

          <code>
            poNumber
          </code>

          \~\~
        </p>
      </td>

      <td>
        <p>
          ~~string~~
        </p>
      </td>

      <td>
        <p>
          —
        </p>
      </td>

      <td>
        <p>
          <b>
            Removed
          </b>

          in

          <code>
            2026-01
          </code>

          . Replaced by

          <code>
            retailerPoNumber
          </code>

          and

          <code>
            criteoPoNumber
          </code>

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

***

### New Field on Campaigns

A new field `RetailerId` has been added to the following endpoints:

* `/accounts/{accountId}/campaigns`
* `/campaigns/{campaignId}`

<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>
            RetailerId
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            string
          </code>
        </p>
      </td>

      <td>
        <p>
          The retailer this campaign is associated with.
        </p>

        <p>
          Required when using a retailer-billed balance.
        </p>

        <p>
          <b>
            Writeable?
          </b>

          Y (at create)
        </p>

        <p>
          <b>
            Nullable?
          </b>

          Y (for non-retailer-billed campaigns)
        </p>
      </td>
    </tr>
  </tbody>
</table>

### New Fields on Retailer Search

The new fields are added to the following endpoint:

* `/accounts/{accountId}/retailers/search`

<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>
            budgetModel
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            string
          </code>
        </p>
      </td>

      <td>
        <p>
          Budget model(s) supported for the given

          <code>
            buyType
          </code>

          /

          <code>
            campaignType
          </code>

          combination at this retailer.
        </p>

        <p>
          Values:

          <code>
            capped
          </code>

          ,

          <code>
            uncapped
          </code>

          ,

          <code>
            retailerBilled
          </code>

          .
        </p>

        <p>
          <b>
            Writeable?
          </b>

          N
        </p>

        <p>
          <b>
            Nullable?
          </b>

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

### New Error Codes

<table>
  <thead>
    <tr>
      <th>
        <p>
          Error code
        </p>
      </th>

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

      <th>
        <p>
          Meaning
        </p>
      </th>
    </tr>
  </thead>

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

      <td>
        <p>
          <code>
            DELETE /balances/\{balanceId}/campaigns
          </code>
        </p>
      </td>

      <td>
        <p>
          Cannot remove a retailer-billed balance from a campaign.
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            RetailerMismatchWithBalance
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            POST /accounts/\{accountId}/campaigns
          </code>
        </p>
      </td>

      <td>
        <p>
          Campaign

          <code>
            RetailerId
          </code>

          does not match the balance's

          <code>
            RetailerId
          </code>

          .
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          <code>
            RetailerMismatchWithCampaign
          </code>
        </p>
      </td>

      <td>
        <p>
          <code>
            POST /campaigns/\{campaignId}/auction-line-items
          </code>
        </p>
      </td>

      <td>
        <p>
          Line item

          <code>
            targetRetailerId
          </code>

          does not match the campaign's

          <code>
            RetailerId
          </code>

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

***

# 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-billed balances are included and `retailerId`, `retailerPoNumber`, and `criteoPoNumber` are returned. The old `poNumber` field is removed.

<Info>
  **Query parameters**

  * `offset` (int, default 0),
  * `limit` (int, default 25, max 500),
  * `limitToId` (List\<string>)
</Info>

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/balances
  ```
</EndpointBadge>

**Sample Request**

<CodeGroup>
  ```bash cURL theme={null}
  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>'
  ```

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

  conn = http.client.HTTPSConnection("api.criteo.com")
  headers = {'Accept': 'application/json', 'Authorization': 'Bearer &lt;TOKEN&gt;'}
  conn.request("GET", "/2026-01/retail-media/accounts/625702934721171442/balances", headers=headers)
  res = conn.getresponse()
  print(res.read().decode("utf-8"))
  ```

  ```java Java theme={null}
  OkHttpClient client = new OkHttpClient().newBuilder().build();
  Request request = new Request.Builder()
    .url("https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/balances")
    .method("GET", null)
    .addHeader("Accept", "application/json")
    .addHeader("Authorization", "Bearer &lt;TOKEN&gt;")
    .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/2026-01/retail-media/accounts/625702934721171442/balances');
  $request->setMethod(HTTP_Request2::METHOD_GET);
  $request->setHeader(array('Accept' => 'application/json', 'Authorization' => 'Bearer &lt;TOKEN&gt;'));
  echo $request->send()->getBody();
  ```
</CodeGroup>

**Sample Response**

```json expandable theme={null}
{
  "meta": { "count": 2, "offset": 0, "limit": 25 },
  "data": [
    {
      "id": "814283465675018240",
      "type": "Balance",
      "attributes": {
        "name": "Retailer Billed Q2 Budget",
        "retailerId": "1298",
        "retailerPoNumber": "A-5678",
        "criteoPoNumber": null,
        "memo": "Q2 retailer-billed campaign",
        "deposited": 2000.00,
        "spent": 0.00,
        "remaining": 2000.00,
        "startDate": "2026-07-01",
        "endDate": "2026-12-31",
        "status": "active",
        "balanceType": "capped",
        "spendType": "Onsite",
        "privateMarketBillingType": "billByRetailer",
        "createdAt": "2026-02-24T23:51:46+00:00",
        "updatedAt": "2026-02-24T23:51:48+00:00"
      }
    },
    {
      "id": "814313002113232896",
      "type": "Balance",
      "attributes": {
        "name": "Standard Advertiser Balance",
        "retailerId": null,
        "retailerPoNumber": null,
        "criteoPoNumber": "A-1234",
        "deposited": 2000.00,
        "spent": 0.00,
        "remaining": 2000.00,
        "startDate": "2026-07-01",
        "endDate": "2026-12-31",
        "status": "active",
        "balanceType": "capped",
        "spendType": "Onsite",
        "privateMarketBillingType": "billByCriteo",
        "createdAt": "2026-02-25T01:49:08+00:00",
        "updatedAt": "2026-02-25T01:49:10+00:00"
      }
    }
  ],
  "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-billed.

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/2026-01/retail-media/balances/{balanceId}/campaigns/append
  ```
</EndpointBadge>

**Sample Request**

```bash theme={null}
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**

```json theme={null}
{
  "data": {
    "attributes": {
      "ids": ["718038552188952576", "234105251251242423"]
    },
    "type": "BalanceCampaigns"
  },
  "warnings": [],
  "errors": []
}
```

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

```json theme={null}
{
  "errors": [
    {
      "message": "Only retailer-sold campaigns are allowed to be mapped to a retailer-billed balance.",
      "status": 400
    }
  ]
}
```

***

## Remove Campaign(s) from a Balance

This endpoint removes one or more campaigns from a balance.

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/2026-01/retail-media/balances/{balanceId}/campaigns/delete
  ```
</EndpointBadge>

**Sample Request**

```bash theme={null}
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**

```json theme={null}
{
  "data": {
    "attributes": {
      "ids": ["718038552188952576"]
    },
    "type": "BalanceCampaigns"
  },
  "warnings": [],
  "errors": []
}
```

***

## Create New Campaigns

This endpoint creates a new campaign.

<Warning>
  For retailer-billed campaigns, `retailerId` is required and must match the `retailerId` on the drawable balance.
</Warning>

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/campaigns
  ```
</EndpointBadge>

**Sample Request**

<CodeGroup>
  ```bash cURL theme={null}
  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 Billed Campaign Q2",
        "startDate": "2026-07-01T00:00:00+00:00",
        "clickAttributionWindow": "30D",
        "viewAttributionWindow": "None",
        "retailerId": "1298",
        "drawableBalanceIds": ["814886589256347648"]
      }
    }
  }'
  ```

  ```python Python theme={null}
  import http.client
  import json
  conn = http.client.HTTPSConnection("api.criteo.com")
  payload = json.dumps({
    "data": {
      "type": "Campaign",
      "attributes": {
        "name": "Retailer Billed Campaign Q2",
        "startDate": "2026-07-01T00:00:00+00:00",
        "clickAttributionWindow": "30D",
        "viewAttributionWindow": "None",
        "retailerId": "1298",
        "drawableBalanceIds": ["814886589256347648"]
      }
    }
  })
  headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer &lt;TOKEN&gt;'}
  conn.request("POST", "/2026-01/retail-media/accounts/625702934721171442/campaigns", payload, headers)
  print(conn.getresponse().read().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\":{\"type\":\"Campaign\",\"attributes\":{\"name\":\"Retailer Billed Campaign Q2\",\"startDate\":\"2026-07-01T00:00:00+00:00\",\"clickAttributionWindow\":\"30D\",\"viewAttributionWindow\":\"None\",\"retailerId\":\"1298\",\"drawableBalanceIds\":[\"814886589256347648\"]}}}");
  Request request = new Request.Builder()
    .url("https://api.criteo.com/2026-01/retail-media/accounts/625702934721171442/campaigns")
    .method("POST", body)
    .addHeader("Content-Type", "application/json")
    .addHeader("Accept", "application/json")
    .addHeader("Authorization", "Bearer &lt;TOKEN&gt;")
    .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/2026-01/retail-media/accounts/625702934721171442/campaigns');
  $request->setMethod(HTTP_Request2::METHOD_POST);
  $request->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer &lt;TOKEN&gt;'));
  $request->setBody('{"data":{"type":"Campaign","attributes":{"name":"Retailer Billed Campaign Q2","startDate":"2026-07-01T00:00:00+00:00","clickAttributionWindow":"30D","viewAttributionWindow":"None","retailerId":"1298","drawableBalanceIds":["814886589256347648"]}}}');
  echo $request->send()->getBody();
  ```
</CodeGroup>

**Sample Response**

```json theme={null}
{
  "data": {
    "id": "718038552188952576",
    "type": "Campaign",
    "attributes": {
      "name": "Retailer Billed 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`.

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/2026-01/retail-media/accounts/{accountId}/campaigns
  ```
</EndpointBadge>

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/2026-01/retail-media/campaigns/{campaignId}
  ```
</EndpointBadge>

**Sample Request — Get a Single Campaign**

```bash theme={null}
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**

```json theme={null}
{
  "data": {
    "id": "718038552188952576",
    "type": "Campaign",
    "attributes": {
      "name": "Retailer Billed 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-billed campaigns, `targetRetailerId` is required and must match the campaign's `retailerId`. Only one retailer is allowed per retailer-billed campaign.

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/2026-01/retail-media/campaigns/{campaignId}/auction-line-items
  ```
</EndpointBadge>

**Sample Request**

<CodeGroup>
  ```bash cURL theme={null}
  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 Billed Line Item",
        "targetRetailerId": "1298",
        "startDate": "2026-07-01",
        "bidStrategy": "automated",
        "optimizationStrategy": "conversion",
        "keywordStrategy": "genericAndBranded"
      }
    }
  }'
  ```

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

  conn = http.client.HTTPSConnection("api.criteo.com")
  payload = json.dumps({
    "data": {
      "type": "SponsoredProductsLineItem",
      "attributes": {
        "name": "Retailer Billed Line Item",
        "targetRetailerId": "1298",
        "startDate": "2026-07-01",
        "bidStrategy": "automated",
        "optimizationStrategy": "conversion",
        "keywordStrategy": "genericAndBranded"
      }
    }
  })
  headers = {'Content-Type': 'application/json', 'Accept': 'application/json', 'Authorization': 'Bearer &lt;TOKEN&gt;'}
  conn.request("POST", "/2026-01/retail-media/campaigns/718038552188952576/auction-line-items", payload, headers)
  print(conn.getresponse().read().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\":{\"type\":\"SponsoredProductsLineItem\",\"attributes\":{\"name\":\"Retailer Billed Line Item\",\"targetRetailerId\":\"1298\",\"startDate\":\"2026-07-01\",\"bidStrategy\":\"automated\",\"optimizationStrategy\":\"conversion\",\"keywordStrategy\":\"genericAndBranded\"}}}");
  Request request = new Request.Builder()
    .url("https://api.criteo.com/2026-01/retail-media/campaigns/718038552188952576/auction-line-items")
    .method("POST", body)
    .addHeader("Content-Type", "application/json")
    .addHeader("Accept", "application/json")
    .addHeader("Authorization", "Bearer &lt;TOKEN&gt;")
    .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/2026-01/retail-media/campaigns/718038552188952576/auction-line-items');
  $request->setMethod(HTTP_Request2::METHOD_POST);
  $request->setHeader(array('Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Bearer &lt;TOKEN&gt;'));
  $request->setBody('{"data":{"type":"SponsoredProductsLineItem","attributes":{"name":"Retailer Billed Line Item","targetRetailerId":"1298","startDate":"2026-07-01","bidStrategy":"automated","optimizationStrategy":"conversion","keywordStrategy":"genericAndBranded"}}}');
  echo $request->send()->getBody();
  ```
</CodeGroup>

**Sample Response**

```json theme={null}
{
  "data": {
    "id": "234105251251242423",
    "type": "SponsoredProductsLineItem",
    "attributes": {
      "name": "Retailer Billed 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)**

```json theme={null}
{
  "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.

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

**Sample Request**

```bash theme={null}
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**

```json theme={null}
{
  "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

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

      <th>
        <p>
          Title
        </p>
      </th>

      <th>
        <p>
          Detail
        </p>
      </th>

      <th>
        <p>
          Troubleshooting
        </p>
      </th>
    </tr>
  </thead>

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

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

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

      <td />

      <td>
        <p>
          Request executed successfully.
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          🔴

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

      <td>
        <p>
          Retailer-billed balance mapping
        </p>
      </td>

      <td>
        <p>
          "Only retailer-sold campaigns are allowed to be mapped to a retailer-billed balance."
        </p>
      </td>

      <td>
        <p>
          Only campaigns scoped to the same retailer as the balance can be appended via

          <code>
            /campaigns/append
          </code>

          .
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          🔴

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

      <td>
        <p>
          <code>
            RetailerMismatchWithBalance
          </code>
        </p>
      </td>

      <td>
        <p>
          Campaign

          <code>
            retailerId
          </code>

          does not match the balance

          <code>
            retailerId
          </code>

          .
        </p>
      </td>

      <td>
        <p>
          Ensure the

          <code>
            retailerId
          </code>

          in campaign settings matches the

          <code>
            retailerId
          </code>

          on the balance you are associating.
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          🔴

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

      <td>
        <p>
          <code>
            RetailerMismatchWithCampaign
          </code>
        </p>
      </td>

      <td>
        <p>
          Line item

          <code>
            targetRetailerId
          </code>

          does not match the campaign

          <code>
            retailerId
          </code>

          .
        </p>
      </td>

      <td>
        <p>
          Ensure

          <code>
            targetRetailerId
          </code>

          on the line item matches the

          <code>
            retailerId
          </code>

          set on the parent campaign.
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          🔴

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

      <td>
        <p>
          <code>
            Error deserializing request
          </code>
        </p>
      </td>

      <td>
        <p>
          A required field is missing or has an invalid value.
        </p>
      </td>

      <td>
        <p>
          Review the request body against the attributes table above.
        </p>
      </td>
    </tr>

    <tr>
      <td>
        <p>
          🔴

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

      <td>
        <p>
          <code>
            Unauthorized
          </code>
        </p>
      </td>

      <td />

      <td>
        <p>
          Verify your access token and that your account has access to the retailer in question.
        </p>
      </td>
    </tr>
  </tbody>
</table>
