To get Amazon Mexico product data, call the SellerMagnet API with marketplaceId=A1AM78C64UM0Y8: the request goes to amazon.com.mx and prices come back in Mexican pesos (currency code MXN). The currency symbol is a plain "$", the same as on amazon.com, so read the code, never the symbol. amazon.com.mx is one of 11 marketplaces with price history, so one script can put today's featured offer next to its 30-day Buy Box low.
Key Takeaways
- amazon.com.mx is marketplace A1AM78C64UM0Y8 and is priced in MXN, but its currencySymbol is "$": check currencyCode before you treat a price as pesos.
- All ten endpoints answer on amazon.com.mx, including price history, estimated sales and the ASIN/EAN converter.
- Statistics prices are whole centavos (114900 = 1,149.00 MXN); offers and lookup prices are decimal pesos.
- Amazon sells on amazon.com.mx as seller AVDBXBAVVSXLQ: in amazonSellerId on the offers endpoint and directly in the Buy Box holder history.
- Bestseller category IDs come from amazon.com.mx's own Spanish-language tree, which shares no numeric ID with amazon.com.
What is different about the Amazon Mexico product API?
The request format is the same as for every other store: GET, query parameters, the key in the X-Api-Key header. What changes are the values: the store, the currency, the default delivery postcode and Amazon's own seller ID. The trap is the currency symbol. amazon.com.mx and amazon.com both answer with "$", so a script that labels prices by symbol mixes pesos and dollars without an error. Marketplace data cached before 18 September 2026 listed USD for Mexico; refresh it.
| Item | amazon.com.mx |
|---|---|
| Marketplace ID | A1AM78C64UM0Y8 |
| Store | amazon.com.mx |
| Currency | MXN (currencySymbol "$", the same symbol as amazon.com) |
| Default postcode | 06000 |
| Number format | same as amazon.com: comma thousands, dot decimal |
| Amazon's own seller ID | AVDBXBAVVSXLQ |
| Offer condition values | English ("New", "Used - Like New") |
| Bestseller category tree | amazon.com.mx's own, Spanish names |
| History endpoints | full coverage, no free 400 |
The amazon.com.mx entry of /amazon-get-marketplaces (data is keyed by marketplace ID)
{
"A1AM78C64UM0Y8": {
"marketplace_domain": "amazon.com.mx",
"marketplace_name": "Amazon MX",
"currency_code": "MXN",
"currency_name": "Mexican Peso",
"currency_symbol": "$",
"geo_location": "06000"
}
}
Endpoint coverage on amazon.com.mx
All ten. Six endpoints only check that the marketplace ID is valid and answer on every store. The three history endpoints (statistics, estimated sales and the ASIN/EAN converter) cover 11 marketplaces, and amazon.com.mx is one of them, together with amazon.com, amazon.ca and amazon.com.br in the Americas. Stores outside that list get a free 400 "This endpoint is not available for the requested marketplace" on those three; amazon.com.mx never does. Search runs on amazon.com.mx's own results page (page one), so pass keywords the way shoppers type them there, in Spanish. The full matrix is in API marketplace coverage.

