What this report contains
One row per campaign per day, for Sponsored Products. The left-hand side is what you spent — impressions, clicks, cost — and the right-hand side is what Amazon attributed back to it.
What makes this report bigger than it looks is that the outcome side is repeated four times, once per attribution window: 1, 7, 14 and 30 days. Each window is repeated again for units and again for same-SKU, which is how a report about campaigns ends up 43 columns wide. They are not alternative measures of the same thing and they do not sum: purchases_30d includes purchases_7d. Picking a window is picking how much credit a click gets for a slow decision.
The row also carries the campaign's configuration on the day — budget, budget type, bidding strategy, and any budget rule that overrode the configured amount. That is what makes the report self-contained: a campaign that flatlines at its campaign_budget_amount is capped, and you can see it without joining anything.
How to get it
In the Amazon Ads console, this is Measurement and Reporting → Sponsored ads reports, with report category Sponsored Products and report type Campaign. Choose daily time unit, pick your window, and the console emails a link when it is ready.
Through the Amazon Ads API v3, you POST to /reporting/reports with reportTypeId: spCampaigns, adProduct: SPONSORED_PRODUCTS, groupBy: ["campaign"] and timeUnit: DAILY, naming every column you want. Amazon returns a report ID; poll it until the status is COMPLETED and download the gzipped JSON from the URL it hands back. Generation can take as long as three hours, and startDate to endDate may not exceed 31 days.
Two things about v3 that the v2 API did not do. First, you get exactly the columns you asked for — nothing arrives that you did not request, so a missing column is your request, not Amazon's schema. Second, some columns are only available at certain groupBy values: the campaign_* configuration columns in this report exist because it groups by campaign.
Reports are per-profile, so a seller in five marketplaces runs five requests and gets five files, each in its own currency.
Sample rows
Illustrative values, not data from a real account. Shown to give the shape of the file.
| date | campaign_name | campaign_status | impressions | clicks | click_through_rate | cost | purchases_7d | sales_7d |
|---|---|---|---|---|---|---|---|---|
| 2026-09-14 | Brand Defense - Exact | ENABLED | 41207 | 612 | 1.485 | 428.40 | 63 | 2519.37 |
| 2026-09-14 | Category Targeting - Auto | ENABLED | 128940 | 1341 | 1.040 | 938.70 | 74 | 2072.26 |
| 2026-09-14 | Competitor ASINs - Manual | ENABLED | 22118 | 204 | 0.922 | 193.80 | 11 | 384.89 |
| 2026-09-14 | Top Sellers - Broad | ENABLED | 9874 | 88 | 0.891 | 70.40 | 4 | 119.96 |
| 2026-09-14 | New Launch - Discovery | ENABLED | 3160 | 19 | 0.601 | 22.61 | 0 | 0.00 |
Field reference
| Column | Type | Description |
|---|---|---|
date | date | The advertising day the row's metrics are attributed to, in the marketplace's own timezone. No time component — this is the column to partition on. |
campaign_id | string | Amazon's numeric campaign identifier, carried as a string because it is a join key and a numeric type would silently drop a leading zero. |
campaign_name | string | The campaign name as it stood when the report ran. Renaming a campaign rewrites this in history, so join on campaign_id and never on the name. |
campaign_status | string | Whether the campaign was enabled, paused or archived. Reflects status at report time, not on the row's date. |
campaign_bidding_strategy | string | The bidding strategy in force. Observed values in production files are legacy, manual, ruleBased and optimizeForSales — Amazon's API names, not the console's "down only / up and down / fixed" labels. Changing it mid-flight is one of the commonest explanations for a step change in CPC. |
campaign_budget_amount | decimal | The campaign's configured daily budget. A campaign whose spend sits at this number day after day is capped, and the report will not tell you what it missed. |
campaign_budget_type | string | Whether the budget is daily or a lifetime total. |
campaign_budget_currency_code | string | The currency of the budget and of every money column in the row. Essential once you pull more than one marketplace into the same table. |
campaign_rule_based_budget_amount | decimal | The budget actually in force when a budget rule overrode the configured amount. Frequently null — it is populated only while a rule applies. |
campaign_applicable_budget_rule_id | string | The identifier of the budget rule that applied, if any. |
campaign_applicable_budget_rule_name | string | The name of the applied budget rule, for reporting without a second lookup. |
impressions | int64 | Times an ad from this campaign was displayed. |
clicks | int64 | Clicks on those ads. The billable event for Sponsored Products. |
click_through_rate | float64 | Clicks divided by impressions. Amazon computes this per row, so re-deriving it over an aggregate means recomputing from the raw counts rather than averaging the column. |
cost | decimal | What the clicks cost. Identical to spend on every observed row; both are carried because both are in Amazon's vocabulary. |
spend | decimal | Amazon's other name for cost. Carried so a consumer reading either finds it, but nobody should treat them as independent measures. |
cost_per_click | decimal | Average cost per click for the row. Like CTR, recompute from cost and clicks when aggregating rather than averaging the column. |
purchases_1d | int64 | Orders attributed to a click within 1 day. The tightest window, and the one closest to what a same-session buyer looks like. |
purchases_7d | int64 | Orders attributed within 7 days. The de facto industry default, and what most ACOS figures quietly mean. |
purchases_14d | int64 | Orders attributed within 14 days — the Amazon Ads console's own default for Sponsored Products. |
purchases_30d | int64 | Orders attributed within 30 days. The most generous window, and the slowest to settle. |
purchases_same_sku_1d | int64 | The subset of purchases_1d that were the exact advertised SKU rather than any other product the shopper bought after clicking. |
purchases_same_sku_7d | int64 | Same-SKU subset of purchases_7d. |
purchases_same_sku_14d | int64 | Same-SKU subset of purchases_14d. |
purchases_same_sku_30d | int64 | Same-SKU subset 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. |
sales_1d | decimal | Attributed sales value within 1 day. Divide cost by this for a 1-day ACOS. |
sales_7d | decimal | Attributed sales value within 7 days — the numerator behind most quoted ROAS. |
sales_14d | decimal | Attributed sales value within 14 days, matching the console's default view. |
sales_30d | decimal | Attributed sales value within 30 days. |
attributed_sales_same_sku_1d | decimal | The portion of sales_1d from the advertised SKU itself. The gap between the two is halo — other products bought after the click. |
attributed_sales_same_sku_7d | decimal | Same-SKU portion of sales_7d. |
attributed_sales_same_sku_14d | decimal | Same-SKU portion of sales_14d. |
attributed_sales_same_sku_30d | decimal | Same-SKU portion of sales_30d. |
kindle_edition_normalized_pages_read_14d | int64 | KENP pages read within 14 days, for KDP titles enrolled in Kindle Unlimited. Zero for every physical product. |
kindle_edition_normalized_pages_royalties_14d | decimal | Royalties earned on those KENP pages. For KDP advertisers this is real revenue that no ACOS calculation based on sales_* will include. |
Use cases
Calculating ACOS and ROAS you can defend. ACOS is cost ÷ sales_Nd and ROAS is its inverse. Fix the window across every report you publish — most teams settle on 7 or 14 days — and say which one you used, because the same campaign can show 22% ACOS at 7 days and 17% at 30.
Finding budget-capped campaigns. Compare daily cost against campaign_budget_amount. A campaign that hits its cap before the day ends stops bidding, and the demand it missed appears nowhere in this report — it is invisible loss, and the only signal is the cap itself.
Separating halo from direct sales. The gap between sales_7d and attributed_sales_same_sku_7d is revenue from other products bought after the click. A campaign with poor same-SKU ACOS but strong total ACOS is working; judging it on the advertised SKU alone would have you switch it off.
Auditing a CPC step change. campaign_bidding_strategy and campaign_budget_amount on the row mean a jump in cost_per_click can be checked against a same-day settings change before anyone blames the auction.
Measuring how long your category takes to convert. The ratio of purchases_1d to purchases_30d is a direct read on deliberation time. High-consideration products show a wide spread; impulse buys converge almost immediately, and that tells you which window to standardise on.
Limitations and gotchas
Attribution windows nest — never add them. sales_30d contains sales_14d contains sales_7d contains sales_1d. Summing them inflates revenue roughly fourfold, and it is by some distance the most common error made with this report.
Recent days keep changing. Amazon restates conversion data 1, 7 and 28 days after the conversion event, and because conversions are reported against the date of the ad interaction a 30-day window can still be revised nearly two months after the advertising day. Amazon says conversion data is subject to change for up to 60 days back, and recommends re-pulling monthly. Click and impression data moves too, for up to three days, as invalid traffic is filtered out. Any snapshot you take of yesterday will disagree with the same day re-pulled in a fortnight — that is attribution settling, not a bug.
cost and spend are the same number. Both are requested and carried because both are in Amazon's vocabulary, but they are not independent measures and adding them doubles your spend.
Campaign names are mutable and reported as-of-now. A campaign renamed today has its new name on rows from three weeks ago. Join on campaign_id.
Don't average the rate columns. click_through_rate and cost_per_click are computed per row. Averaging them across days or campaigns weights a 12-impression day the same as a 120,000-impression one. Recompute from clicks, impressions and cost.
Sponsored Brands and Sponsored Display are separate reports. This one covers Sponsored Products only. A total ad spend figure needs all three, and their columns do not line up.
KENP is invisible to ACOS. For KDP advertisers, kindle_edition_normalized_pages_royalties_14d is real revenue that no sales_* column includes, so ACOS computed the usual way overstates the true cost of advertising a Kindle Unlimited title.
FAQ
Whichever you use consistently. 7 days is the common default for internal reporting and 14 is the console's default for Sponsored Products, so the two rarely agree by accident — the important thing is to fix one and label it.
Invoices bill on a different cycle and in the account's billing currency, and this report is attributed by advertising day in the marketplace's timezone. Small discrepancies at period boundaries are normal; large ones usually mean a marketplace is missing from the pull.
purchases_7d counts orders; units_sold_clicks_7d counts units within them. An order for three units is one purchase and three units.
Sales of the exact product that was advertised, as opposed to anything else the shopper bought after clicking. The difference between the two is the halo effect.
Amazon retains 95 days of history for spCampaigns, but a single request can span at most 31 days — so covering the full window takes four requests, not one. Anything older than 95 days has to be accumulated by pulling on a schedule and storing the results. The 60- and 65-day limits often quoted belong to the Sponsored Brands and Sponsored Display campaign reports.
No. Every sales column here is attributed to an ad click. Organic performance comes from the Sales and Traffic report.
Sources
Every researched claim on this page, and the Amazon or Walmart page it came from.
- history_window — advertising.amazon.com/campaign — the campaign report configuration table gives `spCampaigns` a data retention of 95 days and a maximum date range of 31 days per request. The 60- and 65-day figures in that table belong to `sbCampaigns` and `sdCampaigns`, not to Sponsored Products.
- history_window — advertising.amazon.com/faq — lists a "longer historical reporting window of up to 95 days (versus 60 days for version 2 reports)" and "date ranges up to 31 days" among the version 3 benefits.
- 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, so a 14-day window can restate up to 42 days after the report date. Also: "Report generation can take as long as three hours."
- latency — advertising.amazon.com/overview — conversion data "is subject to change for up to 60 days back from the current date", and click data should be re-pulled after at least 5 days because invalid-traffic detection runs for up to 30 days.