> ## Documentation Index
> Fetch the complete documentation index at: https://developers.criteo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MPO Real-Time Asynchronous API

export const EndpointBadge = ({method = "GET", children}) => {
  const METHOD_STYLES = {
    GET: {
      bg: "mint-bg-[#2AB673]"
    },
    POST: {
      bg: "mint-bg-[#3064E3]"
    },
    PUT: {
      bg: "mint-bg-[#C28C30]"
    },
    PATCH: {
      bg: "mint-bg-[#DA622B]"
    },
    DELETE: {
      bg: "mint-bg-[#CB3A32]"
    },
    API: {
      bg: "mint-bg-black"
    }
  };
  const key = method.toUpperCase();
  const styles = METHOD_STYLES[key] ?? METHOD_STYLES.API;
  return <div className="relative mt-7">
      <span className={`absolute -top-2 -left-2 z-10 ${styles.bg} text-white px-2.5 py-0.5 rounded-full text-xs font-bold tracking-wide`}>
        {key}
      </span>
      {children}
    </div>;
};

<Warning>
  **Important Data Usage Warning**

  This data is generated in real time and is intended **only for real-time reporting purposes**. It is not subject to standard data cleaning practices (deduplication, quality checks) and **must not be used for pricing, bidding, invoicing, or any financial decision-making.**
</Warning>

<Warning>
  **BETA Access**<br />The API is currently in **beta** and is only available to a limited list of clients onboarded by the Criteo technical team. You can find the reference for the endpoints mentioned in the page in [the **Preview** version](/marketing-solutions/v2026-preview/reference/analytics/get-realtime-product) of this documentation.
</Warning>

***

## Overview

This API provides real-time reporting for **Marketplace Performance Outcomes (MPO)** via an asynchronous export workflow designed for large volumes of data.

* **Data latency:** Approximately 10 minutes.
* **Base URL:**

```http theme={null}
https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/
```

* **Compatibility:** This endpoint supports both **multi-seller** and **single-seller** campaign configurations.

<Info>
  The workflow is:

  1. Create an asynchronous report job with your filters.
  2. Poll the job status until it is complete.
  3. Download the generated export file (CSV or JSON).
</Info>

***

### 1. Create a report job

**Endpoint:** `POST /stats/realtime-reports/export`

Submit a request with your desired filters. The API creates an export job and returns an identifier (UUID) and a `status` (typically `Pending`).

### 2. Poll for Completion

**Endpoint:** `GET /stats/report-jobs/{reportId}`

Poll the job status until it reaches `Done`. Do not poll more than once every 5–10 seconds to remain within rate limits.

* **Status options:** `Pending`, `Done`, `Failure`, `Expired`.
* **Note:** Identical requests may reuse cached results, returning a previously generated ID.

### 3. Download the report

**Endpoint:** `GET /stats/realtime-reports/{reportId}`

Once the status is `Done`, this call returns the raw file bytes.

* **CSV output:** `Content-Type: text/csv`.
* **JSON output:** `Content-Type: application/json`.

***

## Data models

### Request attributes (`RealTimeProductReportJob`)

*(\*) - Required*

#### Dimensions

#### Metrics

***

## Step 1. Create an Async Report Job

<EndpointBadge method="post">
  ```http theme={null}
  https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/realtime-reports/export
  ```
</EndpointBadge>

This endpoint creates a new asynchronous report job for a real-time product report. The backend triggers production of an export file and may reuse cached results when the same request has already been processed.

### Sample Request

```json theme={null}
{
  "data": {
    "type": "RealTimeProductReportJob",
    "attributes": {
      "fileFormat": "csv",
      "advertiserIds": ["321"],
      "campaignIds": ["12345", "56789"],
      "sellerIds": ["254614150"],
      "dimensions": ["advertiserId", "campaignId", "sellerId"],
      "metrics": ["clicks", "displays", "cost"],
      "startDate": "2026-01-09T08:00:00Z",
      "endDate": "2026-01-09T09:00:00Z",
      "timezone": "UTC"
    }
  }
}
```

### Sample Response

#### Successful Response

```json theme={null}
{
  "exportId": "45f7ec55-1008-4372-9144-1da37d8dccc2",
  "status": "Pending",
  "message": null
}
```

#### Error Example: unsupported `fileFormat`

If `fileFormat` is not one of `csv` or `json`, the API returns a `400 Bad Request` validation error.

