Catalog Endpoints

Generate and download a copy of retailer's inventory

Endpoints

MethodEndpointDescription
POST/accounts/{accountId}/brand-catalog-exportCreate a request to export existing catalogs from a Brand account
POST/accounts/{accountId}/seller-catalog-exportCreate a request to export existing catalogs from a Seller account
GET/catalogs/{catalogId}/statusRetrieve the status of a specific catalog request.
GET/catalogs/{catalogId}/outputDownload the output of a specific catalog once it's ready.

Attributes

Catalog Export Request Attributes

Brand Accounts

Attribute

Data Type

Description

brandIdFilter

list<string>

Brand(s) ids used to filter down catalog results based on specified brands. Note: If nothing is entered, you will get all brands

Accepted values: int64

retailerIdFilter

list<string>

Retailer(s) ids used to filter down catalog results based on specified retailers. Note: If nothing is entered you will get all retailers

Accepted values: int64

modifiedAfter

timestamp

Modifie stamp which will only include the SKUs modified after the specified time. The upper limit of this field is set to -18 hours from current time. After which, the user will be asked to do a full export instead.

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601

includeFields

list<string>

Additional fields that can be added to the catalog export. If they are not included, when the output endpoint is called, the fields will return with “null” values.

Accepted values: "RetailerName","Description", "BrandName","GoogleCategory","Category","ImageUrl"


Seller Accounts

Attribute

Data Type

Description

sellers

list<object>

retailerId: The id that represents the retailer providing advertising inventory for brands to promote their products.

Accepted values: string

sellerId: Seller id(s) in respective retailers' catalogs, used to filter down catalog items.

Accepted values: string

modifiedAfter

timestamp

Mofified timestamp which will only include the skus modified after the specified time. Upper limit of this field is set to -18 hours from current time. After which user will be asked to do a full export instead.

Accepted values: yyyy-mm-ddThh:mm:ss±hh:mm (in ISO-8601

includeFields

list<string>

Additional fields that can be added to the catalog export. If they are not included, when the output endpoint is called, the fields will return with “null” values.

Accepted values: "RetailerName","Description", "BrandName","GoogleCategory","Category","ImageUrl"


Catalog Status Response Attributes

Attribute

Data Type

Description

id

string

ID of the catalog creation status request

Values: int64

type

string

Type definition of the response

Values: "RetailMediaCatalogStatus"

status

string

Status of the response

Possible Values: pending, success, failure, expired, unknown

currency

string

ISO-4217 currency of the items in the respective catalog

Values: USD, EUR, etc.

rowCount

integer

Number of products contained in the catalog (available when creation reaches success status)

Max Value: 100000

Values: int32

fileSizeBytes

integer

Size of catalog, in bytes (available when creation reaches success status)

Values: int32

md5Checksum

string

MD5 checksum of catalog's content (available when creation reaches success status)

Values: 32-char alphalphanumeric strings

createdAt

timestamp

Timestamp of the creation

Values: ISO-8601

message

string

Optional informative message, for developer consconsumption


Catalog Output Response Attributes

Attribute

Data Type

Description

id

string

Retailer product ID, established by the retailer

Values: 500 char limit

name

string

Retailer product name

Values: 1000 char limit

description

string

Retailer product description

Values: 5000 char limit

category

string

Retailer product category

Values: 1000 char limit

categoryId

string

Category ID associated with the product, derived from the retailer catalog.

googleCategory

string

Category associated with the product, derived from the Google Product Taxonomy list.

brandId

string

Brand ID of the product

For brand accounts, it is derived from the Universal Catalog.
For retailer accounts, it is derived from the Retailer Catalog.

brandName

string

Brand name of the product; names are standardized across retailers

Values: 120 char limit

sellerId

string

Seller ID(s) in the respective retailers' catalogs, used to filter down catalog items.

sellerName

string

Name of the seller associated with the sellerId.

retailerId

string

Retailer ID carrying the product

Values: int64

retailerName

string

Name of the retailer associated with retailerId, carrying the product.

Values: 100 char limit

price

number

Retailer product price in USD

isInStock

boolean

Whether or not the product is in stock

Values: true, false

minBid

number

Minimum Cost-Per-Click (CPC) an advertiser must bid for the product, established by the retailer; any line item with this product must have targetBid meet this value

Values: greater than 0

gtin

string

Global Trade Item Number (GTIN), if available; also known as European Article Number (EAN) or Universal Product Code (UPC)

mpn

string

Manufacturer Part Number (MPN), if available

imageUrl

string

An http image URL provided by the retailer

updatedAt

timestamp

Timestamp in UTC of last update

Values: ISO-8601


Export Catalog of a Specific Account

Brand account

This endpoint allows you to generate the most up-to-date catalog for a specific brand account.

https://api.criteo.com/{version}/retail-media/accounts/{accountId}/brand-catalog-export
💭

Best Practice Tip!

If you wish to filter SKUs modified within the last 18 hours, you can use modifiedAfter field. The request should be formatted according to ISO 8601 standards. Although the example provided uses Eastern Standard Time (EST), you can specify any time zone.

Important: If the specified time exceeds the 18-hour limit, the request will return a 400 response, advising you to perform a full catalog export instead.

Sample Request

curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/4/brand-catalog-export' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
--data-raw '{
  "data": {
    "type": "<string>",
    "attributes": {
      "brandIdFilter": [
        "123"
      ],
      "retailerIdFilter": [
        "456"
      ],
      "modifiedAfter": "2025-03-21T08:00:00-5:00",
      "includeFields": ["ImageUrl","GoogleCategory", "RetailerName", "Category", "BrandName","Description"]
    }
  }
}'
import requests
import json

