Home / Blog / Amazon Best Sellers Rank by Category via API: Current Rank and Category Lists

Amazon Best Sellers Rank by Category via API: Current Rank and Category Lists

Three different places a Best Sellers Rank can come from via API - a free field inside a product lookup, a dedicated category list, and salesRank history - and which one answers which question.

October 20, 2026
3 min read
SellerMagnet Team
Share & Bookmark
Terminal window showing a Python function that reads a product's current Best Sellers Rank

To get Amazon's Best Sellers Rank by category via API, read bestsellerRanks straight off a /amazon-product-lookup call for a single product's current rank at no extra credit, call /amazon-bestsellers with a category_id for the ranked list itself, or /amazon-product-statistics for root-category rank history over time. Each answers a different question, and mixing them up wastes credits on the wrong endpoint.

Key Takeaways

  • A product's current main/subcategory rank is already inside /amazon-product-lookup - no extra call needed.
  • /amazon-bestsellers returns the ranked list for one category_id, up to 50 products per page, 1 credit per page.
  • /amazon-product-statistics salesRankHistory tracks the root category's rank over time, not the live list.
  • An unknown category_id is a billed 400 ('Invalid CategoryId') - validate against the category tree JSON first.
  • count above 50 on /amazon-bestsellers is also a billed 400; cap it client-side.

Where does each rank number come from?

Three endpoints, three different rank answers (October 2026).
EndpointFieldWhat it gives you
/amazon-product-lookupbestsellerRanks.main_categorycurrent rank, no extra credit
/amazon-product-lookupbestsellerRanks.subcategorycurrent rank, no extra credit
/amazon-bestsellersbestsellers[].ranklist position for a category_id, 1 credit per page
/amazon-product-statisticssalesRank / salesRankHistoryroot-category rank over time

How do I check a product's current BSR, and pull a category's bestseller list?

current_rank reads the free field from a lookup you likely already call. category_page validates count client-side before it can turn into a billed 400, and still lets a genuinely invalid category_id raise its billed error rather than hiding it; its count=50 default is this helper's own choice, not the API's - /amazon-bestsellers itself defaults to 30 when count is omitted. get() and new_session() come from the Python quickstart; category IDs come from Amazon's own Best Sellers URLs, as in the category ID guide.

bsr_category.py - current rank and a category list

from sellermagnet import get, new_session


def current_rank(session, asin: str, marketplace_id: str) -> dict:
    """Current BSR straight from a lookup: main category and subcategory rank,
    no extra credit over the lookup you already pay for. Either rank can be
    missing when the product carries no bestseller rank on that marketplace."""
    p = get(session, "amazon-product-lookup", asin=asin, marketplaceId=marketplace_id)["productInfo"]
    ranks = p.get("bestsellerRanks") or {}
    main = ranks.get("main_category") or {}
    sub = ranks.get("subcategory") or {}
    return {
        "asin": p["asin"],
        "main_category": main.get("name"), "main_rank": main.get("rank"),
        "subcategory": sub.get("name"), "sub_rank": sub.get("rank"),
    }


def category_page(session, category_id: str, marketplace_id: str, count: int = 50) -> list[dict]:
    """One /amazon-bestsellers page (max 50 - a higher count is a billed 400,
    so validate client-side). An unknown category_id is also billed (400
    'Invalid CategoryId'), so check it against the category tree first in a
    real integration."""
    if not 1 <= count <= 50:
        raise ValueError("count must be 1-50 (50+ is a billed 400 on the API)")
    data = get(session, "amazon-bestsellers", category_id=category_id, marketplaceId=marketplace_id, count=count)
    return [{"rank": b.get("rank"), "asin": b.get("asin"), "title": b.get("productTitle")}
            for b in data["bestsellers"]]


if __name__ == "__main__":
    session = new_session()
    print(current_rank(session, "B0CL61F39H", "ATVPDKIKX0DER"))
    print(current_rank(session, "B0NORANK", "ATVPDKIKX0DER"))
    print(category_page(session, "281407", "ATVPDKIKX0DER", count=5)[:3])

Example output (illustrative ASIN and category)

{'asin': 'B0CL61F39H', 'main_category': 'Video Games', 'main_rank': 31, 'subcategory': 'PlayStation', 'sub_rank': 1}
{'asin': 'B0NORANK', 'main_category': None, 'main_rank': None, 'subcategory': None, 'sub_rank': None}
[{'rank': 1, 'asin': 'B000000001', 'title': 'Item 1'}, {'rank': 2, 'asin': 'B000000002', 'title': 'Item 2'}, {'rank': 3, 'asin': 'B000000003', 'title': 'Item 3'}]

Trimmed bestsellerRanks (example values)

{
  "productInfo": {
    "bestsellerRanks": {
      "main_category": {"name": "Video Games", "rank": 31},
      "subcategory": {"name": "PlayStation", "rank": 1}
    }
  }
}
Blueprint table comparing the three bestseller rank endpoints
Pick the endpoint by the question, not by habit.

Why does my category's rank list not match the live Amazon page?

Bestseller lists update on Amazon's own schedule, not on your polling interval, so a page fetched minutes apart can show small rank shuffles even for a near-static category. Treat the list as a snapshot and compare successive snapshots rather than expecting it to match a page you refresh in a browser at the same instant. The Movers and Shakers guide covers tracking rank gains across snapshots.

Blueprint decision table for which bestseller rank endpoint to call
Pick by the question you are answering, not by which call you already have open.

Frequently Asked Questions

Which number should I use: lookup rank, bestsellers rank or statistics salesRank?

Lookup gives the current main/subcategory rank for free with any product call; bestsellers gives list position for a specific category_id; statistics gives root-category history over time.

Does checking the BSR cost extra credits?

Reading bestsellerRanks from a lookup costs nothing extra since it is already in that response; calling /amazon-bestsellers separately is its own 1-credit-per-page call.

What happens if I send an unknown category_id?

The API returns a billed 400 'Invalid CategoryId' raised inside the view, so validate the ID against the category tree JSON first to avoid paying for a bad call.

Can count be higher than 50 on /amazon-bestsellers?

No, count above 50 is a billed 400 ('Count Max: 50'); cap it client-side before the request.

Why does a product have no bestsellerRanks at all?

Some listings carry no rank on a given marketplace; both main_category and subcategory are then absent from the response, not zero.

Bottom line: use the lookup's free rank field for a single product, the bestsellers endpoint for a category list, and statistics history for a trend - and validate category_id and count before paying for a mistake.

Ready to Extract Amazon Data at Scale?

Start building with SellerMagnet API today. Real-time product data, competitive pricing, and review analytics at your fingertips.

150 free API credits • No credit card required • Cancel anytime