
# Work with live Amazon operations

Beyond the warehouse, the platform passes through to Amazon itself: live retail lookups, report generation, pricing, and advertising operations, all using the authorization your accounts already have through MixShift. You skip the developer applications entirely, and the token plumbing (minting, refresh, regional routing) is handled server-side.

## Naming the merchant you mean

Every call below acts for one merchant. Two identifiers name one, and there is no `merchantId` parameter:

- `sellerId`, the merchant token assigned by Amazon (the `A...` / `ENTITY...` string). Enough on its own only when the token maps to a single row; a seller trading in several marketplaces also needs `marketplace`.
- `legacySellerId`, the integer MixShift seller id. Identifies exactly one merchant row and takes precedence. Prefer it when you have it.

`GET /api/amazon/merchants` returns both for every merchant you can act for, and `GET /api/amazon/spapi/operations` returns the same contract as a `merchantIdentifiers` object next to the operation list, so your code never has to hardcode it. Full detail, including why the same distinction matters when you query the warehouse: [Identify a merchant](/knowledge-base/builder-platform/reference/merchant-identifiers).

## Reading from Amazon

- `GET /api/amazon/merchants` lists the merchants your credential can act for.
- **Cataloged operations:** `GET /api/amazon/spapi/operations` and `GET /api/amazon/ads/operations` list every callable operation with its parameters; `POST /api/amazon/spapi/call` and `POST /api/amazon/ads/call` invoke one. The catalogs cover retail (catalog, inventory, FBA inbound shipments, orders, finances, fees, pricing, seller promotions, listings) and advertising (campaigns, ad groups, keywords, targets, budgets, recommendations, bid adjustments, and reporting on both v3 and the [unified Reporting v1](#unified-reporting-v1-for-history-v3-does-not-have)).
- **FBA inbound shipments:** read the shipments on their way to Amazon, not just the stock already received. You get shipment status and destination, the items on a shipment across a date range, and the item list for a single shipment id, which is what you need to reconcile what you sent against what Amazon received. The newer Fulfillment Inbound API (version 2024-03-20) is in the same catalog, read-only: inbound plans, and for each shipment its carrier tracking (a tracking id per box for small parcel, the PRO and bill of lading for freight), its boxes with the case-pack template they were packed with, pallets, the carrier, and the placement fees. It replaces the transport-details call Amazon removed in January 2025, on the same authorization.
- **Seller promotions:** read a seller's own promotions live from Amazon: deals, coupons, price discounts, and basket-building offers. Three operations run on the same `retail:read` authorization as the rest of retail, with nothing extra to request from Amazon. Search promotions for one marketplace by status, type, product, or date; open one for its schedule, budget, discount, purchase requirements, fees, and any issues Amazon has flagged; then page through the products it covers. Read-only, so nothing creates, edits, or cancels a promotion, and for seller accounts only: a vendor merchant gets a `403` `restricted_report`, which is the API being seller-only rather than a re-authorization problem. The operations listing carries the parameters, and the full detail is on the [developer reference](https://mcp.mixshift.io/developers#promotions).
- **Reports:** submit a report request, poll it, and download the document through `/api/amazon/reports`. Pricing has its own batch surface under `/api/amazon/pricing`; a synchronous call takes up to 200 SKUs for Featured Offer Expected Price and up to 100 ASINs for Competitive Summary, and a longer list goes to the matching `/start` endpoint, which accepts any size and runs in the background. Competitive Summary lists are split for you into batches of 20, the most Amazon accepts at once. Report types Amazon has retired fail immediately and name the live replacement to use instead, rather than returning an opaque error from Amazon.

## Unified Reporting v1, for history v3 does not have

Reporting v3 covers most report types with roughly a ninety-five day lookback. `reporting_v1.create_report`, `reporting_v1.retrieve_report`, and `reporting_v1.delete_report` run on the same `ads:read` credential as everything else here, answer across ad products in one report (DSP included), and reach much further back: up to 24 months at daily grain, and 6 years at monthly or yearly grain. Reach for it when you have been rebuilding long-run history out of the warehouse because the API would not give it to you.

It is addressed differently from the rest of the Ads catalog: it is not profile-scoped. You name up to five accounts in `accessRequestedAccounts` instead, as an `advertiserAccountId` or a `managerAccountId`. For a DSP advertiser, find it with `accounts.list_manager_accounts` and pass its numeric `dspAdvertiserId` as the `advertiserAccountId`. The `accountId` listed beside it is a seat id. Amazon rejects it in either slot, and the call fails as `403 profile_not_authorized`, which reads like a permissions failure. A `managerAccountId` is accepted too, but in our testing 1 of 6 manager-scoped reports completed against 3 of 3 addressed to a single advertiser, so address advertisers directly.

Two shapes here will hand you a wrong answer rather than an error, so check for them before you trust a result: time is a dimension, not a `timeUnit`, and `month.value` / `week.value` carry no year, so a window crossing a year boundary can silently merge two different years' same-numbered month into one summed row unless you request `year.value` alongside them; and a completed report's document arrives as an array of presigned urls (`completedReportParts`), so code that reads only the first part truncates the report without failing.

Spend is `metric.totalCost`. There is no `metric.cost`, and like `metric.sales` it needs `budgetCurrency.value` in the same request (verified on Sponsored Ads, not yet confirmed for DSP).

## Updating Sponsored Brands entities

Changing an existing Sponsored Brands keyword, product target or negative target
needs the ad group's id alongside the entity's own id. A campaign id does not
substitute for it, and Amazon rejects the call without it. Negative targets are
identified by `targetId`, not `negativeTargetId`, which Amazon rejects outright
as an unrecognised field.

You do not have to remember either rule. Every operation publishes the fields it
requires as `requiredItemFields` in the operations catalog (`GET
/api/amazon/ads/operations`), so you can validate a body before calling, and the
dry run now checks them too and names what is missing per operation rather than
letting a bad body preview clean and fail against a live account.

## Creating a Sponsored Brands ad

Building a full Sponsored Brands ad from nothing takes an ad group plus one ad-type-specific create, because Amazon exposes a separate endpoint per creative type rather than one shared ad shape. Build in order: create the campaign, create the ad group, then create the ad itself as brand video, video, product collection, or store spotlight, each with its own required creative fields.

Two acceptance rules Amazon enforces that a preview cannot check for you:

- Every asset id (video, brand logo, custom image) must already exist in the Creative Asset Library. There is no upload operation on this surface, so a new video or logo goes in through the Amazon console first; the Creative Asset Library lookup below gives you the id afterward.
- On the ad types that land on your Store, every advertised product must already appear on that Store page, or Amazon rejects the ad.

A dry run checks request shape only and never reaches Amazon, so neither rule above is validated until you commit. Amazon validates per ad, so commit one ad first and read its result before sending the rest of a batch.

## Look up Creative Asset Library assets

Read the newest page of a profile's Creative Asset Library: asset ids, type, approval status, and file metadata (resolution and duration for video, dimensions and aspect ratio for images). Use it to find the id of something just uploaded in the console, or to check which ad programs an asset already qualifies for before building an ad around it.

It returns only the newest page, not the whole library, and the library is scoped per profile, not account-wide: a profile returning no assets does not mean the account has none.

## Advertising writes, with the safety on

Writes to your ad accounts are opt-in (the credential needs the write scope) and default to a dry run:

1. Call the write with default settings and you get a **preview**: validation, a snapshot of current state, and the exact change list. Nothing touches Amazon.
2. Send the explicit commit flag to apply. Changes are capped per call, and every commit is audit-logged with the pre-write snapshot.

This is the same preview-then-confirm model the [plugin](/knowledge-base/plugin) uses; your own tools get it too.

Amazon DSP campaigns and ad groups can be changed the same way. `dsp.update_campaigns` edits a campaign's state, budget caps and flights (up to 5 campaigns per call), and `dsp.update_ad_groups` edits an ad group's state, budget, bids, pacing and dates (up to 20 per call). Each takes the numeric DSP advertiser id, preview comes first, and the result comes back per item. Flights are a full replacement, so send every flight you keep. A server error is never resent automatically, because whether the change applied is unknown until you read the entity again.

## Amazon Marketing Cloud audiences

Amazon Marketing Cloud audiences are the write side of AMC. `amc.create_audience` builds a rule-based audience from SQL over the instance's audience tables and activates it on one destination account, either a DSP advertiser or a sponsored-ads account. `amc.list_audiences` and `amc.get_audience` read status and the failure reason from Amazon, and `amc.update_audience` and `amc.delete_audience` work on failed audiences only, because an audience that succeeded cannot be changed.

They need the `ads:write` scope and preview first, like every other advertising write here. The window you send is the lookback, applied before the SQL runs, so the query carries no date filter of its own. Before anything reaches Amazon, the platform refuses what Amazon would only reject after a run: a trailing semicolon, a refresh outside 0 to 21 days, interval date arithmetic, and a query that reads a paid dataset the instance does not have. The AMC discovery and reporting operations around them stay read-only on `ads:read`; the full reference is on the [developer reference](https://mcp.mixshift.io/developers#amc).

## Placement and audience bid adjustments

`sp.update_campaign_bid_adjustments` and `sb.update_campaign_bid_adjustments` set the modifiers that used to be reachable only in the Amazon console: the percentage a campaign bids up by placement (top of search, product page, rest of search on Sponsored Products; top of search, home, detail page, other on Sponsored Brands) and by audience cohort. They are split out of the regular campaign-update operations, so a modifier change is audited and metered on its own rather than arriving as an untyped campaign edit.

Both operations **replace** the object you send: an entry you leave out does not keep its old value. Read the current modifiers from `sp.list_campaigns` / `sb.list_campaigns` first, and re-send the entries you are not changing. On Sponsored Brands the whole `bidding` object goes back together, `bidOptimization` included, or a modifier edit silently flips the optimization setting with it.

A `percentage` is a whole-number bid *increase*; `0` means no adjustment, so a Sponsored Products modifier can never lower a bid. These are ordinary `ads:write` operations, so they take the same dry-run-by-default contract and per-call cap as every other write here, and the current modifiers are snapshotted to the audit log before the change.

## Listing content writes

Product listing edits (title, highlights, bullets, description, search keywords, ingredients, item form, images) run as a strict two-call contract:

1. **Preview** validates the change against Amazon for up to ten SKUs and returns a change-set id and hash. Nothing is applied.
2. **Commit** takes that id and hash and replays exactly what was previewed. If anything drifted in between, the affected SKU fails closed instead of applying a stale change.

Identifiers, brand fields, compliance and safety attributes, variations, price, quantity, fulfillment, and deletes are refused by design. Images apply asynchronously on the Amazon side (Amazon re-hosts them), so verify by checking that the image slot changed and the listing has no new issues, not by comparing URLs.

## Related

- [Get access](/knowledge-base/builder-platform/getting-started/get-access) (scopes are granted at mint time)
- [Identify a merchant: sellerId and legacySellerId](/knowledge-base/builder-platform/reference/merchant-identifiers)
- [Limits and guardrails](/knowledge-base/builder-platform/reference/limits-and-guardrails)
- Operation-level reference: [mcp.mixshift.io/developers](https://mcp.mixshift.io/developers)