GuidesAPI ReferenceChangelog
GuidesAPI ReferenceChangelogLog In
Guides

Catalog

Generate and download a copy of retailer's inventory

Endpoints

VerbEndpointDescription
POST/accounts/{accountId}/catalogsCreate a Catalog Request
GET/catalogs/{catalogId}/statusGet Status of a Specific Catalog
GET/catalogs/{catalogId}/outputDownload Output of a Specific Catalog

Catalog Body Parameters

format Optional

    Data Type: string

    Description: Format of the catalog data returned

    Values: json-newline


brandIDFilter Optional

    Data Type: string

    Description: Brand(s) ids used to filter down catalog results based on specified brands

    Values: int64


💭

Best Practice Tip!

Narrow down catalog downloads by brands using the brandIdFilter body parameter. Doing so can help return catalog results faster.

 

Catalog Response Attributes

id

    Data Type: string

    Values: 500 char limit

    Description: Retailer product ID, established by the retailer


name

    Data Type: string

    Values: 1000 char limit

    Description: Retailer product name


category

    Data Type: string

    Values: 1000 char limit

    Description: Retailer product category


brandName

    Data Type: string

    Values: 120 char limit

    Description: Brand name of the product; names are standardized across retailers


retailerId

    Data Type: string

    Values: int64

    Description: Retailer ID carrying the product


retailerName

    Data Type: string

    Values: 100 char limit

    Description: Retailer name carrying the product


price

    Data Type: number

    Values: -

    Description: Retailer product price in USD


isInStock

    Data Type: boolean

    Values: true, false

    Description: Whether or not the product is in stock


minBid

    Data Type: number

    Values: greater than 0

    Description: 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


gtin

    Data Type: string

    Values: -

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


mpn

    Data Type: string

    Values: -

    Description: Manufacturer Part Number (MPN), if available


imageUrl

    Data Type: string

    Values: -

    Description: An http image URL provided by the retailer


updatedAt

    Data Type: timestamp

    Values: ISO-8601

    Description: Timestamp in UTC of last update


📘

Catalog Asynchronous Workflow: Step 1 of 3

1st. Create a request for the latest catalog of the specified account
2nd. This generates a catalogId representing the account catalog
3rd. Catalog requests are cached for 1 hour.

 

Create a Catalog Request

This endpoint creates a request for the latest available catalog for a specific account

https://api.criteo.com/{version}/retail-media/accounts/{accountId}/catalogs

Sample Request

curl -L -X POST 'https://api.criteo.com/{version}/retail-media/accounts/4/catalogs' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <MY_ACCESS_TOKEN>' \
--data-raw '{
  "data": {
    "type": "RetailMediaCatalogStatus",
    "attributes": {
      "format": "json-newline",
      "brandIdFilter": [
        "40115",
        "9092"
      ]
    }
  }
}'
import requests
import json

url = "https://api.criteo.com/2023-07/retail-media/accounts/4/catalogs"

payload = json.dumps({
  "data": {
    "type": "<string>",
    "attributes": {
      "format": "json-newline",
      "brandIdFilter": [
        "4768"
      ]
    }
  }
})
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      \"format\": \"json-newline\",\n      \"brandIdFilter\": [\n        \"4768\"\n      ]\n    }\n  }\n}");

Request request = new Request.Builder()
  .url("https://api.criteo.com/2023-07/retail-media/accounts/4/catalogs")
  .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/2023-07/retail-media/accounts/4/catalogs');
$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      "format": "json-newline",\n      "brandIdFilter": [\n        "4768"\n      ]\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": "2020-04-06T05:11:41.351+00:00",
            "message": null
        }
    }
}

📘

Catalog Asynchronous Workflow: Step 2 of 3

Next, use the catalogId to poll the catalog status endpoint until one is successfully created.

 

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/2023-07/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/2023-07/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/2023-07/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
        }
    }
}

📘

Catalog Asynchronous Workflow: Step 3 of 3

Finally, download the collection of catalog products using the catalog output endpoint. Catalog outputs typically have an expiration of 72 hours

 

Download Output of a Specific Catalog

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

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", "/2023-07/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/2023-07/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/2023-07/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": "sku1", \
    "name": "Product One", \
    "category": "category1", \
    "brandId": "7672171780147256541", \
    "brandName": "Brand 123", \
    "retailerId": "3239117063738827231", \
    "retailerName": "Retailer 123", \
    "price": 1.00, \
    "isInStock": true, \
    "minBid": 0.30, \
    "gtin": "abc123", \
    "mpn": "789xyz", \
    "imageUrl": "/image1.jpg", \
    "updatedAt": "2020-04-06T02:23:07Z" \
}
 
// ... newline-delimited, no comma
 
{ \
    "id": "product-1001", \
    "name": "Product One Thousand and One", \
    "category": "category2", \
    "brandId": "7672171780147256541", \
    "brandName": "Brand 123", \
    "retailerId": "18159942378514859684", \
    "retailerName": "Retailer 789", \
    "price": 5.00, \
    "isInStock": false, \
    "minBid": 0.45, \
    "gtin": "none", \
    "mpn": "none", \
    "imageUrl": "/image1001.jpg", \
    "updatedAt": "2020-04-06T01:07:23Z" \
}

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