```json theme={null}
{
  "warnings": [],
  "errors": [
    {
      "traceId": "31500d5059bb85b2168e9256f8722fa8",
      "type": "validation",
      "code": "json-serialization-error",
      "title": "JSON error",
      "detail": "data.attributes.fileFormat 'xls' not valid. Must be one of 'Csv','Json'"
    }
  ]
}
```

***

## Step 2. Poll for completion

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/report-jobs/{reportId}
  ```
</EndpointBadge>

This endpoint polls the job status until it reaches `Done`.<br />Do not poll more than once every 5–10 seconds to remain within rate limits.

* **Status options:** `Pending`, `Done`, `Failure`, `Expired`.
* **Note:** Identical requests may reuse cached results, returning a previously generated ID.

***

## Step 3. Download Report Output

<EndpointBadge method="get">
  ```http theme={null}
  https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/realtime-reports/{reportId}
  ```
</EndpointBadge>

This endpoint downloads the file corresponding to a completed export job.

<Info>
  Download availability window

  Export files generated by the MPO Real-Time Asynchronous API are only guaranteed to be available for download for a short period after the job reaches `status = Done` (typically up to **4 hours**). If the file has expired, you must create a new export job and download its output within this retention window.
</Info>

* If `fileFormat = csv` → `Content-Type: text/csv`
* If `fileFormat = json` → `Content-Type: application/json`

### Path Parameters

*(\*) - Required*

### Example Request

<EndpointBadge method="get">
  ```http theme={null}
  GET https://api.criteo.com/{version}/marketing-solutions/marketplace-performance-outcomes/stats/realtime-reports/45f7ec55-1008-4372-9144-1da37d8dccc2
  ```
</EndpointBadge>

#### Successful response

* **200 OK** only if job status is `Done`.
* Body contains **raw file bytes** (CSV or JSON).

### Output formats

#### CSV output

The response contains a header row followed by data rows.

```csv theme={null}
"advertiserId","campaignId","clicks","displays","cost"
321,12345,1873,800247,992.21671380425
321,56789,17927,5275096,3460.71409576333
...
```

#### JSON output

The response contains a columnar JSON payload with a `data` array and top-level `columns` and `rows` fields.

```json theme={null}
{
  "columns": [
    "advertiserId",
    "campaignId",
    "clicks",
    "displays",
    "cost"
  ],
  "data": [
    [
      321,
      12345,
      17927,
      5275096,
      3460.71409576333
    ],
    [
      321,
      56789,
      1873,
      800247,
      992.21671380425
    ]
  ],
  "rows": 2
}
```

***

## Validation rules

The following validation rules are explicitly described via field notes and domain errors.

### 1) Required fields

* `advertiserIds` is **required**.
* Missing required fields yields `invalid-query`.

### 2) File format

* `fileFormat` must be one of `csv` or `json`.
* Otherwise the API returns `json-serialization-error` (as shown in the example).

### 3) Time interval definition

You must use **exactly one** of:

* **Relative interval:** `lookbackWindow` (minutes from now).
* **Absolute interval:** `startDate` (and optionally `endDate`).

Rules:

* `lookbackWindow` must be within **60–1440**.
* `lookbackWindow` **cannot** be combined with `startDate` and/or `endDate`.
* `startDate` is **mutually exclusive** with `lookbackWindow`.
* `startDate` must be within the **last 24 hours** relative to “now”. Requests with an older `startDate` are **rejected**.
* If `startDate` is provided and `endDate` is omitted, `endDate` defaults to the **current time**.

### 4) Time zone

* `timezone` must exist in the IANA Time Zone database.
* Invalid time zones yield `invalid-query` (as part of "invalid query definition").

### 5) Dimension combination constraints

* Only **one** of the following dimensions can be used in a single request:
  * `productId`
  * `hour`
  * `minute`

Violations yield `invalid-dimensioncombination`.

### 6) Report lifecycle constraints

* Downloading output is only valid when `status == Done`.
* If the job does not exist (or is not visible), the API returns `export-not-found` and maps it to HTTP `403`.
* If the job exists, but the output has been permanently deleted, the API returns `export-alreadyexpired`.

### 7) Caching behavior (identical requests)

* Identical requests may reuse cached results, meaning a previous export/report ID may be returned instead of generating a new export.

***

## Errors & status codes

### HTTP status codes

### Domain errors / validation errors

## What's next

* [Validation Errors](/marketing-solutions/v2027.01-rc/docs/validation-errors)
* [MPO Standard Reporting API](/marketing-solutions/v2027.01-rc/docs/mpo-standard-reporting-api)
