Skip to main content

Overview

The Product Level Reporting API provides product-level (SKU) performance data for Marketplace Performance Outcomes (MPO). It is designed for use cases where you need to understand how individual products perform across clicks, displays, and cost -at a granularity that campaign or seller-level reporting does not provide. This API is asynchronous and file-based. Because product-level reports cover every product with activity in the requested period, they are designed for large-scale data export: you create a report job, poll for its status, and download the result as a CSV or JSON file once it is ready. Totals returned by this API reconcile with the MPO Statistics API for the same scope and period.

When to Use This API

Use the Product Level Reporting API when you need to:
  • Analyze performance at individual product level across sellers and campaigns
  • Export complete product-level data with no truncation -all products with activity in the period are included
  • Understand product-level cost and delivery (clicks, displays) for BI or data warehouse use
  • Filter performance by advertiser, campaign, ad set.
For seller-level or campaign-level aggregated reporting, use the MPO Standard Reporting API instead. For near real-time product monitoring, use the MPO Real-Time Asynchronous API instead.

Campaign vs Ad Set -Terminology

This API follows the standard MPO object model: campaignId refers to the marketing campaign, and adSetId refers to the ad set -the buying entity below the campaign. Legacy MPO APIs use the term campaignId to refer to what this API calls adSetId. If your integration uses the legacy campaignId to identify a buying entity, that same ID maps to adSetId here. The campaignId dimension and filter in this API refer to the marketing campaign and are available for MPO Pro only.

How It Works

The API follows a three-step asynchronous flow:
  1. Create a report job (POST /product-reports/export)
  2. Poll for job status (GET /report-jobs/{reportId})
  3. Download the report once ready (GET /product-reports/{reportId})
Report jobs are cached. If you submit an identical request within the configured freshness window, the API may return a DONE status immediately with the cached result. Reports contain totals over the requested interval -there is no time breakdown or date column in the output.

Endpoint Reference

1. Create Report Job

POST https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/product-reports/export
Creates a new asynchronous product-level report job. Returns a reportId to use in subsequent status and download calls.

Request Body

{
"data": {
"type": "ProductReportJob",
"attributes": {
"fileFormat": "csv",
"advertiserIds": ["2914"],
"adSetIds": ["106509"],
"dimensions": ["advertiserId", "adSetId", "sellerId", "productId"],
"metrics": ["displays", "clicks", "cost"],
"startDate": "2026-03-09T00:00:00Z",
"endDate": "2026-03-11T00:00:00Z"
}
}
}

Request Parameters

  Data availability grows progressively after launch. If your startDate is earlier than the available data window, the request will be rejected with an invalid-query error. Full 1-year lookback is expected to be available progressively after go-live.

Response

{
"data": {
"type": "ProductReportJobStatus",
"attributes": {
"reportId": "e0893b6b-be25-477f-9ca3-e6e8c8ec9e30",
"status": "PENDING"
}
}
}
If an identical request was recently processed and the cache is still valid, the response may already show "status": "DONE".

2. Get Report Status

GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/report-jobs/{reportId}
Returns the current status of a report job.

Path Parameters

Response

{
"data": {
"type": "ProductReportJobStatus",
"attributes": {
"reportId": "e0893b6b-be25-477f-9ca3-e6e8c8ec9e30",
"status": "DONE",
"expiresAt": "2026-03-18T10:35:53Z",
"fileSizeBytes": 154555
}
}
}

Status Values

Poll this endpoint at a regular interval (recommended: every 30–60 seconds) until status is DONE before downloading.

3. Download Report

GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/product-reports/{reportId}
Downloads the completed report file. Only available when job status is DONE.

Path Parameters

Response -CSV (text/csv)

One row per combination of the requested dimensions, with metrics totalled over the full reporting interval. There is no date column -the report returns interval totals only. advertiserId,adSetId,sellerId,productId,displays,clicks,cost
2914,106509,515151,847392011,220,45,4400
2914,106509,515151,847392012,800,4,400
2914,106509,131313,564656664,1832,3,450

Response -JSON (application/json)

{
"data": [
[2914, 106509, 515151, 847392011, 220, 45, 4400],
[2914, 106509, 515151, 847392012, 800, 4, 400],
[2914, 106509, 131313, 564656664, 1832, 3, 450]
],
"metadata": {
"columns": ["advertiserId", "adSetId", "sellerId", "productId", "displays", "clicks", "cost"],
"rows": 3
}
}

Dimensions

Duplicate dimension values in the same request are not permitted. Time dimensions (date, day, hour) are not supported by this API -the report always returns interval totals.

Metrics

Duplicate metric values in the same request are not permitted.

Error Handling

HTTP Status Codes

Error Codes

Example: Invalid file format

{
"errors": [
{
"traceId": "56ed4096-f96a-4944-8881-05468efe0ec9",
"code": "unsupported-file-format",
"title": "Unsupported file format",
"detail": "The requested fileFormat 'xls' is not supported. Supported formats are: csv and json."
}
]
}

Integration Pattern

A typical integration for a daily product-level export:
  1. Call POST /product-reports/export with your desired dimensions, metrics, and date range.
  2. Store the returned reportId.
  3. Poll GET /report-jobs/{reportId} every 30–60 seconds.
  4. When status is DONE, call GET /product-reports/{reportId} to download the file.
  5. If status is FAILURE, check your request parameters and retry.
  6. If status is EXPIRED, submit a new report job.
If you submit the same request within the cache freshness window, the API may return DONE immediately on the initial POST response -check before polling.