The Amazon USA product API is the same set of endpoints with marketplaceId=ATVPDKIKX0DER, the ID of amazon.com. Three things make it different from every other marketplace this API covers: it is one of the 11 domains with full price-history coverage, so no endpoint answers a free 400; statistics prices are integers in cents and need dividing by 100; and Amazon's own first-party seller ID happens to equal the marketplace ID itself, which is true nowhere else. The script below reads an ASIN correctly across all three live endpoints at 3 credits per ASIN.
Key Takeaways
- amazon.com is marketplaceId ATVPDKIKX0DER, and it is one of only 11 marketplaces where statistics, estimated sales and the ASIN converter work; the other 12 get a free 400.
- Lookup and offers prices are decimal dollars (444.99); statistics prices are integers in cents (44499), so divide statistics values by 100 before comparing them to lookup prices.
- offers[].totalPrice is rounded to 2 decimals; the top-level buyBox.totalPrice is an unrounded float sum of item price and shipping (444.97999999999996), so round it client-side.
- When Amazon itself holds the Buy Box, its amazonSellerId on amazon.com is ATVPDKIKX0DER, the same value as marketplaceId; on every other covered marketplace the two values differ.
- Lookup, offers and statistics cost 3 credits per ASIN; a malformed ASIN is filtered out before it can cost anything, and a 404 is billed once and not retried.
What is different about the Amazon USA product API?
Nothing in the request shape: the same endpoints, the same X-Api-Key header, one marketplace ID. The differences are in coverage and in the data. Coverage-wise, amazon.com is one of the 11 marketplaces (with amazon.co.uk, amazon.de, amazon.fr, amazon.co.jp, amazon.ca, amazon.it, amazon.es, amazon.in, amazon.com.mx and amazon.com.br) where /amazon-product-statistics, /amazon-product-search-estimated-sells and /amazon-asin-converter all return data instead of a free 400. Data-wise, prices differ by endpoint and Amazon's own seller ID is a special case. The full list of marketplace IDs is in the Amazon marketplace IDs guide; which endpoints cover which of the 23 marketplaces is in the marketplace coverage guide.
| Field | On amazon.com | Handle it by |
|---|---|---|
| marketplaceId | ATVPDKIKX0DER (amazon.com, USD) | pass it on every call |
| lookup and offers prices | decimal dollars, e.g. 444.99, or "N/A" | show with 2 decimals |
| statistics price series | integers in minor units (cents) | divide by 100 |
| listedSinceDate | YYYY-MM-DD, English "Date First Available" label | always the baseline case |
| Amazon as Buy Box holder | sellerId "Amazon", amazonSellerId ATVPDKIKX0DER | ONLY marketplace where amazonSellerId == marketplaceId |
| history endpoints (statistics, estimated sales, ASIN converter) | all available (1 of 11 marketplaces) | no free-400 gate, unlike 12 of the 23 marketplaces |
Which endpoints work on amazon.com?
All ten. amazon.com is one of the 11 marketplaces with full history coverage, so unlike amazon.se, amazon.pl, amazon.ae and 9 other marketplaces, the three history-based endpoints work here too, at the same 1 credit per call as everything else.
| Endpoint | Works on amazon.com? | Cost | Returns |
|---|---|---|---|
| /amazon-product-offers | yes | 1 credit | live offers in USD |
| /amazon-product-lookup | yes | 1 credit | listing data, listedSinceDate populated |
| /amazon-search | yes | 1 credit | page one for a keyword |
| /amazon-bestsellers | yes | 1 credit | amazon.com's own category tree |
| /amazon-deals | yes | 1 credit | current deals |
| /amazon-seller-review | yes | 1 credit | feedback on amazon.com |
| /amazon-product-statistics | yes | 1 credit | full price and rank history |
| /amazon-product-search-estimated-sells | yes | 1 credit | monthly sales estimate |
| /amazon-asin-converter | yes | 1 credit | UPC/EAN/ISBN to ASIN |
How do I call the Amazon USA product API in Python?
check() makes three calls per ASIN: /amazon-product-lookup for the title and the current Buy Box item price, /amazon-product-offers for the live, deduplicated offer list and the landed Buy Box price, and /amazon-product-statistics for the 90-day landed price range and the Buy Box holder history. to_major() turns the statistics integer into dollars by dividing by 100, and dedupe_sellers() removes the duplicate rows offers can contain for the same seller. get_with_retry comes from retry.py and ApiError and new_session from sellermagnet.py, both from the Python quickstart. A 401, a 403 or a 503 stops the whole run, not just the one ASIN, since every remaining ASIN would hit the same wall; a 404 is reported for its ASIN only and the run goes on without spending another credit on it.
us_products.py - lookup, offers and statistics on amazon.com, cents handled, dedupe applied
import re
import sys
from datetime import date, timedelta
import requests
from retry import get_with_retry
from sellermagnet import ApiError, new_session
MARKETPLACE_ID = "ATVPDKIKX0DER" # amazon.com
AMAZON_SELLER_ID = "ATVPDKIKX0DER" # on amazon.com this equals MARKETPLACE_ID (nowhere else)
ASIN_RE = re.compile(r"^[A-Z0-9]{10}$")
STOP = (401, 403, 503) # bad key, no credits, marketplace circuit breaker: stop
RANGE_DAYS = 90
def to_major(cents: int) -> float:
"""/amazon-product-statistics prices are integers in minor units; USD has 2, so divide by 100."""
return cents / 100
def usd(amount: float) -> str:
return f"${amount:,.2f}"
def dedupe_sellers(offers: list[dict]) -> list[dict]:
"""Offers can list the same seller twice; dedupe on (sellerId, deliveryDate, condition, fulfillmentType)."""
seen = set()
unique = []
for o in offers:
key = (o.get("sellerId"), o.get("deliveryDate"), o.get("condition"), o.get("fulfillmentType"))
if key in seen:
continue
seen.add(key)
unique.append(o)
return unique
def buy_box_range(history: list, today: date) -> str:
"""Low and high of the landed Buy Box price series (item + shipping) over RANGE_DAYS."""
cutoff = (today - timedelta(days=RANGE_DAYS)).isoformat()
values = [v for ts, v in history if ts[:10] >= cutoff]
if not values:
return f"no Buy Box price in {RANGE_DAYS} days"
return f"{RANGE_DAYS}-day landed Buy Box {usd(to_major(min(values)))} to {usd(to_major(max(values)))}"
def check(session, asin: str, today: date) -> list[str]:
lines = [asin]
info = get_with_retry(session, "amazon-product-lookup", asin=asin, marketplaceId=MARKETPLACE_ID)["productInfo"]
box = info.get("buyBoxInfo") or {}
item_price = box.get("price") # decimal dollars, or "N/A" with no featured offer
lines.append(f" {info['title'][:60]}")
lines.append(f" lookup item price {usd(item_price) if isinstance(item_price, (int, float)) else 'N/A'}")
offers_data = get_with_retry(session, "amazon-product-offers", asin=asin, marketplaceId=MARKETPLACE_ID)
buy_box = offers_data.get("buyBox") or {}
offers = dedupe_sellers(offers_data.get("offers") or [])
if buy_box:
landed = round(buy_box["totalPrice"], 2) # buyBox.totalPrice is an unrounded float sum, round it
lines.append(f" offers landed Buy Box {usd(landed)} ({len(offers)} unique seller(s))")
else:
lines.append(f" offers: no featured offer ({len(offers)} unique seller(s) listed)")
amazon_offer = next((o for o in offers if o.get("sellerId") == "Amazon"), None)
if amazon_offer:
matches = amazon_offer.get("amazonSellerId") == MARKETPLACE_ID
lines.append(f" Amazon itself is an offer; its amazonSellerId {'equals' if matches else 'differs from'}"
f" the marketplace ID (amazon.com only)")
stats = get_with_retry(session, "amazon-product-statistics", asin=asin, marketplaceId=MARKETPLACE_ID)
lines.append(f" {buy_box_range(stats.get('buyBoxPriceHistory') or [], today)}")
holder_history = stats.get("buyBoxSellerIdHistory") or []
no_holder_days = sum(1 for ts, seller in holder_history if seller == "-1")
if no_holder_days:
lines.append(f" {no_holder_days} recorded point(s) with no Buy Box holder (\"-1\")")
return lines
def main(asins: list[str]) -> None:
today = date.today()
session = new_session()
for raw in asins:
asin = raw.strip().upper()
if not ASIN_RE.fullmatch(asin):
print(f"{raw} skipped: not a 10-character ASIN, no credit spent")
continue
try:
for line in check(session, asin, today):
print(line)
except ApiError as err:
print(f"{asin} error {err.status}: {err}")
if err.status in STOP:
sys.exit(1)
except requests.RequestException as err:
print(f"{asin} network error: {type(err).__name__}")
if __name__ == "__main__":
main(sys.argv[1:] or ["B0CL61F39H", "B0EXAMPLE2"])
Output for two ASINs (B0CL61F39H is a documented example; the second is illustrative)
$ python us_products.py B0CL61F39H B0EXAMPLE2 # second ASIN is illustrative
B0CL61F39H
PlayStation®5 console (slim)
lookup item price $444.99
offers landed Buy Box $444.98 (2 unique seller(s))
Amazon itself is an offer; its amazonSellerId equals the marketplace ID (amazon.com only)
90-day landed Buy Box $447.98 to $469.99
1 recorded point(s) with no Buy Box holder ("-1")
B0EXAMPLE2
Stainless Steel Insulated Bottle 20oz
lookup item price $18.99
offers landed Buy Box $18.99 (1 unique seller(s))
90-day landed Buy Box $18.99 to $19.99

