How-tos

UPC vs EAN vs GTIN vs ASIN: a 2026 product-identifier guide for sellers and developers

Every product identifier you'll encounter as a seller or developer, what it means, when it's interchangeable with another, and the bugs that hit when you treat them all the same.

By Matt Hall··6 min read

If you sell on Walmart, Amazon, eBay, or any of the major retailers in 2026, you've already run into the identifier mess. A product comes in as a "UPC" but is 13 digits long. An ASIN is supposed to be 10 characters but yours has 11. A GTIN-14 has a leading zero that turns it into a UPC-12 with one strip. A 12-digit string could be a UPC, a Walmart item_id, or an absurd phone number with no dashes. None of these are accidents. Each came from a different industry at a different time, and the standards committees never bothered to align them.

This post is the cheat sheet I wish I'd had when I started building product-data tools.

The 7 identifiers you'll meet

NameLengthFormatUsed byNotes
UPC-A12 digitsAll numericNorth American retail (Walmart, Target, Best Buy, etc.)The "barcode" most consumers know
UPC-E6 digitsAll numericSmall packagingCompressed UPC-A; expand by adding implicit zeros
EAN-1313 digitsAll numericEuropean retail, also globally as a UPC supersetFirst 1-3 digits = country prefix
EAN-88 digitsAll numericTiny packaging where EAN-13 won't fitRarely seen on consumer goods
ISBN-1010 chars9 digits + check digit (or 'X')Books pre-2007Last char can be 'X' for the check digit
ISBN-1313 digitsAll numeric, prefix 978 or 979Books post-2007Encodable as EAN-13
GTIN-1414 digitsAll numericBulk packaging, B2BOutermost case-pack identifier; strip leading zero to recover UPC-A or EAN-13
ASIN10 charsAlphanumeric (B0xxxxxxxx for modern goods)Amazon-onlyAmazon's internal ID; not a real GTIN
walmart_item_id6-12 digitsAll numericWalmart-onlyWalmart's internal ID; not a GTIN

The interchangeability rules

These rules are the bug source for 90% of product-identifier code:

Rule 1: A UPC-A is also an EAN-13 with a leading zero. 012345678905 (UPC-A) and 0012345678905 (EAN-13) refer to the same product. Most retailers store UPCs as 12-digit and EANs as 13-digit, but Walmart's catalog mixes them.

Rule 2: An ISBN-13 is also an EAN-13. Books got their own GTIN allocation under the 978 and 979 country prefixes. So 9780553213119 is both a valid ISBN-13 (Pride and Prejudice) and a valid EAN-13.

Rule 3: A GTIN-14 with a leading zero is a packed EAN-13 or UPC-A. Strip the leading zero. If the result is 13 digits and starts with 978/979, it's an ISBN. Otherwise EAN-13. If you instead recover a 12-digit string, that's the equivalent UPC-A.

Rule 4: An ASIN is NOT a GTIN. It is Amazon's internal identifier, not a real product code. You cannot lookup an ASIN at Walmart or Lowe's. ASINs starting with B0 are modern Amazon catalog IDs; older books may have ASINs that match their ISBN-10.

Rule 5: A walmart_item_id is NOT a GTIN. Walmart's internal ID. 6 to 12 digits, all numeric. Looks identical to a UPC short or an EAN if you don't know to check. If it's 9 to 11 digits and you know the source is Walmart, it's almost certainly an item_id, not a UPC. If it's 12 digits, you have to guess (or have the retailer pre-tag it for you).

The ambiguity bug that bit us

When we built retailerapi's identifier detector (identifier-lite.ts), we initially treated 11-digit numeric strings as "UPC-A short, left-pad with zero." Walmart item_ids are also frequently 11 digits. Our first deployment hit production and our example item 19667262713 (a real Walmart item_id) got mis-classified as a UPC-A and the lookup failed.

The fix: 6 to 11 digits routes to item_id first, with UPC as a fallback retry on miss. 12 digits routes to UPC first, with item_id as a fallback. 13 digits routes to EAN first, with ISBN as a fallback when prefix is 978/979. 14 digits to GTIN with strip-leading-zero. 10-character alphanumeric starting with B0 to ASIN.

The pattern: detect, try, fall back across formats on 404. Cheap latency cost on the rare miss; saves "doesn't exist" errors on perfectly real products.

When you only have one identifier and need another

ASIN to UPC: Amazon's PA-API returns gtin for most products. If you don't have PA-API access, scraping Amazon's product page surfaces the GTIN in the rendered HTML for ~85% of products. retailerapi's Phase 3 Amazon coverage will return both.

UPC to ASIN: Amazon's catalog supports UPC search via the PA-API ExternalIds parameter. Without PA-API, you can scrape Amazon's /s?k= search results and the first organic result is usually the right ASIN.

walmart_item_id to UPC: retailerapi's lookup_product returns both, regardless of which you input.

UPC to walmart_item_id: Same. Both directions work.

Bulk conversion: GS1's GEPIR service maps GTIN to manufacturer info but not to per-retailer SKUs. There is no canonical "UPC to ASIN" registry; everything is per-retailer.

How retailerapi handles this

Our lookup_product endpoint accepts any of UPC-12, EAN-13, ISBN-10/13, GTIN-14, or walmart_item_id, with optional format hint. Auto-detection runs first; if the primary format misses, we retry across the other numeric formats before giving up. ASIN inputs return a "Phase 3" placeholder (Amazon coverage ships separately).

curl -H "Authorization: Bearer rk_live_..." \
  "https://api.retailerapi.com/v1/products/194629116676"
# returns the same product whether you query by UPC, walmart_item_id,
# or any equivalent format

The full identifier-detection logic is open and lives in our identifier-lite source. About 50 lines of TypeScript.

When identifier mismatch is the actual bug

Sometimes a "missing product" report is really an identifier-format mismatch. Check:

  1. Did you pass leading zeros where they belong? UPC-A is exactly 12 digits.
  2. Did the retailer truncate? Walmart's CSV exports sometimes drop leading zeros from UPCs, turning a 12-digit UPC into an 11-digit string that looks like an item_id.
  3. Did you confuse ASIN with UPC? ASINs are alphanumeric (B0xxxxxxxx). If the input has any letters, it's not a UPC.
  4. Is the value actually a phone number, SKU, or order number? UPC and EAN have check digits at the end. Validating the check digit catches a surprising amount of accidental "this isn't a real UPC" data.

UPC-A check digit: sum positions 1, 3, 5, 7, 9, 11 (odd-indexed if 1-indexed) and multiply by 3, sum positions 2, 4, 6, 8, 10 (even-indexed), sum the two values, the check digit is (10 - (total mod 10)) mod 10. EAN-13 same formula with positions reversed (even × 3, odd × 1).

The standards behind the standards

UPC was created in 1973 by the Uniform Code Council (now GS1 US). EAN came in 1977 to give Europe its own allocation. ISBN was invented separately in 1970 for books and was later folded under GS1's 978 prefix. GS1 manages the global GTIN registry, runs the GEPIR lookup service, and accredits the prefix-allocation issuers in each country. ASIN is Amazon-internal, not a GS1 standard. walmart_item_id is Walmart-internal, also not a GS1 standard.

If you're building product software seriously, the GS1 General Specifications document is the source of truth, all 600+ pages of it. For day-to-day work, the cheat sheet above covers 99% of cases.

Try a real lookup

Working examples:

Sign up free for 1,000 lookups (no expiration, no card) and run any identifier through lookup_product.


Free account

Build with retailerapi

1,000 free lookups per month, no credit card. Cross-retailer price and history across every major US retailer that carries the product.