url = "https://api.criteo.com/{version}/retail-media/accounts/4/brand-catalog-export"

payload = json.dumps({
  "data": {
    "type": "<string>",
    "attributes": {
      "brandIdFilter": [
        "123"
      ],
      "retailerIdFilter": [
        "456"
      ],
      "modifiedAfter": "2025-03-21T08:00:00-5:00",
      "includeFields": ["ImageUrl","GoogleCategory", "RetailerName", "Category", "BrandName","Description"]
    }
  }
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer <MY_ACCESS_TOKEN>'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();

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

RequestBody body = RequestBody.create(mediaType, "{\n  \"data\": {\n   \"type\": \"<string>\",\n   \"attributes\": {\n     \"brandIdFilter\": [\n       \"123\"\n     ],\n     \"retailerIdFilter\": [\n       \"456\"\n     ],\n     \"modifiedAfter\": \"2025-03-21T08:00:00-5:00\",\n     \"includeFields\": [\"ImageUrl\",\"GoogleCategory\", \"RetailerName\", \"Category\", \"BrandName\",\"Description\"]\n   }\n }\n}");

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

$request->setHeader(array(
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer <MY_ACCESS_TOKEN>'
));

$request->setBody('{\n  "data": {\n   "type": "<string>",\n   "attributes": {\n     "brandIdFilter": [\n       "123"\n     ],\n     "retailerIdFilter": [\n       "456"\n     ],\n     "modifiedAfter": "2025-03-21T08:00:00-5:00",\n     "includeFields": ["ImageUrl","GoogleCategory", "RetailerName", "Category", "BrandName","Description"]\n   }\n }\n}');
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();
}

Sample Response

{
    "data": {
        "type": "RetailMediaCatalogStatus",
        "id": "1122850670915847014",
        "attributes": {
            "status": "pending",
            "currency": null,
            "rowCount": null,
            "fileSizeBytes": null,
            "md5Checksum": null,
            "createdAt": "2025-01-22T23:10:12.21+00:00",
            "message": null
        }
    }
}

Seller account

This endpoint allows you to generate the most up-to-date catalog for a specific seller account.

https://api.criteo.com/{version}/retail-media/accounts/{accountId}/seller-catalog-export

Sample Request

curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/4/seller-catalog-export' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
--data-raw '{
  "data": {
    "type": "<string>",
    "attributes": {
      "sellers": [
        {
          "retailerId": "123",
          "sellerId": "5e0axxxxxxxxxx"
        }
      ],
      "modifiedAfter": "",
      "includeFields": [
        "ImageUrl",
        "Description"
      ]
    }
  }
}'
import requests
import json