Why are Amazon USA statistics prices divided by 100?
Statistics price series are integers in minor units, and the US dollar has 2, so 44499 means $444.99, not $44,499. The lookup and offers endpoints already return decimal dollars (444.99), which only needs 2-decimal formatting. The statistics series (buyBoxPriceHistory and the rest) are landed prices (item plus shipping), while the lookup price is the item price alone, so the two can differ by the shipping charge, same as the offers endpoint's own unrounded buyBox.totalPrice. The price history API guide lists every series.
Trimmed lookup response on amazon.com (example values)
{
"success": true,
"data": {
"productInfo": {
"asin": "B0CL61F39H",
"marketplaceId": "ATVPDKIKX0DER",
"title": "PlayStation®5 console (slim)",
"buyBoxInfo": {"price": 444.99, "currencyCode": "USD", "currencySymbol": "$",
"sellerId": "Amazon", "amazonSellerId": "ATVPDKIKX0DER"},
"bestsellerRanks": {"main_category": {"name": "Video Games", "rank": 31}},
"link": "https://www.amazon.com/dp/B0CL61F39H"
}
}
}
Why does Amazon's seller ID equal the marketplace ID on amazon.com?
On every other marketplace with a tracked first-party seller ID, the two values are unrelated: amazon.ca's marketplace ID is A2EUQ1WTGCTBG2 while Amazon's own seller ID there is A3DWYIK6Y9EEQB; amazon.co.jp's marketplace ID is A1VC38T7YXB528 while Amazon's seller ID there is AN1VRQENFRJN5. On amazon.com both are ATVPDKIKX0DER (the shared first-party seller ID table that backs the amazonSellerId field on lookup and offers). A check that assumes the two IDs are always different, or always the same, will misread one marketplace or the other; compare offers[].sellerId == "Amazon" (works everywhere) rather than comparing IDs directly, unless the code only ever targets amazon.com.

