Sponsored Product Ads Reporting
The SPA Reporting interface provides performance metrics and on-demand report generation for Sponsored Product Ads campaigns. It provides data maximum for the last 90 days excluding the present day.
It offers two usage modes:
- Synchronous performance calculation request — fetch pre-aggregated KPIs directly for a campaign (provided by campaignId) or product (provided by combination of campaignId and SKU). These endpoints are meant to be fast because it only calculates aggregated KPIs for single campaign or product (but not for keyword).
- Asynchronous report generation request — request a full CSV report, each report will receive an unique id (reportId). This applies for campaign, product and keyword report. Generating such a report could take more time than single KPI calculation request, you have to poll for its status using reportId and when the status becomes READY, you can download it via the provided URL. Each report will be kept for 24 hours, afterward it is deleted (this time limit is subject to be changed).
All endpoints are served under the base path /v1/spa-reporting.
Choosing the right mode
Use this table to decide which mode fits your need:
| Your goal | Recommended mode | Endpoint(s) |
|---|---|---|
| Quick aggregated KPIs for a single campaign | Synchronous | GET /campaign-performance |
| Quick aggregated KPIs for a single product (SKU) | Synchronous | GET /product-performance |
| Full, downloadable CSV broken down by dimensions | Asynchronous | POST /campaign-performance, POST /product-performance |
| Any keyword / search term level data | Asynchronous (only option) | POST /keyword-performance |
Large date ranges or multi-level groupBy | Asynchronous | the POST report endpoints |
Rule of thumb: if you need a single number now, use the synchronous GET endpoints. If you need a detailed, exportable breakdown — or any keyword data — use the asynchronous report endpoints.
End-to-end workflow
The asynchronous report mode follows three steps. The synchronous mode is a single GET call that returns the KPI metrics directly in the JSON response.
| Step | Action | You send | You receive |
|---|---|---|---|
| 1. Submit | Request a report with a POST endpoint | POST /{type}-performance with the report configuration | 202 Accepted → { reportId, status: IN_PROGRESS } |
| 2. Poll | Check the job status with the returned reportId, repeating until it resolves | GET /{type}-performance/status?reportId=… | 200 OK → { status } (IN_PROGRESS → READY / FAILED) |
| 3. Download | Fetch the file once the status is READY | GET /reports/download?reportId=… | 200 OK → CSV file stream (text/csv) |
Notes
- After submitting, you receive a
reportIdand an initialstatusofIN_PROGRESS. - When polling, use a reasonable interval (e.g. a few seconds) rather than tight-looping. Only continue to step 3 once the status is
READY; aFAILEDstatus means you must submit a new request. - The generated file is available for 24 hours after generation.
Authentication & scopes
- All requests must carry a valid OAuth 2.0 bearer token in the
Authorizationheader. - The token must include the
advertising-servicesscope. - The token's partner identity determines which data is visible — you can only access data belonging to your own
partner_id. There is no need to pass the partner identity as a parameter; it is derived from the token. - Missing or invalid credentials return
401 Unauthorized; a token without the required scope or with a partner mismatch returns403 Forbidden.
Reports
A report is a simple CSV file that consists performance data for a chosen report type (campaign, product, keyword). You might chose further metadata information to include in the report. Generally to generate a report, you need to provide 3 types of information in its configuration
- columns: the metadata (including performance data) that you want to include in the report. It will become the column in the CSV file.
- groupBy (optional): you can provide a list of dimensional columns to have the performance data broken down in multiple levels. For example: to know total ads impression of a keyword at daily level (groupBy list of column would be: KEYWORD, EVENT_DATE_CET)
- filters (optional): you can also specify some condition to filter the data you may want, for example: to know about total ads impression of a keyword from only one specific ads campaign (CAMPAIGN_ID='campaign_id'). Multiple filter entries are combined with
ANDlogic.
The detailed configuration is described below:
Columns
Each report type exposes a fixed set of columns. Columns that represent KPI metrics (TOTAL_VIEWS, TOTAL_CLICKS, TOTAL_COSTS) are automatically aggregated with SUM() when used with a groupBy.
Keyword Reports
| Column | Type | Description |
|---|---|---|
TOTAL_VIEWS | KPI | Total ads impressions |
TOTAL_CLICKS | KPI | Total ads clicks |
TOTAL_COSTS | KPI | Total ads spend |
CAMPAIGN_ID | Dimension | Campaign identifier |
KEYWORD | Dimension | Bid keyword |
SEARCHTERM | Dimension | Actual search term used by the customer |
EVENT_DATE_CET | Dimension | Event (impression, click) date in Central European Time |
MATCH_TYPE | Dimension | Matching logic used to match keyword with the actual search term used by the customer with possible values: EXACT, BROAD, PHRASE |
Default groupBy: KEYWORD
Campaign Reports
| Column | Type | Description |
|---|---|---|
TOTAL_VIEWS | KPI | Total ads impressions |
TOTAL_CLICKS | KPI | Total ads clicks |
TOTAL_COSTS | KPI | Total ads spend |
CAMPAIGN_ID | Dimension | Campaign identifier |
EVENT_DATE_CET | Dimension | Event (impression, click) date in Central European Time |
Default groupBy: CAMPAIGN_ID
Product Reports
| Column | Type | Description |
|---|---|---|
TOTAL_VIEWS | KPI | Total ads impressions |
TOTAL_CLICKS | KPI | Total ads clicks |
TOTAL_COSTS | KPI | Total ads spend |
TOTAL_SALES | KPI | Total revenue (€) attributed to ad interactions (product-level-metric - only the sales of the SPA product are counted) |
TOTAL_ORDERED_SKUS | KPI | Total number of articles ordered attributed to ad interactions (campaign-level metric) |
TOTAL_SALES_SELLER | KPI | Total seller revenue from articles having same brand attributed to ad interactions |
CAMPAIGN_ID | Dimension | Campaign identifier |
SKU | Dimension | Product SKU |
EVENT_DATE_CET | Dimension | Event (impression, click) date in Central European Time |
Default groupBy: SKU
Keyword Match Types - Now supporting BROAD, PHRASE
The keyword report now includes the KPI for additional matching logic of BROAD and PHRASE beside EXACT. This means that currently we offer only metrics coming from POSITIVE as keyword type.
We will update when metrics for keyword type of NEGATIVE are available for reporting.
See Sponsored Product Ads Key Campaign Creation for more information.
Report Filters
Async report requests accept an optional configuration.filters array to narrow the data included in the report. Each filter entry has the following shape:
{
"column": "CAMPAIGN_ID",
"operator": "=",
"value": "camp456"
}
Filterable columns: CAMPAIGN_ID, SKU. For keyword report, MATCH_TYPE could be used.
Allowed operators: =, !=, >=, <=, >, <
Multiple filter entries are combined with AND logic.
Report Job Status
Asynchronous report generation endpoints include reportId and status in their responses. The status transitions are:
IN_PROGRESS
The report job has been submitted and is currently being generated. Poll the corresponding/statusendpoint until the status changes.READY
The report file has been generated and is available for download.FAILED
The report generation encountered an error. A new report request must be submitted.
Only reports with status READY can be downloaded.
Common Use Cases
Synchronous KPIs calculation request
Get campaign KPIs for the last 7 days
Omit both fromDate and toDate to use the default 7-day rolling window.
GET /v1/spa-reporting/campaign-performance?campaignId=camp456
Get campaign KPIs for a specific date range
GET /v1/spa-reporting/campaign-performance?campaignId=camp456&fromDate=2026-03-01&toDate=2026-03-31
Get product KPIs, its SKU and the corresponded campaignId must be provided
GET /v1/spa-reporting/product-performance?campaignId=camp456&sku=SKU789&fromDate=2026-03-01&toDate=2026-03-31
Asynchronous report generation request
Request a keyword performance report
Submit a report generation request for keyword. The response contains a reportId and you can use it to poll the report's status including a download URL when it is ready.
POST /v1/spa-reporting/keyword-performance
{
"name": "Keyword Performance Report",
"fromDate": "2026-03-01",
"toDate": "2026-03-31",
"configuration": {
"columns": ["KEYWORD", "TOTAL_VIEWS", "TOTAL_CLICKS", "TOTAL_COSTS"],
"format": "CSV"
}
}
To additionally having keyword performance broken down by search term:
{
"name": "Search Term Analysis",
"fromDate": "2026-03-01",
"toDate": "2026-03-31",
"configuration": {
"columns": ["SEARCHTERM", "TOTAL_VIEWS", "TOTAL_CLICKS"],
"groupBy": ["SEARCHTERM"],
"format": "CSV"
}
}
To have a report on only keyword matched by BROAD logic
{
"name": "Keyword Performance Report for BROAD matching type",
"fromDate": "2026-07-01",
"toDate": "2026-07-28",
"configuration": {
"columns": [
"KEYWORD",
"TOTAL_VIEWS",
"TOTAL_CLICKS",
"TOTAL_COSTS",
"TOTAL_SALES",
"MATCH_TYPE",
"TOTAL_ORDERED_SKUS",
"EVENT_DATE_CET"
],
"filters": [
{
"column": "MATCH_TYPE",
"operator": "=",
"value": "BROAD"
}
],
"format": "CSV"
}
}
Request a campaign performance report (async) with a filter
POST /v1/spa-reporting/campaign-performance
{
"name": "Campaign Report",
"fromDate": "2026-03-01",
"toDate": "2026-03-31",
"configuration": {
"columns": ["CAMPAIGN_ID", "TOTAL_VIEWS", "TOTAL_COSTS"],
"groupBy": ["EVENT_DATE_CET", "CAMPAIGN_ID"],
"filters": [
{ "column": "CAMPAIGN_ID", "operator": "=", "value": "camp456" }
],
"format": "CSV"
}
}
Request a product performance report (async)
POST /v1/spa-reporting/product-performance
{
"name": "Product Performance Report",
"fromDate": "2026-03-01",
"toDate": "2026-03-31",
"configuration": {
"columns": ["SKU", "TOTAL_VIEWS", "TOTAL_CLICKS", "TOTAL_COSTS"],
"format": "CSV"
}
}
Poll report status until READY
GET /v1/spa-reporting/keyword-performance/status?reportId={reportId}
The same pattern applies to campaign and product reports using their respective /status endpoints.
Download a completed report
Once the status is READY, download the CSV file using the reportId:
GET /v1/spa-reporting/reports/download?reportId={reportId}
The response is a streamed CSV file with the following headers:
Content-Type: text/csv; charset=utf-8Content-Disposition: attachment; filename="<report-filename>.csv"Cache-Control: no-store
Attempting to download a report that is not yet READY (or an unknown reportId) returns 404 Not Found. If the report once existed but its file has already expired and been deleted, the endpoint returns 410 Gone.
Date Parameters
All date parameters use the format YYYY-MM-DD.
For real-time query endpoints (GET /campaign-performance, GET /product-performance):
- Both
fromDateandtoDatemust be provided together, or neither. - Omitting both defaults to the last 7 days.
fromDatemust not be aftertoDate— a400 validation-erroris returned otherwise.- Providing only one of the two dates also returns a
400 validation-errorindicating which field is missing.
For async report generation endpoints (POST /keyword-performance, POST /campaign-performance, POST /product-performance):
- Both
fromDateandtoDateare required fields in the request body.
Glossary
You may take a look into our Sponsored Product Ads glossary to have an overview.
- Campaign — A Sponsored Product Ads campaign grouping one or more ad placements under a shared budget and targeting configuration. Identified by
campaignIdin the request parameter (orCAMPAIGN_IDcolumn in the report) - SKU — Stock Keeping Unit. The unique identifier for a product variant in the partner's catalogue.
- Keyword — A string denotes the keyword (not the
keywordId) used to match a sponsored ad to customer search queries. - Search Term — The actual search query entered by a customer that triggered an ad impression. Currently the reporting api supports only EXACT match, so search term should be identical to keyword.
- KPI — Key Performance Indicator. Numeric metrics such as views, clicks, and costs that measure campaign effectiveness.
- Report ID — A UUID that uniquely identifies an async report generation job. Used to poll status and download the result.
- groupBy — An optional list of dimension columns by which KPI metrics are aggregated in a report. Dimension columns included in
groupByare automatically added to the SELECT clause.
KPI Report Columns
- TOTAL_VIEWS — The total number of ad impressions (how often an ad was shown to customers).
- TOTAL_CLICKS — The total number of ad clicks (how often a customer clicked on an ad).
- TOTAL_COSTS — The total ad spend in euros (the cumulative cost incurred from ad clicks).
- TOTAL_SALES - The total revenue (€) attributed to ad interactions (product-level-metric - only the sales of the SPA product are counted).
- TOTAL_ORDERED_SKUS - The total number of articles ordered attributed to ad interactions (campaign-level metric).
- TOTAL_SALES_SELLER - The total seller revenue attributed to ad interactions.
Synchronous Response Metrics
These computed metrics are returned by the synchronous performance calculation endpoints (GET /campaign-performance, GET /product-performance):
- totalViews — Total ad impressions within the requested date range.
- totalClicks — Total ad clicks within the requested date range.
- totalCosts — Total ad spend (€) within the requested date range.
- costPerClick — The average cost per click (totalCosts / totalClicks). Indicates the average price paid for each ad click.
- clickThroughRate — The ratio of clicks to views (totalClicks / totalViews). Indicates how effectively an ad converts impressions into clicks.
- returnOnAdSpend — The ratio of revenue to ad spend (totalSales (product-level-metric) / totalCosts). Indicates how much revenue is generated per euro spent on ads.
- orderedSkus — The total number of distinct product SKUs ordered attributed to ad interactions (product-level metric).
- totalOrderedSkus — The total number of articles ordered attributed to ad interactions (campaign-level metric).
- totalSales — The total revenue (€) attributed to ad interactions (product-level-metric - only the sales of the SPA product are counted).
- totalSalesSeller — The total seller revenue (€) attributed to ad interactions.
Dimensions and Parameters
- EVENT_DATE_CET — The date of the ad event (impression or click, format:
YYYY-MM-DD), in Central European Time (CET/CEST). Used as a dimension column for daily breakdowns. - fromDate — Start of a date range filter (format:
YYYY-MM-DD), in Central European Time (CET/CEST). Inclusive lower bound. - toDate — End of a date range filter (format:
YYYY-MM-DD), in Central European Time (CET/CEST). Inclusive upper bound.