Catalog Endpoints
Generate and download a copy of retailer's inventory
Endpoints
Method | Endpoint | Description |
---|---|---|
POST | /accounts/{accountId}/brand-catalog-export | Create a request to export existing catalogs from a Brand account |
POST | /accounts/{accountId}/seller-catalog-export | Create a request to export existing catalogs from a Seller account |
GET | /catalogs/{catalogId}/status | Retrieve the status of a specific catalog request. |
GET | /catalogs/{catalogId}/output | Download the output of a specific catalog once it's ready. |
Attributes
Catalog Export Request Attributes
Brand Accounts
Attribute | Data Type | Description |
---|---|---|
brandIdFilter | list | 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 | 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 | 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 | 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 | 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 | 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 alpha-numeric strings |
createdAt | timestamp | Timestamp of the creation Values: ISO-8601 |
message | string | Optional informative message, for developer consumptio |
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 |
Updated 7 days ago