How many credits does the script use?
Three per ASIN: one lookup, one offers and one statistics call. A 404 on the lookup is billed and skips the remaining calls for that ASIN; a 502 or 503 is billed on every attempt of get_with_retry, a 500 is refunded and retried once, and the free gate errors (400 for a missing parameter, 401, 403, 429) cost nothing. To see the same product on another marketplace, the cross-marketplace price comparison runs one lookup per marketplace; plans are on Pricing.
Frequently Asked Questions
What is the Amazon USA marketplace ID?
ATVPDKIKX0DER is amazon.com. Pass it as marketplaceId on every call; prices come back in US dollars (USD).
Is amazon.com one of the 11 marketplaces with full price history?
Yes. amazon.com, amazon.co.uk, amazon.de, amazon.fr, amazon.co.jp, amazon.ca, amazon.it, amazon.es, amazon.in, amazon.com.mx and amazon.com.br are the 11 domains with statistics, estimated sales and the ASIN converter; the other 12 marketplaces get a free 400 on those three endpoints.
Why does Amazon's own seller ID equal the marketplace ID on amazon.com?
It is how the underlying seller directory happens to be keyed for amazon.com; every other covered marketplace (amazon.ca, amazon.de, amazon.co.jp and the rest) has its own, different first-party seller ID. A hardcoded "if sellerId == marketplaceId" check only works on amazon.com.
Are amazon.com prices in cents?
Lookup and offers return decimal dollars such as 444.99. Statistics returns integers in minor units, which for USD means cents, so 44499 there means $444.99 and must be divided by 100.
Does Date First Available work normally on amazon.com?
Yes. It is read from the English "Date First Available" label, the same phrase match other marketplace guides (amazon.co.jp, amazon.se) are compared against; amazon.com needs no swap or fallback handling.
Bottom line: on amazon.com every endpoint is available, statistics prices are cents and need dividing by 100, and Amazon's own seller ID happens to equal the marketplace ID, a coincidence true nowhere else this API covers. A free account includes 150 credits, enough for 50 ASINs with this script.