DEV Community

ByteHarvester
ByteHarvester

Posted on AI-assisted

EU customs identifiers from 1 Nov 2026: audit SKU coverage of many Shopify stores with one API call

If you look after more than one Shopify store, the EU customs deadline of 1 November 2026 is a catalog problem multiplied by your client list. The Shopify AI Readiness Audit on Apify answers the first, cheapest question for all of them in one call: how many variants in each store have a usable SKU, which SKUs are duplicated, and does the product page print a valid GTIN. It costs $0.01 per store (500 stores = $5), and stores it cannot read are free. Run it on your own list of stores. If you want to see it work first, open the ready-made EU customs ID check example task for 20 Shopify stores and press Start.

I am not giving legal advice, and I will say plainly what this can and cannot see further down. First, why SKUs are the right place to start.

Why SKUs, and why now

From 1 November 2026, EU customs declarations for online sales of goods to consumers need product identifiers for each item: your own product code, a manufacturer or supplier code, and a standardised code such as a GTIN where the product has one. For a Shopify merchant, your own product code is the variant SKU. A variant with no SKU, a placeholder such as N/A, or a SKU shared by several variants cannot identify anything.

For one store you fix that in a spreadsheet. For an agency with 40 clients, a developer building a catalog-cleanup service, or an analyst comparing a market, opening every store by hand does not scale. The public storefront already shows enough to size the job: every Shopify store that leaves it open serves its product list at /products.json, SKUs included.

What 1,071 stores looked like

In October 2026 we read the public data of 1,071 live Shopify stores (the first 50 products of each feed plus one product page). No store is named here. Two numbers matter for this deadline:

  • 50.3% of products have at least one variant with no SKU. 79.6% of the stores have at least one such product.
  • 8.4% of the stores print a GTIN in the Product JSON-LD of the product page we read. That is a lower bound, not the share of stores with barcodes: the public feed does not show barcodes, and a theme only prints one if it is set up to.

Half the products in that sample have a SKU gap. If your client list looks like the sample, a large part of it needs work before the deadline, and you want to know which part.

One API call for the whole list

The audit is an Apify Actor, so any language with an HTTP client can drive it. In Python, with the apify-client package (pip install apify-client):

from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("highbrow_fame/shopify-ai-readiness-audit").call(
    run_input={
        "stores": [
            "theme-dawn-demo.myshopify.com",
            "client-one.example.com",
            "client-two.example.com",
        ],
        "maxProducts": 50,
    }
)

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["status"] != "ok":
        print(row["input"], row["status"])  # unreadable stores are free
        continue
    print(
        row["store"],
        row["euSkuCoveragePct"],
        row["euVariantsWithoutSku"],
        row["euDuplicateSkus"],
        row["euGtinInJsonLd"],
    )
Enter fullscreen mode Exit fullscreen mode

Swap the list for your own, or pass csvUrl with a public link to a file with one store per line. Up to 5,000 stores fit in a run. You can also paste the same list into the Actor's input form on the Store page and download the rows as JSON, CSV or Excel, no code needed.

What one row looks like

This is the audit of Shopify's own demo store, theme-dawn-demo.myshopify.com (a store Shopify publishes for its free Dawn theme, so nobody's real shop), trimmed to the fields that matter here:

{
  "input": "theme-dawn-demo.myshopify.com",
  "status": "ok",
  "readinessScore": 95,
  "euSkuCoveragePct": 40.2,
  "euVariantsWithoutSku": 159,
  "euVariantsSampled": 266,
  "euDuplicateSkus": 0,
  "euGtinInJsonLd": true
}
Enter fullscreen mode Exit fullscreen mode

Read it like this: 159 of the 266 sampled variants have no SKU (so 40.2% coverage), no SKU value is used twice, and the product page prints a GTIN with a valid check digit. The overall readiness score is 95 out of 100, because the other parts (product feed completeness, Product structured data, AI crawler access) are in good shape. The EU fields do not change that score, and that is the point: a store can look healthy and still have a SKU gap, and now the gap has its own columns. When SKUs are missing, one of the row's top-three fixes says so in plain English ("Give every variant its own SKU").

Sort the table by euSkuCoveragePct ascending and you have your work queue for the next days.

What it costs

  • $0.01 per store audited, charged only for stores with status ok.
  • 20 stores = $0.20. 500 stores = $5. 1,000 stores = $10.
  • Stores that cannot be audited are free: product feed not public, robots.txt disallows it, blocked, rate limited, not a Shopify store, empty catalog.
  • Set a Maximum charge on the run and it stops cleanly when the budget is used up.

The honest caveat

This is a readiness proxy, not a customs check. The public product feed carries no barcodes and no manufacturer codes, so the Actor cannot tell you that a catalog is complete. A clean euSkuCoveragePct of 100 means your own product codes are in order; it does not mean the manufacturer codes and barcodes are, and euGtinInJsonLd describes the single product page that is read, not the whole catalog. It is also not legal advice: which of your parcels are in scope and what data your carrier needs is for your carrier or customs broker to confirm.

The Actor is polite by design: it reads robots.txt first and obeys it, makes at most three requests per store, identifies itself, and never retries after a refusal.

Who this is for

  • Agencies and freelancers who want one comparable table for a client list instead of 40 browser tabs.
  • Developers and app builders who need a lead list sorted by how much a store has to fix, or who want a SKU-readiness check inside their own tool through the API.
  • Analysts who want to measure the catalog quality of a market segment, the way the 1,071-store sample above was read.

The Python client is documented in the Apify docs. If you would rather call Apify Actors from an AI assistant than from Python, the apify-data-mcp project on GitHub shows how.

Do it before the 1st

1 November is close. A first run of 20 stores costs $0.20 and takes seconds: open the Actor, paste your stores, press Start. If it saves you an afternoon of tab-hopping, a short review on the Store page tells me what to improve next. And if you remember only one thing from this post: start with the SKUs, and audit the whole list in one go.

Written with AI assistance.

Top comments (0)