To use the SellerMagnet API as an Amazon Belgium product API, call it with marketplaceId=AMEN7PMS3EDWL, the same ID Amazon's Selling Partner API uses for Belgium: the request goes to amazon.com.be and prices come back in EUR. Offers, product lookup, search, deals, bestsellers and seller feedback all answer for amazon.com.be; price history, sales estimates and the ASIN converter return a free 400. Two details matter: Amazon's own offer carries the seller ID A3Q3FYJVX702M2, and bestseller categories come from amazon.com.be's own tree, whose names are in English.
Key Takeaways
- amazon.com.be is marketplace AMEN7PMS3EDWL and is priced in EUR.
- Six endpoints answer on amazon.com.be; statistics, estimated sales and the converter return a free 400 and no data.
- Amazon's own offer is
sellerId"Amazon" withamazonSellerIdA3Q3FYJVX702M2 on amazon.com.be. - Bestsellers accept an English category name or an ID from amazon.com.be's own tree; French or Dutch names and IDs from amazon.nl or amazon.fr get a free 400.
- A short name can land in an unexpected department ("headphones" is a car electronics node), so check the department before you pay for offers calls.
What is different about the Amazon Belgium 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 a few values, the endpoint coverage and the category tree. Prices come back as plain decimal numbers in EUR; the € symbol is for display only, and currency_code tells you the currency, the same as on amazon.nl, amazon.fr and amazon.de.
| Item | amazon.com.be |
|---|---|
| Marketplace ID | AMEN7PMS3EDWL |
| Store | amazon.com.be |
| Currency | EUR (Euro), symbol € |
| Default postcode | 1000 (Brussels), used when you send no geo_location |
| Amazon's own offer | sellerId "Amazon", amazonSellerId A3Q3FYJVX702M2 |
| Bestseller category tree | amazon.com.be's own, names in English, 26 top-level |
| History endpoints | free 400, no data |
The amazon.com.be entry of /amazon-get-marketplaces as sent (keyed by marketplace ID; the euro sign arrives JSON-escaped)
{
"AMEN7PMS3EDWL": {
"currency_code": "EUR",
"currency_name": "Euro",
"currency_symbol": "\u20ac",
"geo_location": "1000",
"marketplace_domain": "amazon.com.be",
"marketplace_name": "Amazon BE"
}
}
Amazon's own APIs answer different questions. The Selling Partner API is for sellers and the apps they authorise, and the Creators API, which replaces the deprecated Product Advertising API 5, is for affiliates: Amazon requires at least 10 qualifying sales within the past 30 days for access. To read any amazon.com.be listing, its offers and its bestsellers without a seller or affiliate account, the endpoints below need only an API key.
Endpoint coverage on amazon.com.be
Six of the ten endpoints only check that the marketplace ID is valid, so they answer on all 23 marketplaces, amazon.com.be included. The three history endpoints cover only 11 marketplaces and turn every other one away before the credit is taken: amazon.com.be gets a 400 with the message "This endpoint is not available for the requested marketplace" followed by the list of supported stores. That call costs nothing, but it returns no data either. Among the euro stores, amazon.de, amazon.fr, amazon.it and amazon.es have history; amazon.com.be, amazon.nl and amazon.ie do not.

Recognising Amazon's own offer on amazon.com.be
An offer from Amazon itself comes back with sellerId "Amazon" and, on amazon.com.be, amazonSellerId A3Q3FYJVX702M2. That ID belongs to this store only: Amazon's ID on amazon.nl is A17D2BRD4YMT0X, on amazon.fr A1X6FK5RDHNB96. Code that compares amazonSellerId with one hardcoded ID misses Amazon as soon as it reads another store, so test sellerId == "Amazon" and keep the ID for display or logging. The is Amazon selling on this listing guide covers the same check across stores.
Which category names work for amazon.com.be bestsellers?
category_id on the bestsellers endpoint takes either an ID or a category name, matched against amazon.com.be's own tree. That tree has 26 top-level categories and 18,691 nodes, and its names are in English ("Electronics & Photo", "Home & Kitchen"), not in French or Dutch. Amazon lists French as amazon.com.be's default language, with Dutch and English as the alternatives, and shows the Electronics department as "High-Tech": in the tree it is electronics ("Electronics & Photo"). So "mobile phones" resolves, while "koptelefoon" and "casque" find nothing. A name that fits several categories, such as "chargers", is turned away with the candidates so you can pick one. All three answers come before the credit is taken, so they are free.
The free 400 for category_id=chargers on amazon.com.be (keys as sent)
{
"candidates": [
{
"category_id": "27862700031",
"name": "Chargers",
"path": "Electronics & Photo > Mobile Phones & Communication > Accessories > Chargers"
},
{
"category_id": "27862904031",
"name": "Chargers",
"path": "Electronics & Photo > Radio Communication > Accessories > Chargers"
}
],
"error": "Bad request",
"message": "'chargers' matches 2 categories on amazon.com.be. Pass the category_id of the one you want.",
"success": false
}
A name that does resolve is not always the one you meant. The best match for "headphones" (tree as of November 2026) is a car electronics node under Automotive, because its own name is exactly "Headphones", while the department you probably want is called "Headphones, Earphones & Accessories" (27862506031). The answer's data.link names the department, so you can check it before you pay for more calls.

