Developer Changelog / Admin GraphQL API

Variants
now support multiple barcodes
— barcode is being deprecated

The one-barcode-per-variant limit is gone: a variant can now hold up to 20 typed identifiers across UPC / EAN / ISBN / GTIN / ASIN. The old barcode field keeps working, but it is deprecated. Keep reading only that field and you will never notice the other barcodes exist.

What's on this page
  1. The 30-second version: what changed
  2. How it works: the read and write paths
  3. Supported barcode types and validation
  4. Usage rules (limits, overwrites, exclusivity)
  5. Compatibility with barcode (deprecated)
  6. The biggest pitfall: silent truncation
  7. Migration in 3 steps
  8. 5 points developers should know
  9. 3 use cases you can put to work
  10. A one-line summary for your pitch

1The 30-second version: what changed

Plenty of merchants sell the same variant under several identifiers: the manufacturer's UPC, a private-label EAN, a GTIN, a reissued ISBN, a marketplace ASIN, and so on.
Until now, a variant could hold only onebarcode, so the extras had to be parked in metafields, tags, or somewhere outside Shopify. Where each identifier lived came down to per-store tribal knowledge.Now multiple barcodes are a first-class data structure.

Before: only one fits

Any identifier beyond the first was pushed into metafields, tags, or an external system. Which one held what varied store by store and lived in someone's head.

Now: up to 20, typed

ProductVariant.barcodes connection to read, and thebarcodes input to write. Declare the type and the value is validated against that standard's rules.

Three mutations can write them: productSet / productVariantsBulkCreate / productVariantsBulkUpdate . All three accept the barcodes input.

2How it works: the read and write paths

Write (mutation) productSet productVariantsBulkCreate productVariantsBulkUpdate input: barcodes (sending replaces all) ProductVariant barcodes[0] (first) barcodes[1] barcodes[2] ... up to 20 barcode (deprecated; points to the first one) Apps that read barcodes All identifiers are visible ✓ Recommended Apps that read only barcode Only one is visible △ Can't tell the others exist
Search has caught up too : products and productVariants queries' barcode filter now matches any of the barcodes a variant holds. It no longer matches only the first one.

3Supported barcode types and validation

Each barcode can declare a type . When declared, the value is validated against that format's character set, digit count, prefix, and check digit rules.

UPC
EAN
ISBN
GTIN
ASIN
With type

Validated against the standard

Values that don't match the character set, length, prefix, or check digit rules are rejected. Data quality is enforced at the API layer.

Without type

Stores the value exactly as sent

If you don't declare a type, the submitted value is stored as-is.Existing untyped data keeps working as before, so there's no need to retype everything in bulk.

4Usage rules (count, overwrite, exclusivity)

RuleDetailsWhat it means in practice
Max count 20 / variant If you need a 21st, rethink the design (a separate variant or a metafield)
Max length 255 characters / barcode Plenty for real-world identifiers; not meant for packing in concatenated values
Sort order The first value you send is sorted to the front of the connection You can design around putting the "primary identifier" first
Write behavior Full replacement barcodes A write replaces the entire set always include the barcodes you want to keep. It is not a partial patch
Mutual exclusion Not allowed In a single variant input, barcode and barcodes cannot both be set Migration-era code that sets both will fail. Commit to one or the other
Search filter products / productVariants 's barcode filter matches any single entry searching by a secondary identifier still returns a hit
"Full replacement" is the easiest way to break things : if you send barcodes: [新しい値] intending to add just one, every existing barcode is wiped. Always implement it as read → merge → send the full set , in that order.

5Compatibility behavior with barcode (deprecated)

ProductVariant.barcode is now deprecated, butnothing breaks as of today. It is enough to remember the behavior as "it always points to the first item in the connection."

Read

barcode , you getthe first entry in the barcodes connectionback.

Write

barcode updates only the first entry, andleaves the other barcodes untouched.

Sending an empty value

Sending an empty value clears the first entry, andthe next barcode in the set moves up. The same behavior repeats until none are left.

By adding or swapping the barcode in the first position, you cancontrol how not-yet-migrated screens and integrations see the data whilestill getting the benefits of multiple barcodes. It works as an escape hatch for migrating in stages.
Removal timeline : The deprecation date will be announced later. Before the field goes away, there will reportedly be a notice period of one full API version. No specific date has been given.

6The biggest pitfall : silent truncation

Variant in Shopify UPC 0123456789012 EAN 4901234567894 ASIN B0XXXXXXXX 3 barcodes stored correctly reads barcode only Existing integration UPC 0123456789012 the other 2 appear to be "missing" ERP Marketplace POS Supplier feed identifiers missing synced no error, no warning
From the moment a second barcode is added, integrations that read only,barcode see just "one of them," andget no signal that the others even exist.
Apps that sync product identifiers to ERP, marketplaces, POS, and supplier feeds should move their reads to the barcodes connection.

