GuidesAPI ReferenceChangelog
GuidesAPI ReferenceChangelogLog In
Guides

Get Started

Setup your endpoints, view report attributes, and examples of requests

Endpoints

Four separate endpoints support requests to create campaign and line item reports and retrieve the report data and status.

VerbEndpointDescription
POST/reports/campaignsCreate a Campaign Report Request
POST/reports/line-itemsCreate a Line Item Report Request
GET/reports/{reportId}/statusGet Status of a Specific Report
GET/reports/{reportId}/outputDownload Output of a Specific Report

Report Request Attributes

id Required

    Data Type: string

    Description: Campaign or Line Item ID of the desired report

    Accepted Values a single or a group of campaignId or lineItemId e.g id: CampaignId, OR ids: ["CampaignId1","CampaignId2"], (maximum 50 ids per call)


metrics

    Data Type: string

    Description: Quantitative values associated to the campaign or line item

    Accepted Values:

  • Campaign Report
  • impressions, clicks, spend, attributedSales, attributedUnits, attributedOrders, ctr, cpc, cpo, cpm, roas, uniqueVisitors, frequency, assistedUnits, assistedSales

  • Line-item report
  • impressions, clicks, spend, attributedSales, attributedUnits, attributedOrders, ctr, cpc, cpo, roas, assistedUnits, assistedSales, uniqueVisitors, frequency

dimensions

    Data Type: string

    Description: Attributes of your campaign or line item data

    Accepted Values:

  • Campaign Report
  • date, campaignId, campaignName, campaignTypeName, advProductCategory, advProductId, advProductName, brandId, brandName, pageTypeName, environment, keyword, salesChannel, retailerId, retailerName, searchTerm

  • Line-item Report
  • date, campaignId, campaignName, campaignTypeName, advProductCategory, advProductId, advProductName, brandId, brandName, lineItemId, lineItemName, retailerId, retailerName, keyword, pageTypeName, salesChannel, environment, searchTerm

reportType

    Data Type: string

    Description: Type of report requested

    Accepted Values summary, pageType, keyword, productCategory, product, attributedTransactions, servedCategory, environment


startDate Required

    Data Type: date

    Description: Earliest day to report; inclusive

    Accepted Values: YYYY-MM-DD


endDate Required

    Data Type: date

    Description: Latest day to report; inclusive

    Accepted Values: YYYY-MM-DD


campaignType

    Data Type: enum

    Description: The campaign type

    Accepted Values: sponsoredProducts, onSiteDisplays


timeZone Required

    Data Type: string

    Description: Time zone for the report

    Accepted Values: database tz syntax, eg. America/New_York, Europe/Paris, UTC


clickAttributionWindow Required

    Data Type: string

    Description: The post-click attribution window, defined as the maximum number of days considered between a click and a conversion for attribution; conversions are attributed to the date of conversion, not the date of click; defaults to campaign settings if omitted; must be specified if viewAttributionWindow is one of the accepted values.

    Accepted Values: 7D, 14D,30D


viewAttributionWindow Required

    Data Type: string

    Description: The post-view attribution window, defined as the maximum number of days considered between an impression and a conversion for attribution; conversions are attributed to the date of conversion, not the date of impression; defaults to campaign settings if omitted; must be less than or equal to clickAttributionWindow; must be specified if clickAttributionWindow is one of the accepted values.

    Accepted Values: none, 1D,7D, 14D, 30D


salesChannel

    Data Type: string

    Description:Filter on specific sales channel: offline or online

    Accepted Values: offline, online


format Optional

    Data Type: string

    Description: Format of the report data returned

    Accepted Values: json-compact, json-newline, json (default), csv


📘

Reporting Asynchronous Workflow: Step 1 of 3

  • First, create a request for the campaign or line item report with the desired attributes
  • This generates a reportId representing the report

Create a Report Request

Reporting endpoints provide two separate endpoints that allow downloading reports at the campaign or line item level. Each of the following requests can be repeated for each individual report type

https://api.criteo.com/{version}/retail-media/reports/campaigns

