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

AttributeData TypeDescription
brandIdFilterlistBrand(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
retailerIdFilterlistRetailer(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
modifiedAftertimestampMofified 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
includeFieldslistAdditional 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

AttributeData TypeDescription
sellerslistretailerId: 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
modifiedAftertimestampMofified 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
includeFieldslistAdditional 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

AttributeData TypeDescription
idstringID of the catalog creation status request

Values: int64
typestringType definition of the response

Values: "RetailMediaCatalogStatus"
statusstringStatus of the response

Possible Values: pending, success, failure, expired, unknown
currencystringISO-4217 currency of the items in the respective catalog

Values: USD, EUR, etc.
rowCountintegerNumber of products contained in the catalog (available when creation reaches success status)

Max Value: 100000

Values: int32
fileSizeBytesintegerSize of catalog, in bytes (available when creation reaches success status)

Values: int32
md5ChecksumstringMD5 checksum of catalog's content (available when creation reaches success status)

Values: 32-char alpha-numeric strings
createdAttimestampTimestamp of the creation

Values: ISO-8601
messagestringOptional informative message, for developer consumptio

Catalog Output Response Attributes

AttributeData TypeDescription
idstringRetailer product ID, established by the retailer

Values: 500 char limit
namestringRetailer product name

Values: 1000 char limit
descriptionstringRetailer product description

Values: 5000 char limit
categorystringRetailer product category

Values: 1000 char limit
categoryIdstringCategory ID associated with the product, derived from the retailer catalog.
googleCategorystringCategory associated with the product, derived from the Google Product Taxonomy list.
brandIdstringBrand ID of the product

For brand accounts, it is derived from the Universal Catalog.
For retailer accounts, it is derived from the Retailer Catalog.
brandNamestringBrand name of the product; names are standardized across retailers

Values: 120 char limit
sellerIdstringSeller ID(s) in the respective retailers' catalogs, used to filter down catalog items.
sellerNamestringName of the seller associated with the sellerId.
retailerIdstringRetailer ID carrying the product

Values: int64
retailerNamestringName of the retailer associated with retailerId, carrying the product.

Values: 100 char limit
pricenumberRetailer product price in USD
isInStockbooleanWhether or not the product is in stock

Values: true, false
minBidnumberMinimum 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
gtinstringGlobal Trade Item Number (GTIN), if available; also known as European Article Number (EAN) or Universal Product Code (UPC)
mpnstringManufacturer Part Number (MPN), if available
imageUrlstringAn http image URL provided by the retailer
updatedAttimestampTimestamp 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

ResponseDescription
🟢200Success
🔴400The indicated catalog is not available for retrieval, wait for a success status
🔴403API user does not have the authorization to make requests to the account ID. For an authorization request, follow the authorization request steps