7Three migration steps

1

Find every reference to barcode

Catch every barcode read in your code. Prioritize the paths that write out to external systems.

2

Swap reads over to barcodes

connection to fetch every entry, filtering by type when needed. Where a single barcode is enough, take the first one explicitly.

3

Make writes a merge

barcodes is a full replacement, so switch to "read → merge → send everything."barcode cannot be used alongside it, so standardize on one.

85 points engineers need to know

1. Writes are a full replacement, not a diff

barcodes replaces the variant's entire set.send everything you want to keepis mandatory. Reusing an existing app's update code as-is will wipe them all out.

2. barcode and barcodes are mutually exclusive

You cannot set both in a single variant input. A "write both to be safe" implementation is not viable mid-migration, so decide which one each path uses and commit to it.

3. Declaring type means opting into validation

Declaring UPC / EAN / ISBN / GTIN / ASIN validates character set, length, prefix, and check digit.The moment you declare a type, dirty data that used to pass through starts getting rejected— keep that in mind.

FIRST

4. The "first" entry is the key to backward compatibility

Legacy screens and not-yet-migrated integrations always read the first entry.What you put first is itself your compatibility design. Pinning the primary identifier to the first slot in line with your migration order prevents incidents.

5. The scariest failure is degradation that throws no error

Silent truncation raises no exception and no warning.Apps that sync identifiers to ERP / marketplace / POS / supplier feedscan end up quietly pushing wrong data even if nothing breaks tomorrow. There is no deprecation date yet (a future announcement plus one API version of notice), butmigration urgency is driven by data integrity, not by the deprecation date.

9Three use cases you can put to work

metafield tag External CSV
USE CASE 1

Consolidate identifiers scattered across metafields into a proper data structure

Challenge
Because of the one-barcode-per-variant limit, every UPC / EAN / GTIN beyond the first ends up scattered across metafields, tags, and spreadsheets outside Shopify, and nobody knows which one is authoritative.
What to do
Take inventory of the scattered identifiers and consolidate them onto a single variant with theproductVariantsBulkUpdate barcodes input. Where the standard is known, declare type so the values pass validation.
Impact
Identifiers live in exactly one place, and search can span everything with the barcode filter. The inventory process also surfaces invalid values.
Technical note
The limit is 20 entries / 255 characters each. The migration script replaces the whole set, so send "all existing entries plus the new ones" together in one call.
Shopify ERP POS MP
USE CASE 2

A health check that prevents "silent data loss" in ERP / POS / marketplace integrations

Challenge
In-house and contracted integration apps read only a single barcode and sync that to external systems. The moment a merchant registers a second barcode, incomplete identifiers keep flowing outward (with no warning).
What to do
Find every barcode reference in your integration code and replace it withbarcodes connection reads. As an interim step before migrating, extract the variants that have two or more barcodes and report on them.
Impact
You head off the failures that take the longest to diagnose: marketplace listing errors, receiving inspection mistakes, and supplier feed mismatches.
Technical note
To extract them, walk productVariants and check the count of barcodes . There is no deprecation date yet, butthe impact starts well before the deprecationis the point to watch.
UPC ✓ EAN ✓ ISBN ✗
USE CASE 3

Let the API guarantee product data quality with typed barcodes

Problem
UPCs / EANs with a bad check digit or too few digits slip into the product catalog and only surface at listing or inspection time. Rolling your own validation means ongoing maintenance cost.
Approach
At import time, declare type(UPC / EAN / ISBN / GTIN / ASIN) when writing so the value passes Shopify's validation. For values whose standard can't be determined, send them with no type declared and they are stored as-is.
Impact
Invalid identifiers are rejected at the point of entry. No more maintaining your own validator, and updates to the standards' rules are left to Shopify.
Technical notes
Declaring a type can cause existing invalid data to be rejected, so it's safer tofirst surface the number of validation errors with a dry-run equivalentbefore applying it for real. With no type declared, the value is stored as-is and behavior is unchanged from before.

10One-line summary you can use in a proposal

"The one-barcode-per-variant limit is gone: you can now hold up to 20 typed identifiers (UPC / EAN / ISBN / GTIN / ASIN).
The legacy barcode is deprecated but won't break today. However, from the moment a second barcode is registered,barcode -only integrations will silently drop identifiers.
For projects with ERP, POS, or marketplace integrations, the first move is to switch reads to barcodes rather than waiting for the sunset date."