How do I compare the live price with the 30-day low in Python?
The script below makes two calls per ASIN on amazon.com.mx: /amazon-product-statistics for the Buy Box price history and the holder history, and /amazon-product-offers for the featured offer right now. Both prices are landed prices (item plus shipping), so they compare like for like once the centavos are divided by 100. The price in force when the 30-day window opens counts too, unless the holder history shows that nobody held the Buy Box at that moment. The script skips duplicates and anything that is not a 10-character ASIN before paying, refuses an offer whose currency code is not MXN, and stops the whole run on a 401/403. It uses sellermagnet.py (ApiError, new_session) and retry.py (get_with_retry) from the Python quickstart.
mexico_buybox.py: live featured offer vs 30-day Buy Box low on amazon.com.mx
"""Amazon Mexico (amazon.com.mx): the live featured offer next to its 30-day Buy Box low, in pesos.
Behaviour this relies on (checked 2026-11-01):
- marketplaceId A1AM78C64UM0Y8 = amazon.com.mx, priced in MXN. The response's currency symbol is "$", the same
as on amazon.com, so the script checks the currency CODE, never the symbol.
- amazon.com.mx is one of the 11 marketplaces with price history: /amazon-product-statistics answers it.
- Statistics prices are integer centavos (114900 = 1,149.00 MXN); offers prices are decimal pesos.
- Both prices compared here are landed (item + shipping): buyBoxPriceHistory and buyBox.totalPrice.
- Amazon itself is sellerId "Amazon" on the offers endpoint (its MX seller ID sits in amazonSellerId) and
AVDBXBAVVSXLQ in buyBoxSellerIdHistory, where "-1" means nobody held the Buy Box.
Helpers: sellermagnet.py and retry.py from https://sellermagnet-api.com/blog/amazon-product-api-python
"""
import re
from datetime import datetime, timedelta, timezone
import requests
from retry import get_with_retry
from sellermagnet import ApiError, new_session
MX = "A1AM78C64UM0Y8"
AMAZON_MX = "AVDBXBAVVSXLQ" # Amazon's own seller ID on amazon.com.mx
WINDOW_DAYS = 30
MAX_FAILED = 3 # 502/503 are billed on every attempt: stop after 3 calls that keep failing
ASINS = ["B0CL61F39H", " b0mxonly01 ", "B0NOOFFER1", "B0CL61F39H", "4.00638E+12", "B0NEWLIST1"]
HOLDERS = {AMAZON_MX: "Amazon", "-1": "nobody", "-2": "new seller"}
def window_low(stats, start):
"""Lowest landed Buy Box price (pesos) in force since `start`, or None.
The history holds one point per change, so the price in force when the window opens is the last point
before it, unless the holder history says nobody held the Buy Box at that moment ("-1"): then no old
price is carried into the window."""
series = (stats.get("stats") or {}).get("buyBoxPriceHistory") or []
inside = [cents for day, cents in series if day >= start]
before = [cents for day, cents in series if day < start]
history = stats.get("buyBoxSellerIdHistory") or []
holders = [h for ts, h in history if ts[:10] < start]
if before and not (holders and holders[-1] == "-1"):
inside.append(before[-1])
return min(inside) / 100 if inside else None
def history_holder(stats):
holders = stats.get("buyBoxSellerIdHistory") or []
return HOLDERS.get(holders[-1][1], holders[-1][1]) if holders else "no history"
def live_offer(offers):
"""(landed price in pesos or None, holder text, unique sellers) from one offers answer."""
box = offers.get("buyBox") or {}
sellers = len({o["sellerId"] for o in offers.get("offers") or [] if o.get("sellerId")})
if offers.get("buyBoxSuppressed") or not box.get("totalPrice"):
return None, "no featured offer", sellers
code = (offers.get("currency") or {}).get("code")
if code != "MXN": # "$" alone would also match amazon.com
return None, f"currency {code}, not MXN", sellers
if box.get("sellerId") == "Amazon":
holder = f"Amazon ({box.get('amazonSellerId')})"
else:
holder = f"{box.get('fulfillmentType', '?')} {box.get('sellerId', '?')}"
return round(box["totalPrice"], 2), holder, sellers # buyBox.totalPrice is not rounded by the API
def verdict(price, low, tracked_since, start):
if price is None or low is None:
return "-"
short = " (tracked < 30 d)" if tracked_since not in (None, "N/A") and tracked_since > start else ""
if price <= low + 0.005:
return "at 30-day low" + short
return f"+{(price - low) / low * 100:.0f}% over low" + short
def fetch(session, endpoint, asin):
"""(data, error text, counts as failed). 401/403 propagate: a dead key must stop the whole run."""
try:
return get_with_retry(session, endpoint, asin=asin, marketplaceId=MX), None, False
except ApiError as err:
if err.status in (401, 403):
raise
if err.status == 404: # billed, and not the same as "no price": the ASIN is unknown here
return None, f"{endpoint.rsplit('-', 1)[1]}: not found (billed 404)", False
return None, f"{endpoint.rsplit('-', 1)[1]}: error {err}", err.status >= 500
except (requests.ConnectionError, requests.Timeout) as err:
return None, f"{endpoint.rsplit('-', 1)[1]}: {type(err).__name__}", True
def money(value):
return f"{value:.2f}" if value is not None else "-"
def main():
session = new_session()
start = (datetime.now(timezone.utc).date() - timedelta(days=WINDOW_DAYS)).isoformat()
seen, failed = set(), 0
print(f"{'asin':<11} {'live MXN':>9} {'30d low':>9} {'live holder':<24} {'history':<13} {'sellers':>7} note")
for raw in ASINS:
asin = raw.strip().upper()
if not re.fullmatch(r"[A-Z0-9]{10}", asin) or asin in seen:
why = "duplicate, already checked" if asin in seen else "not an ASIN, skipped before paying"
print(f"{raw.strip():<11} {'-':>9} {'-':>9} {'-':<24} {'-':<13} {'-':>7} {why}")
continue
seen.add(asin)
if failed >= MAX_FAILED:
print(f"stopped after {MAX_FAILED} failed calls")
return
try:
stats, stats_err, stats_failed = fetch(session, "amazon-product-statistics", asin)
offers, offers_err, offers_failed = fetch(session, "amazon-product-offers", asin)
except ApiError as err:
print(f"stopped: {err}")
return
failed += stats_failed + offers_failed
low = window_low(stats, start) if stats else None
price, holder, sellers = live_offer(offers) if offers else (None, "-", "-")
errors = [e for e in (stats_err, offers_err) if e]
if errors:
note = "; ".join(errors)
elif low is None:
note = "no Buy Box price in 30 days"
else:
note = verdict(price, low, stats.get("trackingSince"), start)
print(f"{asin:<11} {money(price):>9} {money(low):>9} {holder:<24} "
f"{history_holder(stats) if stats else '-':<13} {sellers:>7} {note}")
if __name__ == "__main__":
main()
Output (illustrative data: a billed 404, a retried 502, a duplicate and a skipped input)
asin live MXN 30d low live holder history sellers note
B0CL61F39H 1249.00 1149.00 Amazon (AVDBXBAVVSXLQ) Amazon 3 +9% over low
B0MXONLY01 349.00 - FBM A1MXSELLER05 - 1 statistics: not found (billed 404)
B0NOOFFER1 - - no featured offer nobody 0 no Buy Box price in 30 days
B0CL61F39H - - - - - duplicate, already checked
4.00638E+12 - - - - - not an ASIN, skipped before paying
B0NEWLIST1 799.00 799.00 FBA A1MXSELLER02 A1MXSELLER02 2 at 30-day low (tracked < 30 d)
- B0CL61F39H is held by Amazon at 1,249.00 MXN, 9% over the 30-day low of 1,149.00; the history column already names Amazon because AVDBXBAVVSXLQ is mapped to it.
- B0MXONLY01 has live offers but no recorded history yet: statistics answers a billed 404, which the script reports instead of reading it as "no price".
- B0NOOFFER1 got a 502 first (billed, retried) and then an empty offer listing; its last recorded price is older than the window and nobody held the Buy Box after it, so no old price is carried in.
- B0NEWLIST1 sits at its low, but tracking began 12 days ago, so the line says the window is shorter than 30 days.
- A1MXSELLER01 is listed twice on the first ASIN (two delivery dates), and
sellersstill counts 3 distinct sellers.

