What this report contains
One row per advertised product per day, for Sponsored Products. The "product" is the ad itself: ad_id, with the advertised_asin and advertised_sku it promotes, and the campaign_id, ad_group_id and portfolio_id it sits under. Where the campaign report tells you what a campaign did, this one tells you which product inside it did it.
The left-hand side is what the ad cost — impressions, clicks, cost and spend — and the right-hand side is what Amazon attributed back to it, repeated at four attribution windows (1, 7, 14 and 30 days) and repeated again for units and for same-SKU. That is how a report about one ad ends up 49 columns wide. The windows are cumulative rather than additive: sales_30d includes sales_7d, so picking a window is picking how much credit a click gets for a slow decision. Amazon's column reference defines each of them the same way — sales "occurring within N days of an ad click" — so the containment is definitional, not an artefact of the file.
Two columns exist only at 7 days: units_sold_other_sku_7d and sales_other_sku_7d. They are the halo — products other than the advertised SKU bought after the click — carried explicitly rather than left for you to derive. Amazon defines them as the part of the 7-day window where the purchased SKU differed from the one advertised, and the same-SKU columns as the part where it matched, so the two are complements by definition. Whether they reconcile to sales_7d exactly in a real file has not been checked.
Amazon also computes four ratios for you: click_through_rate, acos_clicks_7d, acos_clicks_14d, roas_clicks_7d and roas_clicks_14d. All of them are percentages or bare multiples, none is a 0-to-1 fraction, and all of them are null where their denominator is zero — which at this grain is most rows. The campaign's budget, budget type and budget currency are repeated on every one of its ad rows, so the row is self-contained, but they describe the campaign, not the ad.
Every one of the 49 requested columns arrives on every file. Nothing is conditionally absent; the sparse columns are present and null, which is a different thing.
How to get it
Through the Amazon Ads API v3, request reportTypeId: spAdvertisedProduct with adProduct: SPONSORED_PRODUCTS, timeUnit: DAILY, format: GZIP_JSON and — the part that catches people — groupBy: ["advertiser"]. There is no advertisedProduct grouping to ask for; the report type already fixes the grain, and advertiser is the grouping it accepts. Name every column you want in the request. You POST that to /reporting/reports, get a report ID back, poll until it is COMPLETED and download the gzipped JSON. Amazon's own sample call for this report type is that same POST with adProduct: SPONSORED_PRODUCTS, groupBy: ["advertiser"], reportTypeId: spAdvertisedProduct and format: GZIP_JSON — at timeUnit: SUMMARY, where a row per day needs DAILY — and its reporting guide warns that generation can take as long as three hours.
The v3 API returns exactly the columns you asked for and nothing else. A column that is missing from your file is missing from your request, not from Amazon's schema, and a column you did not ask for will never appear. Reports are per-profile, so a seller advertising in several marketplaces runs one request per profile and gets one file per profile, each in its own currency.
In the Amazon Ads console, the same data is the Sponsored Products Advertised product report: Measurement & Reporting in the sidebar, then Sponsored ads reports, then Create report, at a summary or daily time unit. Amazon is retiring that section — unified reporting at Measurement and Reporting → Reporting carries an Advertised product template, and Sponsored Ads reports is being sunset by 31 December 2026 — so the API request above is the durable path. The console report's lookback is 90 days against the API's 95.
Sample rows
Illustrative values, not data from a real account. Shown to give the shape of the file.
| date | campaign_name | advertised_asin | advertised_sku | impressions | clicks | cost | purchases_7d | sales_7d | acos_clicks_7d |
|---|---|---|---|---|---|---|---|---|---|
| 2026-09-14 | Brand Defense - Exact | B0EXAMPLE01 | EX-BLUE-M | 18420 | 261 | 182.70 | 27 | 1079.73 | 16.92 |
| 2026-09-14 | Brand Defense - Exact | B0EXAMPLE02 | EX-BLUE-L | 12980 | 174 | 121.80 | 15 | 599.85 | 20.31 |
| 2026-09-14 | Category Targeting - Auto | B0EXAMPLE03 | EX-RED-M | 46210 | 512 | 358.40 | 31 | 868.31 | 41.28 |
| 2026-09-14 | Category Targeting - Auto | B0EXAMPLE04 | EX-RED-L | 5130 | 0 | 0.00 | 0 | 0.00 | |
| 2026-09-14 | New Launch - Discovery | B0EXAMPLE05 | EX-GRN-M | 2740 | 23 | 19.55 | 1 | 29.99 | 65.19 |
Field reference
| Column | Type | Description |
|---|---|---|
date | date | The advertising day the row's metrics are attributed to. Arrives as ISO YYYY-MM-DD on every row with no time component and no marketplace date-order ambiguity, which makes it the column to partition on. |
campaign_id | string | Amazon's campaign identifier. Arrives in the JSON as a 12 to 15 digit number and should be kept as text, because it is a join key and a numeric type would silently drop a leading zero. |
campaign_name | string | The campaign name as the report carried it. Join on campaign_id, not on this. |
campaign_status | string | The campaign's status as the report carried it. |
campaign_budget_amount | decimal | The campaign's configured budget, repeated on every ad row in that campaign. Summing it across rows counts one budget many times over. |
campaign_budget_type | string | Whether the budget is daily or a lifetime total. |
campaign_budget_currency_code | string | The currency of campaign_budget_amount, populated on every row. In production files it matches the profile's marketplace (USD, GBP, EUR, PLN, SEK, INR, AED, SAR), so in practice it is the currency of every money column in the row too — but its name says budget, and it is kept under that name rather than promoted to a general currency code. |
ad_group_id | string | Amazon's ad group identifier. A 12 to 15 digit number carried as text for the same reason as campaign_id. |
ad_group_name | string | The ad group's name. Join on ad_group_id, not on this. |
ad_id | string | The identifier of the product ad itself — the thing one row is about. A 12 to 15 digit number carried as text. |
portfolio_id | string | The portfolio the campaign sits in, carried as text. Null on 39.5% of production rows, which is simply a campaign in no portfolio, not a missing value. |
advertised_asin | string | The ASIN the ad promotes. A 10-character ASIN on every one of 1,096,316 production rows. |
advertised_sku | string | The seller SKU the ad promotes. Populated on every production row. |
impressions | int64 | Times the ad was displayed. |
clicks | int64 | Clicks on the ad. Zero on roughly nine rows in ten at this grain, which is why the per-click columns are mostly null. |
click_through_rate | float64 | Clicks divided by impressions, expressed as a percentage rather than a fraction (values up to 200.0 have been observed). Null on the 10.6% of rows with no impressions. Recompute from the counts when aggregating rather than averaging this column. |
cost | decimal | What the ad's clicks cost. Equal to spend on 99.8% of production rows but not all of them, so pick one for reporting and say which. |
spend | decimal | Amazon's other spend figure. Agrees with cost on 1,093,956 of 1,096,316 rows and differs on 2,360, unlike the campaign grain where the two agree everywhere. Never add it to cost. |
cost_per_click | decimal | Average cost per click for the row. Money, not a rate — it multiplies back into cost. Null on the 90.7% of rows with no clicks. |
purchases_1d | int64 | Orders attributed to a click on this ad within 1 day. |
purchases_7d | int64 | Orders attributed within 7 days — the window most quoted ACOS figures quietly mean. |
purchases_14d | int64 | Orders attributed within 14 days. |
purchases_30d | int64 | Orders attributed within 30 days. The most generous window and the slowest to settle. |
purchases_same_sku_1d | int64 | The part of purchases_1d that was the advertised SKU itself rather than another product the shopper bought after clicking. |
purchases_same_sku_7d | int64 | Same-SKU part of purchases_7d. |
purchases_same_sku_14d | int64 | Same-SKU part of purchases_14d. |
purchases_same_sku_30d | int64 | Same-SKU part of purchases_30d. |
units_sold_clicks_1d | int64 | Units sold from click-attributed orders within 1 day. Counts units, where purchases_1d counts orders. |
units_sold_clicks_7d | int64 | Units sold from click-attributed orders within 7 days. |
units_sold_clicks_14d | int64 | Units sold from click-attributed orders within 14 days. |
units_sold_clicks_30d | int64 | Units sold from click-attributed orders within 30 days. |
units_sold_same_sku_1d | int64 | Units of the advertised SKU specifically, within 1 day. |
units_sold_same_sku_7d | int64 | Units of the advertised SKU specifically, within 7 days. |
units_sold_same_sku_14d | int64 | Units of the advertised SKU specifically, within 14 days. |
units_sold_same_sku_30d | int64 | Units of the advertised SKU specifically, within 30 days. |
units_sold_other_sku_7d | int64 | Units of products other than the advertised SKU, within 7 days — the halo in units. Only the 7-day window is offered for this column. |
sales_1d | decimal | Attributed sales value within 1 day. |
sales_7d | decimal | Attributed sales value within 7 days. Divide cost by this for a 7-day ACOS at full precision. |
sales_14d | decimal | Attributed sales value within 14 days. |
sales_30d | decimal | Attributed sales value within 30 days. |
attributed_sales_same_sku_1d | decimal | The part of sales_1d from the advertised SKU itself. |
attributed_sales_same_sku_7d | decimal | The part of sales_7d from the advertised SKU itself — Amazon defines it as the same 7-day window restricted to purchases where the SKU matched the one advertised, and sales_other_sku_7d as the part where it differed. The two are complements by that definition; that they reconcile to sales_7d exactly has not been checked in a production file. |
attributed_sales_same_sku_14d | decimal | Same-SKU part of sales_14d. |
attributed_sales_same_sku_30d | decimal | Same-SKU part of sales_30d. |
sales_other_sku_7d | decimal | Attributed sales of products other than the advertised SKU, within 7 days — the halo in money. Like its units twin, only the 7-day window is offered. |
acos_clicks_7d | float64 | Amazon's 7-day ACOS as a percentage, not a fraction (values up to 182.9 observed). Null on the 98.6% of rows with no attributed sales. A rounded quotient of two columns the row already carries, so recompute from cost and sales_7d when exactness matters. |
acos_clicks_14d | float64 | Amazon's 14-day ACOS as a percentage. Null where there are no attributed sales; recompute from cost and sales_14d when exactness matters. |
roas_clicks_7d | float64 | Amazon's 7-day ROAS as a bare multiple (values up to 6,534 observed). Null on the 90.7% of rows with no clicks. The inverse of ACOS, and recomputable from sales_7d and cost. |
roas_clicks_14d | float64 | Amazon's 14-day ROAS as a bare multiple. Null on rows with no clicks; recomputable from sales_14d and cost. |
Use cases
Product-level ACOS inside a campaign. A campaign's ACOS is an average over its ads. Divide cost by sales_7d per advertised_asin and you find the one product spending the budget while the others earn it — the thing the campaign report structurally cannot show you.
Total ad spend per product, across campaigns. Where the same ASIN is advertised from more than one campaign, summing cost over advertised_asin and date, ignoring campaign, gives the number a product manager actually wants: what it cost to advertise this product today.
Halo per product, not per campaign. sales_other_sku_7d against attributed_sales_same_sku_7d shows which advertised products pull other products with them. A hero ASIN with weak same-SKU ACOS and a large other-SKU column is doing a job the campaign total hides.
Pruning ads that never click. Around nine in ten advertised-product-days have zero clicks. Filter to rows with impressions above some floor and clicks of zero, sum over 30 days by ad_id, and you have the list of ads spending impressions on nothing.
Portfolio roll-ups. portfolio_id lets you aggregate spend and sales at the portfolio level without a second lookup — with the caveat that it is null on roughly 40% of rows, because those campaigns are in no portfolio, and a naive group-by drops them into one anonymous bucket.
Superseding a day cleanly. Because a re-pull of a window restates every day in it, and because each day is a complete statement of that day's rows, you can replace a day wholesale with its latest pull rather than deduplicating overlapping windows.
Limitations and gotchas
cost and spend are not always the same number here. On the campaign grain they agree on every row; on this grain they agree on 99.8% of rows and differ on the rest — 2,360 of 1,096,316 in production files. The evidence records that they differ, not why, and Amazon's documentation offers no cause: the v3 column reference gives both the identical description, Total cost of ad clicks, and the version 2 to version 3 migration guide derives both from the one v2 cost metric. Pick one, use it everywhere, and never add them together.
Null is not zero. cost_per_click, roas_clicks_7d and roas_clicks_14d are null on 90.7% of rows (no clicks); acos_clicks_7d and acos_clicks_14d on 98.6% (no attributed sales); click_through_rate on 10.6% (no impressions); portfolio_id on 39.5% (no portfolio). A tool that reads null as zero will report a 0% ACOS on ads that sold nothing, which is the opposite of the truth.
The ratios are percentages and multiples, not fractions. ACOS runs to 182.9 in production files, click_through_rate to 200.0, ROAS to 6,534. A dashboard expecting 0-to-1 values will show ACOS of 18,290%. And Amazon's ACOS and ROAS exist only at 7 and 14 days — a 1-day or 30-day ACOS you compute yourself from cost and sales_1d or sales_30d.
Don't trust the rounded ratios when it matters. acos_clicks_7d is a rounded quotient of two columns the row already carries at full precision. For anything you will be held to, divide cost by sales_7d yourself, and recompute rather than average when aggregating.
The ID columns arrive as numbers. campaign_id, ad_group_id, ad_id and portfolio_id come through the JSON as 12-to-15-digit numbers. Load them as text: they are join keys, and a numeric type drops a leading zero without a word.
The raw JSON is not stable file to file. Left to infer types, a money column comes out as an integer in a file where every value happened to be whole and as a float in the next; ACOS lands as an all-null column for an advertiser with no attributed sales; and the column order follows whatever order the JSON happened to carry, which varies between files. Read by column name against a fixed schema, never by position, and never let one file's inferred types define the table.
Attribution windows nest — never add them. sales_30d contains sales_14d contains sales_7d contains sales_1d — each is defined as what occurred within that many days of the click. Summing across windows roughly quadruples revenue.
Budget columns describe the campaign, not the ad. campaign_budget_amount is repeated on every ad row in a campaign. Summing it over the report counts each budget as many times as the campaign has advertised products.
An empty day is no file, not a file of zeros. A day on which the advertiser had no rows lands nothing. A gap in your table is not necessarily a failed pull.
Sponsored Products only. adProduct is SPONSORED_PRODUCTS. Sponsored Brands and Sponsored Display advertised-product data are separate reports with their own columns.
FAQ
The campaign report has one row per campaign per day; this one has one row per advertised product per day, carrying the ad's ASIN and SKU plus the campaign, ad group and portfolio it sits in. Use this report when the question is which product, and the campaign report when it is which campaign.
They agree on about 99.8% of rows in production files and differ on the remaining 0.2%, which is not the case at the campaign grain where they always match. What causes the difference is not established: Amazon documents the two columns identically, as Total cost of ad clicks, and maps both back to the single version 2 cost metric. Treat them as two figures, pick one for reporting and never add them.
Because most advertised-product-days have no attributed sales, and Amazon leaves the ratio null rather than writing zero. In production files acos_clicks_7d is null on about 98.6% of rows. A null ACOS means nothing was sold, not that advertising was free.
A percentage: 18.3 means 18.3%, and values above 100 occur. ROAS is a bare multiple, and click_through_rate is a percentage too. None of the ratio columns is a 0-to-1 fraction.
The campaign is not in a portfolio. Roughly 40% of production rows have no portfolio, so any portfolio roll-up needs an explicit bucket for campaigns outside one.
No. It is requested with adProduct SPONSORED_PRODUCTS and covers Sponsored Products ads only. The other ad products have their own advertised-product reports with different columns.
Sources
Every researched claim on this page, and the Amazon or Walmart page it came from.
- marketplaces — advertising.amazon.com/faq — `The reporting updates are available worldwide (NA, EU, FE) wherever you can run sponsored ads.`
- marketplaces — advertising.amazon.com/advertised-product — the spAdvertisedProduct configuration table names no marketplace restriction.
- marketplaces — advertising.amazon.com/GYNVHW8R4QPYUS9H — `Available for: sellers, vendors, authors, and book vendors running Sponsored Products and Display campaigns`, with no marketplace limit.
- marketplaces — advertising.amazon.com/features — the Sponsored Products campaign-management marketplace list (US, CA, MX, BR, DE, ES, FR, IT, UK, NL, SE, TR, PL, BE, UAE, EG, SA, JP, IN, AU, SG, ZA) omits Ireland, yet a production file of this report was pulled from an Irish profile. Where the list and the file disagree, the file wins: marketplaces is `all`.
- history_window — advertising.amazon.com/advertised-product — the configuration table gives spAdvertisedProduct `Maximum date range 31 days` and `Data retention 95 days`. The 65-day figure in that table belongs to sdAdvertisedProduct, not to Sponsored Products.
- history_window — advertising.amazon.com/GYNVHW8R4QPYUS9H — `The advertised product report has 2 time units available: summary or daily. The lookback window for this report is 90 days.`
- latency — advertising.amazon.com/faq — `Initial impression and click data is available using the API within 12 hours`; `Initial conversion data is available within 24 hours`; restatements occur 1, 7 and 28 days after the conversion event; `Report generation can take as long as three hours.`
- latency — advertising.amazon.com/overview — invalid-traffic detection `monitors the traffic data for up to 30 days after the fact`, with a recommendation to wait at least 5 days for accurate click data, and conversion data `is subject to change for up to 60 days back from the current date`.
- how-to-get-it — advertising.amazon.com/advertised-product — the sample call is `POST advertising-api.amazon.com/reports` with adProduct SPONSORED_PRODUCTS, groupBy ["advertiser"], reportTypeId spAdvertisedProduct and format GZIP_JSON, at `"timeUnit":"SUMMARY"`; the configuration table gives the report type `SUMMARY` or `DAILY`.
- how-to-get-it — advertising.amazon.com/get-started — the flow is POST, then poll the report ID until it is COMPLETED, then download; `report generation can take up to three hours`.
- how-to-get-it — advertising.amazon.com/advertising-console — `To access your reports, click ‘Measurement & Reporting’ in the sidebar, then click through to ‘Sponsored ads reports’. From here, click on ‘Create report’`.
- how-to-get-it — advertising.amazon.com/GBYSPTSLR337JMLH — the sponsored ads downloadable report table lists `Advertised product` for Sponsored Products.
- how-to-get-it — advertising.amazon.com/streamline-campaign-analysis-with-unified-reporting — unified reporting is at `Measurement and Reporting > Reporting`, and Amazon is `sunsetting Sponsored Ads reports (Measurement and reporting > Sponsored Ads reports) ... by December 31, 2026`.
- how-to-get-it — advertising.amazon.com/GMH8A8AJSH4ATV6T — unified reporting is reached `under Reporting in the left navigation` and lists `Advertised product` among its report templates.
- fields — advertising.amazon.com/columns — sales7d is `Total value of sales occurring within 7 days of an ad click` and sales30d `within 30 days`, so the windows are inclusive rather than additive; attributedSalesSameSku7d is the part of that window `where the purchased SKU was the same as the SKU advertised` and salesOtherSku7d the part where it `was different`.
- limitations — advertising.amazon.com/columns — `cost` and `spend` carry the identical description `Total cost of ad clicks`, so the reference documents no difference between the two columns.
- limitations — advertising.amazon.com/reporting-v2-v3 — the version 2 to version 3 mapping table derives both v3 `cost` and v3 `spend` from the single v2 `cost` metric for Sponsored Products, so Amazon treats them as two names for one measure and states no rule for when they diverge.
- limitations — advertising.amazon.com/GYNVHW8R4QPYUS9H — the console report carries one such column, `Cost (formerly known as Spend on sponsored ads)`, `assessed per click or per 1,000 views depending on cost type`; there is no second spend column there, so the console documentation offers no account of the API divergence either.
- fields — advertising.amazon.com/columns — salesOtherSku7d is `Total value of sales occurring within 7 days of an ad click where the purchased SKU was different from the SKU advertised`, the complement of attributedSalesSameSku7d, which is the same window `where the purchased SKU was the same as the SKU advertised`. Amazon states no reconciliation of the two back to sales7d, and none has been checked against a production file.