Amazon API marketplace coverage depends on the endpoint. Six SellerMagnet API endpoints read Amazon's live pages and accept all 23 marketplace IDs: product lookup, offers, search, bestsellers, deals and seller reviews. Three answer from recorded history and cover 11 marketplaces: statistics, sales estimates and the ASIN converter. On the other 12 they answer a free 400, and the marketplace list itself costs one credit.
Key Takeaways
- Product lookup, offers, search, bestsellers, deals and seller reviews accept all 23 Amazon marketplace IDs.
- Statistics, sales estimates and the ASIN converter cover 11 marketplaces: amazon.com, .ca, .com.mx, .com.br, .co.uk, .de, .fr, .it, .es, .in and .co.jp.
- On the other 12, including amazon.nl, .se, .pl, .com.be, .ie and .com.au, those three answer a 400 before any credit is charged.
- A covered request is billed even when it answers 404, so there is no free way to test coverage: keep the table in your code.
- An unknown or misspelled marketplace ID is a free 400 on every endpoint that takes one;
/amazon-get-marketplaceslists all 23 for one credit.
Amazon API marketplace coverage by endpoint
The split follows where the data comes from. An endpoint that reads a live Amazon page accepts every marketplace the API knows; an endpoint that answers from recorded history needs that history, and it exists for 11 marketplaces. The marketplace list, /amazon-get-marketplaces, takes no marketplace ID at all. All IDs and domains are in the marketplace IDs list; parameters per endpoint are in the API documentation.
| Endpoint | Reads | Marketplaces |
|---|---|---|
/amazon-product-lookup | The live product page | All 23 |
/amazon-product-offers | The live offer listing (first page) | All 23 |
/amazon-search | The live search results (page one) | All 23 |
/amazon-bestsellers | A live Best Sellers list | All 23 (amazon.ie uses amazon.co.uk category IDs) |
/amazon-deals | The live deals page | All 23 |
/amazon-seller-review | The live seller feedback page | All 23 |
/amazon-product-statistics | Recorded price, rank and Buy Box history | 11; free 400 on the other 12 |
/amazon-product-search-estimated-sells | Recorded history (monthly sales estimate) | 11; free 400 on the other 12 |
/amazon-asin-converter | Recorded product codes (ASIN and EAN) | 11; free 400 on the other 12 |
/amazon-get-marketplaces | The API's own marketplace list | Takes no marketplace ID; lists all 23 |

Which 11 marketplaces have history data?
Eleven: amazon.com, .ca, .com.mx, .com.br, .co.uk, .de, .fr, .it, .es, .in and .co.jp. Every other marketplace ID the API accepts gets the live-page endpoints only: no price or rank history, no monthly sales estimate and no ASIN to EAN conversion. Those 12 are amazon.nl, .com.be, .se, .pl, .ie, .com.tr, .ae, .sa, .eg, .co.za, .sg and .com.au. For a seller comparing stores, the marketplace expansion guide shows how to read competition where estimates are missing.
| Marketplace | Marketplace ID | Currency | History endpoints |
|---|---|---|---|
| amazon.com | ATVPDKIKX0DER | USD | Yes |
| amazon.ca | A2EUQ1WTGCTBG2 | CAD | Yes |
| amazon.com.mx | A1AM78C64UM0Y8 | MXN | Yes |
| amazon.com.br | A2Q3Y263D00KWC | BRL | Yes |
| amazon.co.uk | A1F83G8C2ARO7P | GBP | Yes |
| amazon.ie | A28R8C7NBKEWEA | EUR | No (free 400) |
| amazon.de | A1PA6795UKMFR9 | EUR | Yes |
| amazon.fr | A13V1IB3VIYZZH | EUR | Yes |
| amazon.it | APJ6JRA9NG5V4 | EUR | Yes |
| amazon.es | A1RKKUPIHCS9HS | EUR | Yes |
| amazon.nl | A1805IZSGTT6HS | EUR | No (free 400) |
| amazon.com.be | AMEN7PMS3EDWL | EUR | No (free 400) |
| amazon.se | A2NODRKZP88ZB9 | SEK | No (free 400) |
| amazon.pl | A1C3SOZRARQ6R3 | PLN | No (free 400) |
| amazon.com.tr | A33AVAJ2PDY3EV | TRY | No (free 400) |
| amazon.ae | A2VIGQ35RCS4UG | AED | No (free 400) |
| amazon.sa | A17E79C6D8DWNP | SAR | No (free 400) |
| amazon.eg | ARBP9OOSHTCHU | EGP | No (free 400) |
| amazon.co.za | AE08WJ6YKNBMC | ZAR | No (free 400) |
| amazon.co.jp | A1VC38T7YXB528 | JPY | Yes |
| amazon.in | A21TJRUUN4KGV | INR | Yes |
| amazon.sg | A19VAU5U5O7RUS | SGD | No (free 400) |
| amazon.com.au | A39IBJ37TRP1C6 | AUD | No (free 400) |