Sample Request - Campaign Report

curl -X POST "https://api.criteo.com/{version}/retail-media/reports/campaigns" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>" \
    -H "Content-Type: application/json" \
    -d '{
            "data": {
                "type": "RetailMediaReportRequest",
                "attributes": {
                    "id": "8343086999167541140",
                    "metrics": ["impressions"],
      						  "dimensions": ["date"],
                    "reportType": "summary",
                    "startDate": "2020-04-06",
                    "endDate": "2020-06-04",
                    "timeZone": "America/New_York",
                    "campaignType": "sponsoredProducts",
      						  "salesChannel": "offline"
                }
            }
        }'
import requests
import json

url = "https://api.criteo.com/2023-07/retail-media/reports/campaigns"

payload = json.dumps({
  "data": {
    "type": "RetailMediaReportRequest",
    "attributes": {
      "id": "1285",
      "metrics": [
       		 "impressions"
      		 ],
      "dimensions": [
     		   "date"
     			 ],
      "reportType": "summary",
      "startDate": "2022-06-06",
      "endDate": "2022-07-04",
      "timeZone": "America/New_York",
      "campaignType": "sponsoredProducts",
      "salesChannel": "offline"
    }
  }
})
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\": \"RetailMediaReportRequest\",\n                \"attributes\": {\n                    \"id\": \"8343086999167541140\",\n                    \"metrics\": [\n       \t\t\t\t\t\t\t\t \"impressions\"\n      \t\t\t\t\t\t\t\t ],\n      \t\t\t\t\t\t  \"dimensions\": [\n        \t\t\t\t\t\t   \"date\"\n      \t\t\t\t\t\t\t\t ],\n                    \"reportType\": \"summary\",\n                    \"startDate\": \"2020-04-06\",\n                    \"endDate\": \"2020-06-04\",\n                    \"timeZone\": \"America/New_York\",\n                    \"campaignType\": \"sponsoredProducts\",\n      \t\t\t\t\t\t  \"salesChannel\": \"offline\"\n                }\n            }\n        }");

Request request = new Request.Builder()
  .url("https://api.criteo.com/2023-07/retail-media/reports/campaigns")
  .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/reports/campaigns');
$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\": \"RetailMediaReportRequest\",\n                \"attributes\": {\n                    \"id\": \"8343086999167541140\",\n                    \"metrics\": [\n       \t\t\t\t\t\t\t\t \"impressions\"\n      \t\t\t\t\t\t\t\t ],\n      \t\t\t\t\t\t  \"dimensions\": [\n        \t\t\t\t\t\t   \"date\"\n      \t\t\t\t\t\t\t\t ],\n                    \"reportType\": \"summary\",\n                    \"startDate\": \"2020-04-06\",\n                    \"endDate\": \"2020-06-04\",\n                    \"timeZone\": \"America/New_York\",\n                    \"campaignType\": \"sponsoredProducts\",\n      \t\t\t\t\t\t  \"salesChannel\": \"offline\"\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();
}
https://api.criteo.com/{version}/retail-media/reports/line-items

Sample Request - Line Item Report

curl -X POST "https://api.criteo.com/{version}/retail-media/reports/line-items" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>" \
    -H "Content-Type: application/json" \
    -d '{
            "data": {
                "type": "RetailMediaReportRequest",
                "attributes": {
                    "id": "8343086999167541140",
                    "metrics": [ "impressions"],
      						  "dimensions": ["date"],
                    "reportType": "summary",
                    "startDate": "2020-04-06",
                    "endDate": "2020-06-04",
                    "timeZone": "America/New_York",
                    "campaignType": "sponsoredProducts",
      						  "salesChannel": "offline"
                }
            }
        }'
import requests
import json

url = "https://api.criteo.com/2023-07/retail-media/reports/line-items"