How do I read amazon.com.be bestsellers in Python?
The script below asks for the top five bestsellers of one amazon.com.be category by name, checks that the answer sits in the department you expect, then reads the live offers of each ASIN and prints the bestseller card price next to the featured offer's item price and shipping, in EUR. Before any call it rejects an empty category, an ID a spreadsheet turned into 2.78625E+10 and a count outside 1 to 50 (the API bills that count as a 400); it queries an ASIN that fills two cards only once 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.
be_bestsellers.py - amazon.com.be bestsellers by category name, with the featured offer
"""Amazon Belgium (amazon.com.be) bestsellers by category name: who holds the featured offer, in EUR.
amazon.com.be is marketplace AMEN7PMS3EDWL, priced in EUR. Three things this script relies on:
1. category_id takes an ID or a category NAME from amazon.com.be's own tree. That tree is in English and
its numeric IDs appear in no other store's tree. A short name can land in another department
("headphones" is a car electronics node), so the script checks the department in data.link before it
pays for any offers call.
2. Amazon's own offer comes back as sellerId "Amazon" with amazonSellerId A3Q3FYJVX702M2 on amazon.com.be.
3. amazon.com.be is not one of the 11 marketplaces with price history: statistics, estimated sales and the
ASIN converter answer it with a free 400. The script never sends those calls.
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
MARKET = "AMEN7PMS3EDWL" # amazon.com.be, prices in EUR
AMAZON_BE = "A3Q3FYJVX702M2" # Amazon's own seller ID on amazon.com.be (offers: amazonSellerId)
CATEGORY = "mobile phones" # an English name from amazon.com.be's tree, or an ID like "27862505031"
DEPARTMENT = "electronics" # top-level slug the category must sit under, "" to skip the check
TOP = 5 # bestseller cards to check; 1 to 50 (a bestseller page holds 50)
MAX_FAILED = 3 # 502/503 are billed on every attempt: stop after 3 calls that keep failing
class Stop(Exception):
"""401/403: the key or the credits are the problem, so every further call would fail the same way."""
def call(session, endpoint, **params):
try:
return get_with_retry(session, endpoint, **params)
except ApiError as err:
if err.status in (401, 403):
raise Stop(str(err)) from err
raise
def check_inputs(category, top):
"""Check before any call: a count outside 1 to 50 is a billed 400, and spreadsheet damage is no ID."""
category = " ".join(str(category).split())
if not category:
return None, "category_id is empty"
if re.fullmatch(r"\d+(\.\d+)?[eE]\+?\d+|\d+\.0+", category):
return None, f"category_id {category!r} looks like a number a spreadsheet reformatted"
if not isinstance(top, int) or not 1 <= top <= 50:
return None, f"TOP={top!r}: count must be a whole number from 1 to 50"
return category, ""
def department(link):
"""Top-level slug in data.link: .../gp/bestsellers/<slug>[/<id>]?pg=1."""
match = re.search(r"/gp/bestsellers/([^/?]+)", link or "")
return match.group(1).lower() if match else ""
def top_asins(cards, top):
"""Unique ASINs in rank order; cards without an ASIN are counted, not queried."""
seen, picked, no_asin = set(), [], 0
for card in cards:
asin = str(card.get("asin") or "").strip().upper()
if not re.fullmatch(r"[A-Z0-9]{10}", asin):
no_asin += 1
continue
if asin in seen: # the same product can fill two cards
continue
seen.add(asin)
price = (card.get("price") or {}).get("price")
picked.append((card.get("rank") or "-", asin, price if isinstance(price, (int, float)) else None))
return picked[:top], no_asin
def featured(data):
"""(item, shipping, holder, unique sellers, Amazon among the offers); item None when nothing is featured."""
box, offers = data.get("buyBox") or {}, data.get("offers") or []
sellers = len({o.get("sellerId") for o in offers if o.get("sellerId")}) # a seller can be listed twice
amazon_listed = any(o.get("sellerId") == "Amazon" for o in offers)
item = box.get("priceWithoutShipping") or 0.0
if data.get("buyBoxSuppressed") or item <= 0: # 0.0 = no readable price, never a real price
return None, None, "no featured offer", sellers, amazon_listed
if box.get("sellerId") == "Amazon": # the literal works on every marketplace
holder = f"Amazon {box.get('amazonSellerId') or '(no first-party ID)'}"
else:
holder = f"{box.get('fulfillmentType', '?')} seller {box.get('sellerId', '?')}"
return round(item, 2), round(box.get("shippingPrice") or 0.0, 2), holder, sellers, amazon_listed
def row(rank, asin, card="-", item="-", ship="-", sellers="-", note=""):
print(f"{rank!s:>4} {asin:<10} {card:>8} {item:>8} {ship:>6} {sellers:>7} {note}")
def main():
category, problem = check_inputs(CATEGORY, TOP)
if problem:
print(f"skipped before any call: {problem}")
return
session = new_session()
try:
data = call(session, "amazon-bestsellers", category_id=category, marketplaceId=MARKET, count=TOP)
except Stop as err:
print(f"stopped: {err}")
return
except ApiError as err:
billed = err.status != 400 or any(s in str(err) for s in ("Count Max", "must be"))
hint = "" if billed else " (free 400: pick the category's ID in the category explorer)"
print(f"bestsellers failed: {err}{hint}")
return
except (requests.ConnectionError, requests.Timeout) as err:
print(f"bestsellers failed: {type(err).__name__}")
return
found = department(data.get("link"))
print(f"category {category!r} on amazon.com.be -> {data.get('categoryId')} in department {found or '?'}")
if DEPARTMENT and found != DEPARTMENT:
print(f"not under {DEPARTMENT!r}: no offers calls made; pass the category's numeric ID instead")
return
asins, no_asin = top_asins(data.get("bestsellers") or [], TOP)
print(f"{len(asins)} ASINs to check, {no_asin} card(s) without an ASIN; price history on amazon.com.be: "
f"not available, not called")
print()
row("rank", "asin", "card", "item", "ship", "sellers", "featured offer (EUR)")
failed = amazon_holds = checked = 0
for rank, asin, card in asins:
if failed >= MAX_FAILED:
print(f"stopped after {MAX_FAILED} failed calls")
break
card_txt = f"{card:.2f}" if card is not None else "-"
try:
offers = call(session, "amazon-product-offers", asin=asin, marketplaceId=MARKET)
except Stop as err:
print(f"stopped: {err}")
break
except ApiError as err:
note = "not found on amazon.com.be (billed 404)" if err.status == 404 else f"error {err}"
row(rank, asin, card_txt, note=note)
failed += err.status >= 500
continue
except (requests.ConnectionError, requests.Timeout) as err:
row(rank, asin, card_txt, note=f"error {type(err).__name__}")
failed += 1
continue
checked += 1
item, ship, holder, sellers, amazon_listed = featured(offers)
if item is None:
row(rank, asin, card_txt, sellers=sellers, note=holder)
continue
amazon_holds += holder.startswith("Amazon ")
if not holder.startswith("Amazon ") and amazon_listed:
holder += ", Amazon also offers it"
row(rank, asin, card_txt, f"{item:.2f}", f"{ship:.2f}", sellers, holder)
print(f"\nAmazon holds the featured offer on {amazon_holds} of {checked} products read")
if __name__ == "__main__":
main()
Output of two runs (illustrative data: a retried 502, a card without an ASIN, a listing without offers)
# CATEGORY = 'headphones'
category 'headphones' on amazon.com.be -> 27862729031 in department automotive
not under 'electronics': no offers calls made; pass the category's numeric ID instead
# CATEGORY = 'mobile phones'
category 'mobile phones' on amazon.com.be -> 27862505031 in department electronics
4 ASINs to check, 1 card(s) without an ASIN; price history on amazon.com.be: not available, not called
rank asin card item ship sellers featured offer (EUR)
1 B0BEPHONE1 189.00 189.00 0.00 2 Amazon A3Q3FYJVX702M2
2 B0BEPHONE2 229.90 224.90 0.00 2 FBA seller A2BESELLER02, Amazon also offers it
4 B0BEPHONE4 149.00 - - 0 no featured offer
5 B0BEPHONE5 319.00 309.00 4.99 1 FBM seller A3BESELLER03
Amazon holds the featured offer on 1 of 4 products read

- The first run asked for "headphones", got the car electronics node and stopped after the bestsellers call: 1 credit instead of 1 plus one per ASIN.
- Amazon A3Q3FYJVX702M2 in the last column means the featured offer has
sellerId"Amazon" and carries Amazon's own amazon.com.be ID. - Amazon also offers it marks a product where a third-party seller holds the featured offer while Amazon has an offer in the list too.
- card is the price on the bestseller page and item the featured offer's price without shipping. They can differ (ranks 2 and 5), because the card is not taken from the featured offer, so compare the item column when you track prices.
- sellers counts distinct seller IDs: the offers list can show the same seller twice (different delivery date or condition), so
len(offers)overcounts. no featured offer with 0 sellers is a listing without offers on that page, not an error; rank 3 is missing because its card carried no ASIN.
amazon.com.be IDs are not amazon.nl or amazon.fr IDs
Belgium shares the euro with its neighbours, but not their category IDs. The top level uses the same kind of slugs (electronics, kitchen, toys), while the numeric IDs below them are amazon.com.be's own: none of the 18,665 numeric nodes appears in the amazon.nl, amazon.fr, amazon.de or amazon.co.uk tree. An ID copied from one of those stores gets "Invalid CategoryId", a free 400. Eleven top-level categories, among them kitchen, toys and pets, have no sub-nodes in the tree, so there you can only ask for the whole department. Take IDs from the category explorer with Belgium selected; the Netherlands guide shows the same rule for amazon.nl.
Credit cost of an amazon.com.be check
1 credit per request, as on every store. The script costs 1 credit for the bestsellers call plus 1 credit per ASIN for its offers, plus each billed retry: a 502 or 503 is charged on every attempt, a 500 without Retry-After is refunded. A 404 for an ASIN is billed, and so is a 400 for a count above 50; an invalid marketplace ID, a category name or ID the tree does not know and the history endpoints' amazon.com.be 400 are free. The example made 7 calls: 1 for the "headphones" run, then 1 for the bestsellers, 4 for the four ASINs and 1 retried 502. For every store at once, see API marketplace coverage.
Frequently Asked Questions
What is the Amazon Belgium marketplace ID?
AMEN7PMS3EDWL. Pass it as marketplaceId and the request goes to amazon.com.be, with prices in EUR. A country code like "BE" or a domain like "amazon.com.be" is rejected with a free 400 Invalid marketplaceId.
How do I recognise Amazon's own offer on amazon.com.be?
The offer has sellerId "Amazon" and amazonSellerId A3Q3FYJVX702M2, Amazon's own seller ID for amazon.com.be. Test sellerId, which works on every marketplace; amazonSellerId differs per store.
Can I get Amazon Belgium price history?
Not from this API. Statistics, estimated sales and the ASIN converter cover 11 marketplaces and answer amazon.com.be with a free 400 and no data. Store your own offers snapshots if you need a history.
Can I pass a category name in French or Dutch?
No. The amazon.com.be category tree is in English, so "koptelefoon" or "casque" finds nothing and returns a free 400. Use the English name or the numeric ID from the category explorer.
Do amazon.nl or amazon.fr category IDs work on amazon.com.be?
No. amazon.com.be has its own tree, and none of its numeric IDs appears in the amazon.nl, amazon.fr, amazon.de or amazon.co.uk tree. A foreign ID gets a free 400 Invalid CategoryId.
Bottom line: use AMEN7PMS3EDWL for amazon.com.be, expect EUR, recognise Amazon by sellerId, name categories in English or take their IDs from amazon.com.be's own tree, check the department before you pay for offers, and keep history calls for the 11 covered stores. The bestsellers endpoint page lists every field, and a free account includes 150 credits.