url = "https://api.criteo.com/{version}/retail-media/accounts/4/seller-catalog-export"

payload = json.dumps({
  "data": {
    "type": "<string>",
    "attributes": {
      "sellers": [
        {
          "retailerId": "123",
          "sellerId": "5e0axxxxxxxxxx"
        }
      ],
      "modifiedAfter": "",
      "includeFields": [
        "ImageUrl",
        "Description"
      ]
    }
  }
})
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Authorization': 'Bearer <MY_ACCESS_TOKEN>'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();

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

RequestBody body = RequestBody.create(mediaType, "{\n \"data\": {\n   \"type\": \"<string>\",\n   \"attributes\": {\n     \"sellers\": [\n       {\n         \"retailerId\": \"123\",\n         \"sellerId\": \"5e0axxxxxxxxxx\"\n       }\n     ],\n     \"modifiedAfter\": \"\",\n     \"includeFields\": [\n     \"ImageUrl\",\n     \"Description\"\n     ]\n   }\n }}");

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

$request->setHeader(array(
  'Content-Type' => 'application/json',
  'Accept' => 'application/json',
  'Authorization' => 'Bearer <MY_ACCESS_TOKEN>'
));

$request->setBody('{\n "data": {\n   "type": "<string>",\n   "attributes": {\n     "sellers": [\n       {\n         "retailerId": "123",\n         "sellerId": "5e0axxxxxxxxxx"\n       }\n     ],\n     "modifiedAfter": "",\n     "includeFields": [\n     "ImageUrl",\n     "Description"\n     ]\n   }\n }}');
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();
}

Sample Response

{
    "data": {
        "type": "RetailMediaCatalogStatus",
        "id": "1122850670915847014",
        "attributes": {
            "status": "pending",
            "currency": null,
            "rowCount": null,
            "fileSizeBytes": null,
            "md5Checksum": null,
            "createdAt": "2025-01-22T23:10:12.21+00:00",
            "message": null
        }
    }
}

Get Status of a Specific Catalog

This endpoint retrieves the status of a specific catalog. Status can be pending, success, failure, or expired

https://api.criteo.com/{version}/retail-media/catalogs/{catalogId}/status

Sample Request

curl -X GET "https://api.criteo.com/{version}/retail-media/catalogs/1122850670915847014/status" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
import requests

url = "https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/status"

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

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();

MediaType mediaType = MediaType.parse("text/plain");

RequestBody body = RequestBody.create(mediaType, "");

Request request = new Request.Builder()
  .url("https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/status")
  .method("GET", body)
  .addHeader("Accept", "application/json")
  .addHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
  .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/catalogs/357957813719011328/status');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Accept' => 'application/json',
  'Authorization' => 'Bearer <MY_ACCESS_TOKEN>'
));

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();
}

Sample Response

{
    "data": {
        "type": "RetailMediaCatalogStatus",
        "id": "1122850670915847014",
        "attributes": {
            "status": "success",
            "currency": "USD",
            "rowCount": 1001,
            "fileSizeBytes": 353293,
            "md5Checksum": "2c15b77740028435ca476823df7fb4f8",
            "createdAt": "2020-04-06T05:11:41.351+00:00",
            "message": null
        }
    }
}


Download Output of a Specific Catalog

This endpoint returns the products in a specific catalog as a newline-delimited JSON byte stream

