Skip to main content

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 goalRecommended modeEndpoint(s)
Quick aggregated KPIs for a single campaignSynchronousGET /campaign-performance
Quick aggregated KPIs for a single product (SKU)SynchronousGET /product-performance
Full, downloadable CSV broken down by dimensionsAsynchronousPOST /campaign-performance, POST /product-performance
Any keyword / search term level dataAsynchronous (only option)POST /keyword-performance
Large date ranges or multi-level groupByAsynchronousthe 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.

StepActionYou sendYou receive
1. SubmitRequest a report with a POST endpointPOST /{type}-performance with the report configuration202 Accepted{ reportId, status: IN_PROGRESS }
2. PollCheck the job status with the returned reportId, repeating until it resolvesGET /{type}-performance/status?reportId=…200 OK{ status } (IN_PROGRESSREADY / FAILED)
3. DownloadFetch the file once the status is READYGET /reports/download?reportId=…200 OK → CSV file stream (text/csv)

Notes

  • After submitting, you receive a reportId and an initial status of IN_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; a FAILED status 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 Authorization header.
  • The token must include the advertising-services scope.
  • 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 returns 403 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 AND logic.

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

ColumnTypeDescription
TOTAL_VIEWSKPITotal ads impressions
TOTAL_CLICKSKPITotal ads clicks
TOTAL_COSTSKPITotal ads spend
CAMPAIGN_IDDimensionCampaign identifier
KEYWORDDimensionBid keyword
SEARCHTERMDimensionActual search term used by the customer
EVENT_DATE_CETDimensionEvent (impression, click) date in Central European Time
MATCH_TYPEDimensionMatching 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

ColumnTypeDescription
TOTAL_VIEWSKPITotal ads impressions
TOTAL_CLICKSKPITotal ads clicks
TOTAL_COSTSKPITotal ads spend
CAMPAIGN_IDDimensionCampaign identifier
EVENT_DATE_CETDimensionEvent (impression, click) date in Central European Time

Default groupBy: CAMPAIGN_ID

Product Reports

ColumnTypeDescription
TOTAL_VIEWSKPITotal ads impressions
TOTAL_CLICKSKPITotal ads clicks
TOTAL_COSTSKPITotal ads spend
TOTAL_SALESKPITotal revenue (€) attributed to ad interactions (product-level-metric - only the sales of the SPA product are counted)
TOTAL_ORDERED_SKUSKPITotal number of articles ordered attributed to ad interactions (campaign-level metric)
TOTAL_SALES_SELLERKPITotal seller revenue from articles having same brand attributed to ad interactions
CAMPAIGN_IDDimensionCampaign identifier
SKUDimensionProduct SKU
EVENT_DATE_CETDimensionEvent (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 /status endpoint 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-8
  • Content-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 fromDate and toDate must be provided together, or neither.
  • Omitting both defaults to the last 7 days.
  • fromDate must not be after toDate — a 400 validation-error is returned otherwise.
  • Providing only one of the two dates also returns a 400 validation-error indicating which field is missing.

For async report generation endpoints (POST /keyword-performance, POST /campaign-performance, POST /product-performance):

  • Both fromDate and toDate are 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 campaignId in the request parameter (or CAMPAIGN_ID column 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 groupBy are 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.