To convert an ISBN to an Amazon ASIN, call the SellerMagnet /api/amazon-asin-converter endpoint with conversion_direction=ean-to-asin and the ISBN-13 as the asin parameter. An ISBN-10 must be converted to its ISBN-13 form first (prefix 978, recompute the check digit): in this direction the converter sends the value to Keepa as a barcode exactly as given, and a bare 10-digit ISBN-10 is not a valid EAN-13 barcode, so it will not match. The call costs one credit and returns the ASIN, the book's title and its other recorded barcodes.
Key Takeaways
- An ISBN-13 is an EAN-13 (prefix 978 or 979) and converts exactly like any other barcode.
- An ISBN-10 must be converted to ISBN-13 first - a bare 10-digit code is not a valid EAN-13 barcode and will not match.
- Validate the check digit locally: a malformed code still costs a credit once sent.
- Only the first matching listing is returned, so a book with several editions may have more ASINs.
- The converter covers 11 marketplaces; any other marketplaceId is a free 400, not a silent fallback.
Why can't I send an ISBN-10 straight to the converter?
On conversion_direction=ean-to-asin, the endpoint sends whatever value you pass straight to Keepa as a barcode lookup, with no digit-count branching at all. ISBN-13 and EAN-13 are the same 13-digit number space (books use the 978/979 EAN prefix), so an ISBN-13 matches the barcode Amazon has on file for that edition. A bare ISBN-10 is a different, 10-digit number; it is not the EAN-13 code stored against the listing, so the lookup simply does not find it. Converting to ISBN-13 first turns the ISBN-10 into the same barcode format the converter actually matches on.
| Scenario | Result | Billed? | Notes |
|---|---|---|---|
| Valid ISBN-13, book exists | 200 | Billed | 1 credit, normal response |
| Valid ISBN-10, book exists | 200 | Billed | converted to ISBN-13 locally first, same 1 credit |
| ISBN not on Amazon | 404 Product not found | Billed | not retried |
| Malformed code (bad check digit / wrong length) | caught locally | Free | no call made at all |
| marketplaceId outside the 11 Keepa domains | 400 gate | Free | not retried (keepa_marketplaces_only) |
| Keepa upstream 502/503 | 502/503 | Billed per attempt | retried up to 4x with backoff |
How do I normalise and check an ISBN before calling the API?
The function below strips dashes and spaces, checks the ISBN-10 mod-11 digit or the ISBN-13/EAN mod-10 digit, converts ISBN-10 to ISBN-13 when needed, and only then calls the converter through get_with_retry. get_with_retry and new_session() come from the Python quickstart; a malformed ISBN raises before any request leaves your machine, so a typo never costs a credit.
isbn_to_asin.py - normalise, check, then convert
import re
from retry import get_with_retry
from sellermagnet import ApiError, new_session
MARKETPLACE = "ATVPDKIKX0DER" # amazon.com
def _digits(raw: str) -> str:
return re.sub(r"[^0-9Xx]", "", raw) # drop dashes/spaces; ISBN-10 check digit can be "X"
def _isbn10_to_isbn13(isbn10: str) -> str:
"""Drop the ISBN-10 check digit, prefix 978 and recompute the EAN-13 check digit."""
body = "978" + isbn10[:-1]
total = sum(int(d) * (3 if i % 2 else 1) for i, d in enumerate(body))
check = (10 - total % 10) % 10
return body + str(check)
def _isbn10_ok(isbn10: str) -> bool:
if len(isbn10) != 10 or not isbn10[:9].isdigit():
return False
total = sum(int(d) * w for d, w in zip(isbn10[:9], range(10, 1, -1)))
last = isbn10[9].upper()
total += 10 if last == "X" else (int(last) if last.isdigit() else -1)
return total % 11 == 0
def _isbn13_ok(isbn13: str) -> bool:
if len(isbn13) != 13 or not isbn13.isdigit() or isbn13[:3] not in ("978", "979"):
return False
total = sum(int(d) * (3 if i % 2 else 1) for i, d in enumerate(isbn13[:-1]))
return (10 - total % 10) % 10 == int(isbn13[-1])
def normalise_isbn(raw: str) -> str:
"""Accept an ISBN-10 or ISBN-13 with or without dashes/spaces; return a checked ISBN-13.
Raises ValueError before a credit is spent, instead of paying for a call that will 400."""
code = _digits(raw)
if len(code) == 13:
if not _isbn13_ok(code):
raise ValueError(f"{raw!r}: bad ISBN-13 check digit")
return code
if len(code) == 10:
if not _isbn10_ok(code):
raise ValueError(f"{raw!r}: bad ISBN-10 check digit")
return _isbn10_to_isbn13(code)
raise ValueError(f"{raw!r}: not a 10 or 13 digit ISBN")
def isbn_to_asin(session, raw_isbn: str, marketplace_id: str = MARKETPLACE) -> dict:
isbn13 = normalise_isbn(raw_isbn)
data = get_with_retry(session, "amazon-asin-converter", asin=isbn13,
marketplaceId=marketplace_id, conversion_direction="ean-to-asin")
return {"isbn13": isbn13, "asin": data["asin"], "title": data["productTitle"]}
if __name__ == "__main__":
session = new_session()
for raw in ["978-0-306-40615-7", "0-306-40615-2", "9780000000002", "123", "978-0-306-40615-9"]:
try:
print(raw, "->", isbn_to_asin(session, raw))
except (ValueError, ApiError) as exc:
print(raw, "failed:", exc)
Example output (illustrative ISBN; retry and gate scenarios)
isbn_to_asin: main scenarios, calls= {'amazon-asin-converter': 3}
978-0-306-40615-7 -> {'isbn13': '9780306406157', 'asin': 'B000OZ0NAI', 'title': 'The C Programming Language'}
0-306-40615-2 -> {'isbn13': '9780306406157', 'asin': 'B000OZ0NAI', 'title': 'The C Programming Language'}
9780000000002 failed: 404: Product not found
123 failed: '123': not a 10 or 13 digit ISBN
978-0-306-40615-9 failed: '978-0-306-40615-9': bad ISBN-13 check digit
gate scenario (free 400, not retried): calls= 1 result: ApiError: 400: This endpoint is not available for the requested marketplace
retry scenario (502 then OK): calls= 2 result: {'isbn13': '9780306406157', 'asin': 'B000OZ0NAI', 'title': 'The C Programming Language'}
Trimmed converter response (example values)
{
"success": true,
"data": {
"asin": "B000OZ0NAI",
"productTitle": "The C Programming Language",
"eanList": ["9780306406157"],
"listedSince": "2011-01-01 00:00:00"
}
}