NOTE: The limit will be capped at 100000 rows. If a user reaches this limit, they will need to revise their request to fall within the limit.

https://api.criteo.com/{version}/retail-media/catalogs/{catalogId}/output

Sample Request

curl -X GET "https://api.criteo.com/{version}/retail-media/catalogs/1122850670915847014/output" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
import http.client

conn = http.client.HTTPSConnection("api.criteo.com")
payload = ''
headers = {
  'Accept': 'application/x-json-stream',
  'Authorization': 'Bearer <MY_ACCESS_TOKEN>'
}
conn.request("GET", "/{version}/retail-media/catalogs/357957813719011328/output", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();

MediaType mediaType = MediaType.parse("text/plain");

RequestBody body = RequestBody.create(mediaType, "");

Request request = new Request.Builder()
  .url("https://api.criteo.com/{version}/retail-media/catalogs/357957813719011328/output")
  .method("GET", body)
  .addHeader("Accept", "application/x-json-stream")
  .addHeader("Authorization", "Bearer <MY_ACCESS_TOKEN>")
  .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/catalogs/357957813719011328/output');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Accept' => 'application/x-json-stream',
  'Authorization' => 'Bearer <MY_ACCESS_TOKEN>'
));

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();
}

Sample Response

{ \
    "id": "sku_1", \
    "name": "Product Name", \
    "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \
    "categoryId": "1234xxxx", \
    "brandId": "123456xxxxxx", \
    "brandName": "Brand Name", \
    "retailerId": "54321xxxxxx", \
    "retailerName": "Retailer Name", \
    "price": 1.00, \
    "isInStock": true, \
    "minBid": 0.30, \
    "gtin": "abc12xx", \
    "mpn": "34abxxx", \
    "imageUrl": "/image1.jpg", \
    "updatedAt": "2020-04-06T02:23:07Z", \
    "sellerId": "60axxxxxxxxxxxxxxxx", \
    "sellerName": "Seller Name", \
    "googleCategory": null, \
    "description": "Product's Description" \
}
 
// ... newline-delimited, no comma
 
{ \
    "id": "sku_2", \
    "name": "Product Name", \
    "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \
    "categoryId": "1234xxxx", \
    "brandId": "567890xxxxxx", \
    "brandName": "Brand Name", \
    "retailerId": "098765xxxxxx", \
    "retailerName": "Retailer Name", \
    "price": 1.00, \
    "isInStock": true, \
    "minBid": 0.30, \
    "gtin": "xyz12xx", \
    "mpn": "78asdxxx", \
    "imageUrl": "/image1.jpg", \
    "updatedAt": "2020-04-06T02:23:07Z", \
    "sellerId": null, \
    "sellerName": "Seller Name", \
    "googleCategory": null, \
    "description": "Product's Description" \
}

// ... newline-delimited, no comma
 
{ \
    "id": "sku_3", \
    "name": "Product Name", \
    "category": "clothing, shoes & accessories|men’s clothing|bottoms|shorts", \
    "categoryId": "4568xxxx", \
    "brandId": "96385xxxxxx", \
    "brandName": "Brand Name", \
    "retailerId": "412587xxxxxx", \
    "retailerName": "Retailer Name", \
    "price": 1.00, \
    "isInStock": true, \
    "minBid": 0.30, \
    "gtin": "xyz12xx", \
    "mpn": "56wsdxxx", \
    "imageUrl": "/image1.jpg", \
    "updatedAt": "2020-04-06T02:23:07Z", \
    "sellerId": null, \
    "sellerName": null, \
    "googleCategory": null, \
    "description": "Product's Description" \
}

Responses

Response

Description

🟢

200

Success

🔴

400

The indicated catalog is not available for retrieval, wait for a success status

🔴

403

API user does not have the authorization to make requests to the account ID. For an authorization request, follow the

authorization request

steps