What happens on a marketplace an endpoint does not cover?
The API refuses the request before it charges for it. It checks in this order: the API key, the required parameters, the marketplace ID, then, on the three history endpoints, whether the marketplace is covered; only after that is the credit deducted. A refusal at any of these checks costs nothing: a bad key is a 401, the other three are 400s. The coverage refusal looks like this, and its message lists the supported domains:
Response of /amazon-product-statistics for amazon.nl (A1805IZSGTT6HS): HTTP 400, no credit charged
{
"error": "Bad request",
"message": "This endpoint is not available for the requested marketplace. Supported: amazon.com, .ca, .com.mx, .com.br, .co.uk, .de, .fr, .it, .es, .in and .co.jp.",
"success": false
}
| Request | Answer | Billed |
|---|---|---|
No marketplaceId, or a blank one | 400 Missing required parameter(s): marketplaceId | No |
An unknown ID: a country code such as US, a domain, a lowercase ID | 400 Invalid marketplaceId | No |
| Statistics, estimates or the converter on one of the 12 uncovered marketplaces | 400 This endpoint is not available for the requested marketplace | No |
/amazon-bestsellers with a category ID from another marketplace's tree | 400 Invalid CategoryId | Yes |
| A covered request for a product that is not found there | 404 | Yes |
| A covered request that succeeds | 200 | Yes, 1 credit |
Two consequences. First, there is no free way to find out whether a marketplace is covered: a refused request costs nothing, but a covered one runs and is billed, even when the product is not found. Keep the coverage table in your code instead of probing. Second, retrying the coverage 400 is pointless; it is an answer, not an outage, so record the marketplace as not covered and move on.
History stored before 19 September 2026
Until 19 September 2026 the three history endpoints did not refuse the uncovered marketplaces; they answered with another marketplace's data (amazon.com, or amazon.co.uk for amazon.ie). If you stored statistics, estimates or barcode matches for an uncovered marketplace before that date, those rows describe another marketplace: delete them.
Skip the requests a marketplace cannot answer
The script below checks a list of listings, one ASIN per marketplace: the live Buy Box from /amazon-product-offers on every marketplace and the monthly sales estimate only where history exists. covered() is the coverage table in four lines. ask() treats a coverage 400 from the server as "not covered", not as an error, and drops that marketplace from the table for the rest of the run, in case the table is out of date. It also skips the estimate when the offers call returned 404, because the ASIN is not listed there. get_with_retry comes from retry.py, and ApiError and new_session from sellermagnet.py, both published in the Python quickstart. A 401 or 403 (a key or credits problem, never billed) stops the run, and so do three failed calls.
Install requests, set the key, run the check
pip install requests
export SELLERMAGNET_API_KEY="your-key-here"
python3 marketplace_coverage.py
marketplace_coverage.py: live offers on every marketplace, estimates only where history exists
"""Live offers on every Amazon marketplace, sales estimates only where the API has history data.
/amazon-product-offers, like lookup, search, bestsellers, deals and seller-review, accepts all 23 marketplace IDs.
/amazon-product-search-estimated-sells, like statistics and the ASIN converter, answers on 11 marketplaces and
returns a free 400 on the other 12, so the script does not send those requests at all.
Helpers: sellermagnet.py and retry.py from https://sellermagnet-api.com/blog/amazon-product-api-python
"""
import re
import requests
from retry import get_with_retry
from sellermagnet import ApiError, new_session
LISTINGS = [ # (ASIN, marketplace ID): one row per store you sell in
("B0CLTBHXWQ", "APJ6JRA9NG5V4"), # amazon.it
("B0CLTBHXWQ", "A1PA6795UKMFR9"), # amazon.de
("B0CLTBHXWQ", "A1805IZSGTT6HS"), # amazon.nl
("B0CLTBHXWQ", "A2NODRKZP88ZB9"), # amazon.se
("B0CLTBHXWQ", "A28R8C7NBKEWEA"), # amazon.ie
("B0CL61F39H", "ATVPDKIKX0DER"), # amazon.com
("B0CL61F39H", "A39IBJ37TRP1C6"), # amazon.com.au
("B0CL61F39H", "US"), # a country code, not a marketplace ID
]
OFFERS, ESTIMATES = "amazon-product-offers", "amazon-product-search-estimated-sells"
HISTORY_ENDPOINTS = {"amazon-product-statistics", ESTIMATES, "amazon-asin-converter"}
HISTORY_DOMAINS = {"amazon.com", "amazon.ca", "amazon.com.mx", "amazon.com.br", "amazon.co.uk", "amazon.de",
"amazon.fr", "amazon.it", "amazon.es", "amazon.in", "amazon.co.jp"}
NOT_COVERED = "This endpoint is not available for the requested marketplace"
MAX_FAILED = 3 # 502/503 are billed on every retry: stop after 3 failed calls
def covered(endpoint, domain):
if endpoint in HISTORY_ENDPOINTS: # 11 marketplaces
return domain in HISTORY_DOMAINS
return True # all 23 marketplaces
def ask(session, endpoint, asin, mid, domain):
"""(data, "", False) or (None, reason, failed). A 401/403 (key or credits, never billed) stops the run."""
if not covered(endpoint, domain):
return None, "not covered, not sent", False
try:
return get_with_retry(session, endpoint, asin=asin, marketplaceId=mid), "", False
except ApiError as err:
if err.status in (401, 403):
raise
if err.status == 400 and NOT_COVERED in str(err):
HISTORY_DOMAINS.discard(domain) # the set above is out of date: trust the server (a free 400)
return None, "not covered, free 400", False
if err.status == 404: # not found on that store: a billed answer, not an outage
return None, "404, billed", False
return None, f"error {err.status}", True
except requests.RequestException as err:
return None, type(err).__name__, True
def buy_box(offers):
total = (offers.get("buyBox") or {}).get("totalPrice")
if offers.get("buyBoxSuppressed") or not isinstance(total, (int, float)) or total <= 0:
return "no featured offer"
return f"{total:.2f} {(offers.get('currency') or {}).get('code', '')}".strip()
def row(store, asin, price, units):
print(f"{store:<14} {asin:<10} {price:<22} {units}")
def main():
session = new_session()
markets = get_with_retry(session, "amazon-get-marketplaces") # 1 credit; cache it in a real job
row("store", "asin", "buy box", "est. units/month")
failed = 0
for asin, mid in dict.fromkeys(LISTINGS): # a repeated row is looked up once
domain = (markets.get(mid) or {}).get("marketplace_domain")
if domain is None or not re.fullmatch(r"[0-9A-Z]{10}", asin): # unknown ID (free 400) or bad ASIN
row(mid, asin, "not sent: unknown ID" if domain is None else "not sent: bad ASIN", "-")
continue
offers, price, bad = ask(session, OFFERS, asin, mid, domain)
units = "not sent" # a 404 or a failed offers call: no estimate either
if offers is not None:
price = buy_box(offers)
sales, units, bad = ask(session, ESTIMATES, asin, mid, domain)
if sales is not None:
units = str(sales.get("estimated_monthly_sales", "-"))
row(domain, asin, price, units)
failed += bad
if failed >= MAX_FAILED:
print(f"stopped after {failed} failed calls")
break
if __name__ == "__main__":
try:
main()
except ApiError as err: # the marketplace list failed, or a 401/403
raise SystemExit(f"stopped: {err}")
Output of marketplace_coverage.py (illustrative data, prices in each store's currency)
store asin buy box est. units/month
amazon.it B0CLTBHXWQ 469.99 EUR 600
amazon.de B0CLTBHXWQ 449.99 EUR 1500
amazon.nl B0CLTBHXWQ 459.99 EUR not covered, not sent
amazon.se B0CLTBHXWQ 404, billed not sent
amazon.ie B0CLTBHXWQ 479.98 EUR not covered, not sent
amazon.com B0CL61F39H 444.99 USD 4000
amazon.com.au B0CL61F39H 679.00 AUD not covered, not sent
US B0CL61F39H not sent: unknown ID -
amazon.nl, amazon.ie and amazon.com.au return a Buy Box price but no estimate, because the request was never sent. amazon.se answers 404: the ASIN is not listed there, the call is billed, and the script does not pay for an estimate on top. The last row uses the country code US instead of a marketplace ID, so nothing is sent. Every price is buyBox.totalPrice, the featured offer's item price plus shipping, which the API returns unrounded; the script prints it with 2 decimals.
Credit math: every request costs 1 credit, so the run above made 11 billed requests: 1 for the marketplace list, 7 offers calls (the 404 on amazon.se included) and 3 estimates. Four estimate requests were never sent, three for marketplaces without history and one after the 404. Skipping the three uncovered estimates saves no credits, because the API would refuse them for free; it saves round trips and keeps expected refusals out of your error log. A 404 is billed and not retried, 502 and 503 are billed on every attempt (up to 4 here), a 500 without a Retry-After header is refunded, and 429, 401 and 403 are free. MAX_FAILED stops the script after 3 failed calls, at most 12 billed attempts. Plans and credit prices are on the pricing page.
What else changes between marketplaces?
- Currency: prices come back in the marketplace's currency (
currency_codein the marketplace list), for example EUR on amazon.ie, SEK on amazon.se, PLN on amazon.pl, MXN on amazon.com.mx and BRL on amazon.com.br. - Category IDs: numeric bestseller category IDs belong to one marketplace's tree (amazon.de and amazon.co.uk share none), and amazon.ie uses the amazon.co.uk tree. The category IDs guide shows where to find them.
- Amazon as a seller: on the offers endpoint, Amazon's own offer carries
amazonSellerId, Amazon's seller ID for that marketplace. It is null on amazon.in and amazon.sg, which have no first-party Amazon seller. - Seller feedback: a seller ID is the same in every store, but
/amazon-seller-reviewreturns the feedback of the one marketplace you ask for.
What the coverage table does not tell you
- Whether an ASIN is listed on a marketplace: a covered request for an ASIN that is not there is a billed 404, like amazon.se in the run above.
- Whether a marketplace has data right now: deals accept all 23 marketplace IDs, but a deals page without deal data answers a retryable 5xx, which is billed.
- Whether an ASIN has history: on the 11 history marketplaces, statistics and estimates for an ASIN the recorded history does not know answer a billed 404.
- Next month's coverage: this is the state in October 2026. The coverage 400 names the supported domains, so log it when it appears instead of hiding it.
Frequently Asked Questions
Which Amazon marketplaces does the SellerMagnet API cover?
23 marketplaces. Product lookup, offers, search, bestsellers, deals and seller reviews accept all 23. Statistics, sales estimates and the ASIN converter cover 11: amazon.com, .ca, .com.mx, .com.br, .co.uk, .de, .fr, .it, .es, .in and .co.jp.
Why does the statistics endpoint return 400 for amazon.nl?
Statistics, sales estimates and the ASIN converter answer from recorded history, which covers 11 marketplaces. On amazon.nl and the other uncovered stores they answer HTTP 400 ('This endpoint is not available for the requested marketplace') before any credit is charged.
Is a 400 for an uncovered marketplace billed?
No. The coverage check runs before the credit deduction, like the checks for a missing or unknown marketplace ID, so all three of these 400s are free. A covered request is billed, even when it answers 404.
Can I get Amazon bestseller lists for amazon.ie?
Yes. The bestsellers endpoint accepts the amazon.ie marketplace ID, A28R8C7NBKEWEA, but checks the category ID against the amazon.co.uk category tree, so use UK category IDs. Statistics and sales estimates are not available for amazon.ie.
Does the marketplace list cost a credit?
Yes. The marketplaces endpoint takes no marketplace ID, returns all 23 marketplaces with domain, currency and default postcode, and costs one credit like every other call. Fetch it once and cache it.
Bottom line: six endpoints read Amazon's live pages and take all 23 marketplace IDs; statistics, sales estimates and the ASIN converter cover 11. Keep that split in your code, treat the coverage 400 as "not covered" rather than as an error, and remember that a covered request is billed even when the ASIN is missing. A free account comes with 150 credits after e-mail verification.