Which marketplaces does the ISBN converter cover?
The converter shares its marketplace gate with /amazon-product-statistics and the sales estimator: only the 11 Keepa-backed domains. Since 2026-09-19 any other marketplaceId - including Ireland - gets a free 400 before a credit is deducted, instead of silently falling back to amazon.com. For barcodes that are not book identifiers, see the UPC and EAN to ASIN guide; the ASIN converter page lists every supported conversion direction, and more runnable snippets are on the code examples page.

Frequently Asked Questions
Does the API have a dedicated ISBN parameter?
No. /amazon-asin-converter takes the code in a parameter named asin regardless of direction; an ISBN-13 (or a converted ISBN-10) goes in that same field with conversion_direction=ean-to-asin.
Can I send an ISBN-10 directly?
Convert it to ISBN-13 first (prefix 978, recompute the check digit). In ean-to-asin mode the converter sends the value to Keepa as a barcode exactly as given, and a 10-digit ISBN-10 is not a valid EAN-13 barcode, so it will not match the book's listing.
What if the ISBN maps to more than one Amazon listing?
Only the first match the converter finds is returned; a book re-released under several formats can have more than one ASIN, and this endpoint won't list every one of them.
Is a failed lookup refunded?
No. An unknown ISBN is a billed 404, same as an unknown barcode; only your own code catches a malformed ISBN for free, before any request is sent.
Does this work for every Amazon marketplace?
Only the 11 Keepa-backed domains (.com, .co.uk, .de, .fr, .co.jp, .ca, .it, .es, .in, .com.mx, .com.br); any other marketplaceId is a free 400, not a silent fallback to amazon.com.
Bottom line: convert an ISBN-10 to ISBN-13 and check its digit locally, then send it to the same converter endpoint used for UPC and EAN barcodes with conversion_direction=ean-to-asin.