Amazon's own seller ID on amazon.com.mx
AVDBXBAVVSXLQ. The two endpoints show it in different places. On /amazon-product-offers Amazon's own offer has "sellerId": "Amazon" and AVDBXBAVVSXLQ in amazonSellerId. In the buyBoxSellerIdHistory of /amazon-product-statistics the holder is AVDBXBAVVSXLQ itself, with "-1" for times when nobody held the Buy Box and "-2" for a new seller the history cannot name yet. Map AVDBXBAVVSXLQ to Amazon before you join the two, and never treat "-2" as "no holder". The Buy Box history guide covers the holder history in depth.
Bestseller category IDs on amazon.com.mx
/amazon-bestsellers checks category_id against amazon.com.mx's own tree. It has 21,402 categories under 38 top-level entries, named in Spanish ("Electrónicos", "Hogar y cocina"). Top-level IDs are slugs such as electronics; deeper ones are numeric, for example 9687422011 for Electrónicos > Celulares y Accesorios. The tree shares no numeric ID with amazon.com, so a numeric US category ID on amazon.com.mx is a billed 400 "Invalid CategoryId". Look IDs up in the category explorer or follow the category ID guide.
What does an amazon.com.mx check cost?
1 credit per request, as on every store. The script costs 2 credits per ASIN (statistics and offers), plus each billed retry: a 404 is charged once (it is not retried), a 502 or 503 on every attempt, a 500 without Retry-After is refunded, and a free 400 costs nothing. The example run made 9 calls for 4 unique ASINs, 9 credits: 4 statistics calls (one a billed 404) and 5 offers calls (one retried 502). The duplicate and the malformed input cost nothing because they never left the script. What the data cannot show: the history depends on how often the product was checked, so a short dip between two checks can be missing; the live offer is one reading at the default postcode 06000; and coupons are not visible. The statistics endpoint page lists every history field.
Frequently Asked Questions
What is the Amazon Mexico marketplace ID?
A1AM78C64UM0Y8. Pass it as marketplaceId and the request goes to amazon.com.mx, with prices in MXN. A country code like "MX" or a domain like "amazon.com.mx" gets a free 400 "Invalid marketplaceId" instead.
Does the Amazon Mexico API return price history?
Yes. amazon.com.mx is one of the 11 marketplaces with price and rank history, estimated sales and the ASIN/EAN converter, so /amazon-product-statistics answers it with data, not with the free 400 that uncovered stores get.
Is a "$" price on amazon.com.mx in US dollars?
No. The currency symbol is "$" on both amazon.com and amazon.com.mx, but the currency code is MXN on amazon.com.mx. Read currencyCode or currency.code before you compare or add up prices from both stores.
What seller ID does Amazon itself use on amazon.com.mx?
AVDBXBAVVSXLQ. The offers endpoint shows Amazon as sellerId "Amazon" with AVDBXBAVVSXLQ in amazonSellerId, and the Buy Box holder history in /amazon-product-statistics lists AVDBXBAVVSXLQ directly.
Why is the statistics price 100 times the offers price?
Statistics returns prices as whole centavos (114900 = 1,149.00 MXN), while offers and lookup return decimal pesos (1149.0). Divide statistics prices by 100 before comparing them with a live price.
Bottom line: use A1AM78C64UM0Y8 for amazon.com.mx, trust currencyCode (MXN) over the "$" symbol, divide statistics prices by 100, and map AVDBXBAVVSXLQ to Amazon. Every endpoint, price history included, answers without a gap to code around. A free account includes 150 credits, enough to run this script on about 75 ASINs when nothing needs a retry.