payload = json.dumps({
  "data": {
    "type": "RetailMediaReportRequest",
    "attributes": {
      "id": "1285",
      "metrics": [
       		 "impressions"
      		 ],
      "dimensions": [
     		   "date"
     			 ],
      "reportType": "summary",
      "startDate": "2022-06-06",
      "endDate": "2022-07-04",
      "timeZone": "America/New_York",
      "campaignType": "sponsoredProducts",
      "salesChannel": "offline"
    }
  }
})
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\": \"RetailMediaReportRequest\",\n                \"attributes\": {\n                    \"id\": \"8343086999167541140\",\n                    \"metrics\": [\n       \t\t\t\t\t\t\t\t \"impressions\"\n      \t\t\t\t\t\t\t\t ],\n      \t\t\t\t\t\t  \"dimensions\": [\n        \t\t\t\t\t\t   \"date\"\n      \t\t\t\t\t\t\t\t ],\n                    \"reportType\": \"summary\",\n                    \"startDate\": \"2020-04-06\",\n                    \"endDate\": \"2020-06-04\",\n                    \"timeZone\": \"America/New_York\",\n                    \"campaignType\": \"sponsoredProducts\",\n      \t\t\t\t\t\t  \"salesChannel\": \"offline\"\n                }\n            }\n        }");

Request request = new Request.Builder()
  .url("https://api.criteo.com/2023-07/retail-media/reports/line-items")
  .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/reports/line-items');
$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\": \"RetailMediaReportRequest\",\n                \"attributes\": {\n                    \"id\": \"8343086999167541140\",\n                    \"metrics\": [\n       \t\t\t\t\t\t\t\t \"impressions\"\n      \t\t\t\t\t\t\t\t ],\n      \t\t\t\t\t\t  \"dimensions\": [\n        \t\t\t\t\t\t   \"date\"\n      \t\t\t\t\t\t\t\t ],\n                    \"reportType\": \"summary\",\n                    \"startDate\": \"2020-04-06\",\n                    \"endDate\": \"2020-06-04\",\n                    \"timeZone\": \"America/New_York\",\n                    \"campaignType\": \"sponsoredProducts\",\n      \t\t\t\t\t\t  \"salesChannel\": \"offline\"\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 - Both

{
    "data": {
        "type": "RetailMediaReportStatus",
        "id": "2e733b8c-9983-4237-aab9-17a42f4267cb",
        "attributes": {
            "status": "pending",
            "rowCount": null,
            "fileSizeBytes": null,
            "md5Checksum": null,
            "createdAt": null,
            "expiresAt": null,
            "message": null
        }
    }
}

📘

Reporting Asynchronous Workflow: Step 2 of 3

  • Next, use the reportId to poll the report status endpoint until one is successfully computed

Get Status of a Specific Report

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

https://api.criteo.com/{version}/retail-media/reports/{reportId}/status

Sample Request

curl -X GET "https://api.criteo.com/{version}/retail-media/reports/2e733b8c-9983-4237-aab9-17a42f4267cb/status" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
import requests

url = "https://api.criteo.com/2023-07/retail-media/reports/73fb7859-301f-4371-be91-3e4ad00964aa/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/reports/73fb7859-301f-4371-be91-3e4ad00964aa/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/reports/73fb7859-301f-4371-be91-3e4ad00964aa/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": {
        "attributes": {
            "status": "success",
            "rowCount": 50,
            "fileSizeBytes": 9711,
            "md5CheckSum": "b92bf24cd899f172907f8b001b8a5edb",
            "createdAt": "2023-07-19T19:40:27.000Z",
            "expiresAt": "2023-07-26T19:40:30.000Z",
            "message": "rows_count=50",
            "id": "16d70ce4-6917-48b8-8a55-184809dd59b5"
        },
        "id": "16d70ce4-6917-48b8-8a55-184809dd59b5",
        "type": "StatusResponse"
    },
    "warnings": [],
    "errors": []
}

📘

Reporting Asynchronous Workflow: Step 3 of 3

  • Finally, download the report using the report output endpoint
  • Report outputs are cached for at least 1 hour before expiration
  • Exact expiration is indicated by the expiresAt field in the /status response

Download Output of a Specific Report

This endpoint returns the specific report in the requested format

