DPP Agent docs

Shopify — integration guide

DPP Agent is installed from the Shopify App Store and reads your catalogue through Shopify's GraphQL Admin API, version 2026-10. It never uses the REST Admin API, and it never writes to your store. One passport is created per product variant.

What the app does, in one sentence

DPP Agent pages through your products with the GraphQL products query, turns every variant into a draft passport, addressed by its barcode when the barcode is a GTIN and by its SKU when it is not, and ingests it through the same conflict-aware pipeline as every other integration.

Install and authorisation

The app uses Shopify's managed installation:

  1. The merchant installs DPP Agent from the Shopify App Store.
  2. Shopify shows the access the app asks for (see the scopes below) and the merchant approves it. Shopify, not DPP Agent, runs this consent screen.
  3. When the app opens inside the Shopify admin, it exchanges Shopify's session token for an offline access token (token exchange). The token expires and is renewed automatically before each sync.
  4. The token is encrypted at rest (AES-256-GCM), decrypted only in memory, and never logged or shown in the UI.

There is no separate OAuth "code" flow and no access token to paste.

Access scopes

All read-only:

Scope Why
read_products Products, variants, images, product video, metafields
read_inventory Whether a variant ships, and its country of origin
read_translations Product titles and descriptions in your other languages
read_locales Which languages your store publishes
read_markets Which countries you sell to, so we can tell whether EU rules apply
read_metaobjects The values of Shopify's category metafields (colour, fabric, target gender, age group, care instructions…), which are stored as metaobjects

read_metaobjects was added in October 2026. A store that installed before then is asked to approve it the next time the app is opened in the Shopify admin. Until the store approves it, sync still runs; the category metafields are kept as references and not mapped.

No customer, order or draft-order data is requested. No write scope is requested.

How a variant gets its address

The variant has… Passport address
a barcode that is a GTIN /01/<gtin> (GS1 Digital Link)
a barcode that is not a GTIN, and a SKU /products/<sku>
no barcode, and a SKU /products/<sku>
neither a GTIN nor a SKU no passport

A barcode counts as a GTIN only when it is 8, 12, 13 or 14 digits, its GS1 check digit computes, and its prefix is one GS1 issues for trade items (not an in-store, coupon or demonstration prefix). A barcode that fails is kept on the passport as shopify.raw.barcode, so you can see why the passport is on /products/.

DPP Agent never makes up a GTIN. Add the real barcode in Shopify and sync again to move a variant to /01/<gtin>. The sync result counts each case: passports_gtin, passports_sku, barcodes_not_gtin, variants_without_barcode and variants_without_address.

What is read, and where it lands

Passport field Shopify source
GTIN / address variant.barcode (see above), else variant.sku
espr.pid.product_name product.title (+ translations)
espr.pid.product_description product.descriptionHtml, HTML removed, first 600 characters (+ translations)
espr.pid.color the variant option named Colour (or Color, Färg, Farbe…); else the product's shopify.color-pattern when it has exactly one value
espr.pid.size the variant option named Size (or Storlek, Größe, Taille…)
tex.pid.model_number variant.sku
tex.product.brand_category product.productType (+ translations)
tex.product.hero_image_url, tex.product.gallery product media images, the variant's own image first
tex.product.video the product's video (the MP4 nearest 720p)
tex.mfg.country_of_origin variant.inventoryItem.countryCodeOfOrigin
tex.pid.target_group shopify.target-gender + shopify.age-group (see below)
espr.care.instructions shopify.care-instructions, when every value is an instruction
ict.energy.class shopify.energy-efficiency-class, classes A–G only

Options are matched by their name, not their position. An option whose name is not recognised is kept in shopify.raw.options.

Shopify's category metafields

Shopify's standard product taxonomy gives each category a set of attributes that merchants fill in under Category metafields. DPP Agent maps one to a passport field only where the meaning is the same, and decides on Shopify's taxonomy value, not on the label you see (which you can rename):

  • Target group: Female + Adults → women, Male + Adults → men, Unisex + Adults → unisex, Female + Kids → girls, Male + Kids → boys, Babies / Newborn / 0–6 months / 6–12 months → babies. Other combinations (for example Teens, Toddlers, or Unisex + Kids) are not mapped.
  • Colour: only when the product has a single colour value; otherwise the variant's Colour option is used.
  • Care instructions: Machine washable, Hand wash, Dry clean only, Tumble dry, Dryer safe, in your own wording. "Ironing instructions" and "Other" are not instructions, so a set containing them is not mapped.
  • Energy efficiency class: A to G. A+, A++ and A+++ belong to the old scale and are not mapped.

Every category metafield, mapped or not, is kept on the passport under shopify.raw.category_metafields with its labels, its taxonomy values and the field it was mapped to (null when it was not). Fabric, material, pattern, size, recycled content, certifications and the rest are kept there for you to confirm in a later release; they are not written to the passport's material composition, because a fabric name is not a fibre composition with percentages.

Your own metafields

Metafields in your own namespaces (for example custom.*) are read and kept on the passport under shopify.raw.metafields with their type and value, marked with Shopify as the source. They are not written to any passport field. A screen for choosing where each one goes is planned.

What Shopify does not hold

Shopify has no place for fibre composition with percentages, the manufacturer, substances of concern, certificates, repair or end-of-life information. Add these in DPP Agent, upload a document, or connect a supplier system such as Delogue or TrusTrace alongside.

Settings reference

Setting Required Purpose
shop_domain yes <your-shop>.myshopify.com, set at install
product_status no Default active. draft, archived or any for a one-off pull
exclude_product_types no Extra product types never to make passports for

The API version is not a setting. Every call uses the version DPP Agent is built and tested against (2026-10 today); it is raised for all stores at once.

Sync semantics

  • Sync runs from an hourly scheduler, at the interval set per connection (default every 6 hours), and on demand from the integration page.
  • Products are read a few at a time, with cursor pagination; the page shrinks automatically if Shopify reports a query is over its cost limit, and the sync waits when Shopify asks it to (throttling).
  • Draft passports are updated. A published passport gets a pending revision for a person to review. Withdrawn, archived and recalled passports are left alone.
  • A product removed from Shopify keeps its passport (EN 18219 / EN 18223 retention).

Uninstall

Uninstalling the app stops sync immediately and clears the access token. The passports stay until Shopify sends shop/redact (48 hours after uninstall), which deletes the store's data in DPP Agent.

Troubleshooting

  • HTTP 401 on sync — the app was uninstalled, or the authorisation could not be renewed. Open DPP Agent from the Shopify admin to renew it.
  • metaobjects: no_scope in the sync result — the store has not approved read_metaobjects yet. Open the app in the Shopify admin and approve the updated access.
  • Many passports on /products/ — the variants have no barcode, or a barcode that is not a GTIN. Fill in the barcode in Shopify and sync again.
  • A variant has no passport — it has neither a GTIN barcode nor a SKU.
  • Empty catalogue — all products are draft or archived while product_status is active.

Open a ticket at support@dppagent.com with the integration ID and the sync log.