https://api.criteo.com/{version}/retail-media/reports/{reportId}/output

Sample Request

curl -X GET "https://api.criteo.com/{version}/retail-media/reports/2e733b8c-9983-4237-aab9-17a42f4267cb/output" \
    -H "Authorization: Bearer <MY_ACCESS_TOKEN>"
import requests

url = "https://api.criteo.com/2023-07/retail-media/reports/73fb7859-301f-4371-be91-3e4ad00964aa/output"

payload={}
headers = {
  'Accept': 'application/octet-stream',
  '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/reports/73fb7859-301f-4371-be91-3e4ad00964aa/output")
  .method("GET", body)
  .addHeader("Accept", "application/octet-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/reports/73fb7859-301f-4371-be91-3e4ad00964aa/output');
$request->setMethod(HTTP_Request2::METHOD_GET);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Accept' => 'application/octet-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

Campaign Summary Report

// format="json-compact"

// CAMPAING SUMMARY REPORT

{"columns":[ "campaignId", "campaignName", "campaignTypeName", "date", "impressions", "clicks", "attributedOrders", "attributedUnits", "attributedSales", "ctr", "spend", "cpc", "cpo", "roas", "uniqueVisitors", "frequency" ], 

  "data":[ 
            [ "1285", "End of Summer Sale", "Open Auction", "2021-01-31", 0, 0, 1, 1, 76.9400, null, 0.0000, null, 0.0000, null, null, null ] ,
            [ "1285", "End of Summer Sale", "Open Auction", "2021-01-29", 1883, 6, 8, 8, 1749.2600, 0.0032, 3.7000, 0.6167, 0.4625, 472.7730, null, null ] ,
            [ "1285", "End of Summer Sale", "Open Auction", "2021-02-04", 0, 0, 1, 1, 99.4600, null, 0.0000, null, 0.0000, null, null, null ] ,
            [ "1285", "End of Summer Sale", "Open Auction", "2021-01-28", 35087, 107, 25, 25, 4381.2700, 0.0030, 96.3000, 0.9000, 3.8520, 45.4961, null, null ] 
				], 
"rows":4
}

Campaign Attribution Report

// format="json-compact"

//CAMPAIGN ATTRIBUTION REPORT
{
    "columns": [
        "purchasedDate", "purchasedHour", "advDate", "advHour", "daysDifference", "campaignId", "campaignName", "lineItemId", "lineItemName", "advProductId", "advProductGtin", "advProductMpn", 
        "advProductName", "advProductCategory", "purchasedProductId", "purchasedProductGtin", "purchasedProductMpn", "purchasedProductName", "purchasedProductCategory", "attributedUnits", 
        "attributedSales", "advEngagement", "advToPurchasedProductRelationship", "salesChannel", "retailerName", "pageTypeName", "keyword", "attributionWindow"
    ],
    "data": [
        [
          "2022-10-21", 16, "2022-10-21", 16, 0, "1344", "End to end testing", "2602", "LJ Test", "426292", null, null, "Arm & Hammer Pure Baking Soda, 13.5 lbs", 
          "hardware > tools > hammers > powered hammers", "426292", null, null, "Arm & Hammer Pure Baking Soda, 13.5 lbs",
          "hardware > tools > hammers > powered hammers", 1, 8.6900, "click", "same sku", "online", "Costco", "category", "", "C30V01"
        ]
    ],
    "rows": 1
}

Responses

ResponseDescription
🔵 200Call executed with success

Report Type has been ignored - Report Type has been ignored since Dimensions and Metrics has been provided. Please remove them if you want to use one of the templates.

When generating a report type using the metrics and dimensions filters for multi dimension reporting, a warning message will be presented in the 200 to inform that reportType is ignored. This is because multi dimension takes priority in this scenario.
🔴 400Common Validation Errors

- endDate cannot be more than 100 days from startDate - Using a date range with more than 100 days apart
- reportType invalid - calling an unsupported report type will throw a 400 error
- timeZone must be a valid timezone - using a time zone value that is not listed in the list tz database time zones
- format invalid - using an unsupported file format