The route from "mozimo.in displays Shopify products" to "mozimo.in sells them", as a plan with a phase spine and gates, plus the open decision tickets that still shape it and the evidence they rest on. - .scratch/shopify-headless-commerce/: plan.md (phases and gates), map.md (the wayfinder map), 10 open decision tickets - CONTEXT.md: Storefront / Theme store / Cart / Parity vocabulary - docs/adr/0001-0003: Checkout stays Shopify-hosted, one Variant per product, the checkout domain stays shop.mozimo.in - docs/research/ and docs/shopify-catalog-inventory.md: verified store facts, the Cart API probe, and the catalogue inventory Raw Shopify doc scrapes under .scratch/shopify-research/ are ignored: they are working material, not record.
63 KiB
Shopify admin operations: product CSV round-trip fidelity + customer accounts system (verified 2026-10-13)
Purpose. Two focused factual questions, answered only from Shopify-owned primary sources:
- What survives a manual admin product CSV export → import round trip between two Shopify stores, in particular product metafields.
- Which customer accounts system the merchant's
Settings > Customer accountspage describes, and the lifecycle/plan facts around new vs legacy customer accounts.
Facts only. No recommendations.
Store context (from the parent task and the sibling note
shopify-cart-probe-2026-10.md): mozimo.in, shop GID
gid://shopify/Shop/74467967222, 61 products each with exactly one variant, 16 collections, 20 products
with nutrition/ingredient metafields.
0. How this was verified (and one method finding worth reusing)
-
shopify.dev: every page was fetched as raw Markdown by appending.mdto the HTML URL (e.g. https://help.shopify.com/en/manual/products/import-export/export-products.md), which the site itself documents as available for any page. -
help.shopify.com— the 403 was bypassed by the same.mdsuffix. Bare help-centre URLs return HTTP 403 with<title>Verifying your connection...</title>(Shopify's bot challenge) forcurl, for theweb_fetchtool, and regardless ofUser-Agent(tested: defaultcurl, Chrome desktop, Safari desktop, Googlebot). Appending.mdto the same URL returns HTTP 200 with the complete, untruncated raw Markdown article. Confirmed pairs, same second:URL HTTP https://help.shopify.com/en/manual/products/import-export/export-products403 https://help.shopify.com/en/manual/products/import-export/export-products.md200 (8,029 bytes) A locale-prefixed path is required:
/en/manual/.... Bare/manual/...(no/en) also 403s. This was used for essentially everyhelp.shopify.comclaim below, so the impact of the bot challenge on this research was zero. -
The official sample product CSV was downloaded from the help centre: https://help.shopify.com/csv/product_template.csv → HTTP 200, 6,536 bytes, 61 header columns. Its header row and example rows are quoted verbatim in §1.3 and §1.5. Note: the canonical URL without the
/enprefix works for this asset (/csv/product_template.csv), while/en/csv/product_template.csvreturns the HTML app shell, not the CSV. -
Shopify changelog (
https://shopify.dev/changelog/...andhttps://changelog.shopify.com/posts/...) — the latter supports no.md(HTTP 406) and was extracted from its HTML. -
Shopify community forums were read via the forum's own JSON API (
https://community.shopify.com/t/<id>.json,https://community.shopify.dev/t/<id>.json,.../search.json?q=). These are not documentation; every community claim below is labelled as such and is never used as the sole support for a fact that a primary source could carry. -
What is marked UNVERIFIED is listed inline and collected in §3.
Question 1 — Product CSV export/import round-trip fidelity
1.1 The exact export click path, and the export options
Source: https://help.shopify.com/en/manual/products/import-export/export-products (https://help.shopify.com/en/manual/products/import-export/export-products.md).
Admin path and options, verbatim from the doc:
- Go to Products (https://admin.shopify.com/products).
- Click Export.
- In the dialog, choose the products:
- the current page of products
- All products
- products you have selected
- products that match your search and filters
- Choose the file type:
- CSV file for Excel, Numbers, or another spreadsheet program — "if you plan to use a spreadsheet program to edit your product CSV file"
- Plain CSV file — "if you plan to use a plain-text editor"
- Click Export products.
How the file reaches you (this is conditional, and matters for a 61-product store):
| Situation | Delivery |
|---|---|
| All products selected | CSV is emailed to you; if you aren't the store owner it is also emailed to the store owner |
| Current page or Selected products, and any single product has >100 variants | CSV is emailed |
| Current page or Selected products, and all products have <100 variants | CSV is downloaded by your browser |
Same source (.md, "Export your products" preamble).
Only one file is produced — a single products CSV. There is no second artefact and no image bundle. No doc states the filename; UNVERIFIED (the docs never name the downloaded/emailed file).
Encoding: "A CSV file with UTF-8 encoding is the only file format that can be used to import to or export from Shopify." (same source, "Use a text editor to edit your products CSV file").
1.2 Filtered export (relevant if the export must be split)
- On Products, add a filter so only the wanted products are listed.
- Export, selecting the option that exports only the products matching your filter.
Source: https://help.shopify.com/en/manual/products/import-export/export-products.md. A documented export failure mode for large files: "There was an error exporting your products. Try again in a few minutes" indicates the export timed out (thousands of variants); the documented workaround is to filter and export smaller subsets (same source, "Troubleshooting product exports").
1.3 What is actually in the exported file (headers)
The docs publish the full column list at https://help.shopify.com/en/manual/products/import-export/using-csv#csv-file-description.
The official sample CSV (https://help.shopify.com/csv/product_template.csv, fetched 2026-10-13) carries this exact header row, 61 columns, quoted verbatim:
Title,URL handle,Description,Vendor,Product category,Type,Tags,Published on online store,Status,SKU,Variant Barcodes,Option1 name,Option1 value,Option1 Linked To,Option2 name,Option2 value,Option2 Linked To,Option3 name,Option3 value,Option3 Linked To,Price,Compare-at price,Cost per item,Charge tax,Tax code,Unit price total measure,Unit price total measure unit,Unit price base measure,Unit price base measure unit,Inventory tracker,Inventory quantity,Continue selling when out of stock,Weight value (grams),Weight unit for display,Requires shipping,Fulfillment service,Product image URL,Image position,Image alt text,Variant image URL,Gift card,SEO title,SEO description,Color (product.metafields.shopify.color-pattern),Google Shopping / Google product category,Google Shopping / Gender,Google Shopping / Age group,Google Shopping / Manufacturer part number (MPN),Google Shopping / Ad group name,Google Shopping / Ads labels,Google Shopping / Condition,Google Shopping / Custom product,Google Shopping / Custom label 0,Google Shopping / Custom label 1,Google Shopping / Custom label 2,Google Shopping / Custom label 3,Google Shopping / Custom label 4,Packed product length,Packed product width,Packed product height,Packed product dimension unit
Two further header sources exist and do not agree word-for-word with either the sample or the current documentation — see §1.5 and §1.9:
- A legacy header list is still published in the help centre's import-troubleshooting article:
Handle,Title,Body (HTML),Vendor,Type,Tags,Published,Option1 Name,Option1 Value,...,Image Src,Image Alt Text(https://help.shopify.com/en/manual/products/import-export/common-import-issues.md, "Invalid CSV header: missing headers"). The authoritative current list on the same help centre is theusing-csvone cited above; the article itself notes Shopify "maintains backward compatibility with older column names" (https://help.shopify.com/en/manual/products/import-export/using-csv.md). - Market columns are appended conditionally: "If you have Markets set up on your store, then your
CSV export includes columns for some of your markets...
Included / [Market],Price / [Market],Compare At Price / [Market]." A market gets columns only if exactly one of its active catalogs isn't shared with another market. The primary market always appears asIncluded / [Primary]and the default international market asIncluded / International(same source, "International CSV columns"). So a Mozimo export is not exactly 61 columns; it carries extra market columns.
1.4 The exact import click path, and how the import behaves
Source: https://help.shopify.com/en/manual/products/import-export/import-products (https://help.shopify.com/en/manual/products/import-export/import-products.md).
- Go to Products.
- Click Import.
- Click Add file, select the CSV.
- Optional: deselect Publish new products to all sales channels to publish new products only to the online store.
- Optional: select Overwrite products with matching handles.
- Click Upload and continue.
- Review the details about the import, then click Import products.
Is it a background job? The doc describes an upload → review → confirm flow, followed by a confirmation email from Shopify, and an activity log you can check afterwards. It never calls it a "background job". It does say explicitly: "Product imports started with a CSV file can't be canceled once they begin, and you can't view a history of past imports. To review recent changes made by an import, check your store's activity log." A separate note states that after upload "you receive a confirmation email from Shopify to the email address of your user account" (same source, "Import products from another store"). UNVERIFIED: the doc does not state whether processing continues after the admin tab is closed, nor any progress/status surface beyond the email and activity log.
Dry run / preview? There is a step 7 "Review the details about the import". The docs do not describe it as a data preview, a row-level validation report, or a dry run — the phrase is "details about the import". No documented dry-run/preview exists. UNVERIFIED what that review screen lists.
How errors are reported. Documented error surface is (a) a set of named error messages, and (b) per-line messages. From https://help.shopify.com/en/manual/products/import-export/common-import-issues.md:
Daily variant creation limit reached, try again— for stores with ≥500,000 variants (excluding Plus), max 10,000 new variants per 24 hours created by CSV uploads or API; the 24-hour timer starts at the first upload of the day.Fulfillment service can't be blank— must be a fulfilment-service name, ormanual.Ignored line #-## because handle 'example' already exists— "The handle is used to uniquely identify each individual product."Ignored line #-## because it did not contain product data— a handle with no product title.Illegal quoting on line,Missing or stray quote on line,Unexpected characters or symbols(non-UTF-8 encoding),Network error: Unexpected token < in JSON at position 0(column headers don't match the template exactly; headers are case-sensitive, e.g.Handlenothandle),Not a valid product category,Inventory quantity can't be blank,Inventory quantity is not a number,Inventory policy is not included in the list,Validation failed: price can't be blank,Validation failed: options are not unique,Import fails with error "Line is invalid (No details)".- Image-specific validation failures:
Validation failed: An error occurred while trying to download the image("An image file is missing") andValidation failed: getaddrinfo: nodename nor servname provided, or not known(image URL needshttp:///https://and a publicly accessible direct link) — same source.
Is it idempotent? Does re-importing update by handle or duplicate? This is documented precisely
(https://help.shopify.com/en/manual/products/import-export/using-csv#overwriting-csv-file and the
import-products page):
- With
Overwrite products with matching handlesselected: "when the handle in the import CSV file matches an existing handle in your products list, the values in the CSV file overwrite the values in the matching columns in the existing product list." → re-running the same file updates existing products; it does not create duplicates. - Without that option selected: "the products that match an existing handle are ignored during CSV import." → re-running the same file is a no-op for those products, not a duplicate generator.
- The
Ignored line #-## because handle ... already existserror message corroborates handle-as-key (https://help.shopify.com/en/manual/products/import-export/common-import-issues.md). - A conflicting handle inside one file also fails: "Ignored line #-## because handle
examplealready exists". - CSV cannot bulk-delete products — use bulk actions in Products (https://help.shopify.com/en/manual/products/import-export/using-csv#overwriting-csv-file).
File limit: "Your product CSV can't exceed 15 MB." If the upload errors or times out, split the file (https://help.shopify.com/en/manual/products/import-export/import-products.md).
Required columns. Importing new products: only Title (plus URL handle if adding variants).
Updating products: URL handle and Title. Header names are case-sensitive.
(https://help.shopify.com/en/manual/products/import-export/using-csv.md, "Required columns in the
product CSV file".)
Not a migration tool for anything else. Nothing in the product CSV docs covers customers, orders, discounts, gift cards, or files.
1.5 Variants, and the Title / Default Title question
Representation. One row per variant, with the product-level data repeated on the first row and only the handle repeated on subsequent rows. The docs describe two shapes (https://help.shopify.com/en/manual/products/import-export/using-csv.md, "Create your product CSV file"):
- "Simple product: A simple product doesn't include variants. If you upload a product that doesn't have variants, then enter all the fields for the product in the first row along with the URL for the first image. In the following rows, only enter the handle and the URL for each additional image."
- "Product with variants: ... enter all the fields for the product in the first row along with the URL for the first image. In the following rows, enter the URL handle. Then skip the Title, Description, Vendor, and Tags columns. Fill out the rest of the variants' details and each image URL."
The option columns are Option1 name / Option1 value / Option1 Linked To, up to Option3
(case in the current docs: Option1 name; the sample CSV also uses Option1 name). Up to 3 options per
product (same source, column table).
On the merchant's exact shape (61 products, one variant each, option name Title): the published
guidance is internally inconsistent, and this is the single most quotable wrinkle found:
| Source | What it says for a one-option product |
|---|---|
Current column reference, Option1 name row: "If a product has only one option, then this value should be Default Title." |
Default Title — https://help.shopify.com/en/manual/products/import-export/using-csv.md |
Official sample CSV (/csv/product_template.csv), row 16, product Example Perfume |
Option1 name = Title, Option1 value = Premium — i.e. option name Title with an arbitrary value |
Also in the sample, Title is used as the option name for the single-option product, while multi-option products use Size/Color/Format (verbatim rows quoted in this file's own python3 csv alignment, from the downloaded sample) |
Title |
| Community help article (Shopify-staff-authored account, but a forum post, 2023-05-09): "Change the Option1 Name column value to Title and the Option1 Value column value to Default Title." | Title + Default Title — https://community.shopify.com/t/214856.json |
So the docs' Default Title instruction is about the value; the sample uses Title as the name.
The merchant's stored shape (option name literally Title) is exactly the shape the official sample CSV
represents. Consequence for the round trip:
- Re-importing an unmodified export reproduces the exported shape by construction — the export writes
whatever the store holds, and import consumes the same columns. UNVERIFIED: no primary source
states, for this admin, the literal string an export writes into
Option1 valuefor a one-variant product whose option name isTitle. The only way to establish it is to read the merchant's own export. - Real risk documented around the option columns, not around the name itself:
- "Changing data in the
Option1 value,Option2 value, orOption3 valuecolumns of the product CSV file deletes existing variant IDs, and creates new variant IDs." - "If you don't include the
Option1 nameandOption1 valuecolumns, then a new default variant is created and existing variants are deleted." - "If a non-required column is included in the import CSV file that relies on other column data not
included in the file, then existing data is deleted or removed. For example, if the
SKUcolumn is included in the import CSV file, but not theOption1 valueandOption1 namecolumns, then the product variant option is deleted." - Option-name conflicts fail the whole import with
Line is invalid (No details); the documented workaround is a temporary option name in a first import, then a second import to rename. - "Validation failed: options are not unique." All from https://help.shopify.com/en/manual/products/import-export/using-csv.md and https://help.shopify.com/en/manual/products/import-export/import-products.md.
- "Changing data in the
1.6 METAFIELDS — do custom.ingredients / custom.energy_kcal survive? Yes, with conditions.
Short answer. Product metafields do travel in the product CSV and are a first-class part of the documented CSV column set — but only metafields that have a definition, and the round trip is a two-part operation: (1) definitions in the destination store, (2) the values, which ride in the CSV. There is no separate metafield CSV file in the admin. Variant metafields are excluded from product CSV entirely.
Primary source: https://help.shopify.com/en/manual/products/import-export/using-csv.md
(§"Metafields in CSV columns", §"Variant metafields", and the Metafields row of the column table) —
the same page saved as raw Markdown at
https://help.shopify.com/en/manual/products/import-export/using-csv.md.
Verbatim facts:
- "Product metafields are supported in product bulk import/export using CSV files. After a product metafield is defined, it's included in your product CSV exports."
- Header format:
<name>(product.metafields.<namespace>.<key>) — e.g.Fabric (product.metafields.shopify.fabric)— or bareproduct.metafields.<namespace>.<key>. The sample CSV carries a live example column:Color (product.metafields.shopify.color-pattern). The column-table row repeats the format asNAME; (product.metafields.custom.KEY). The namespace/key are found in Settings > Custom data > Products (same page). → For the merchant:custom.ingredientsandcustom.energy_kcalappear asIngredients (product.metafields.custom.ingredients)andEnergy kcal (product.metafields.custom.energy_kcal)(the display name is the definition's name; the parenthesised identifier is authoritative). - Supported metafield types in CSV bulk import/export (verbatim list):
boolean,color(#ff00cc),date,date_time,dimension(25.0cm),list.color,list.date,list.date_time,list.dimension,list.metaobject_reference,list.number_decimal,list.number_integer,list.product_reference,list.url,list.volume,list.weight,money(5.99 CAD),multi_line_text_field,number_decimal,number_integer,product_reference,shopify.disclosure,single_line_text_field,url,volume,weight.custom.ingredientsas text →multi_line_text_field(supported; example given is literally"Ingredients\nFlour\nWater\nMilk\nEggs").custom.energy_kcalas a number →number_integerornumber_decimal(supported).
- Variant metafields do NOT round-trip. Verbatim: "Variant metafields aren't supported for product CSV import/export. To edit your variant metafields in bulk, you need to use the variant bulk editor, and then add metafield columns." → https://help.shopify.com/en/manual/products/import-export/using-csv.md; bulk editor how-to at https://help.shopify.com/en/manual/custom-data/metafields/bulk-edit-metafields.md.
- Definition-before-value requirement. "Metafield definitions act as templates that specify what part of your store a metafield applies to and what values the metafield can have. Before you can add metafield values to specific products... you need to add the metafield definition for that information." — https://help.shopify.com/en/manual/custom-data/metafields/metafield-definitions.md. Definitions live at https://admin.shopify.com/metafields; up to 256 definitions per type. The CSV page's phrasing "after a product metafield is defined, it's included in your product CSV exports" means an undefined product metafield is not guaranteed to appear as a column, and the docs never state what happens to an undefined metafield's value during import. → Treat "metafield values with no matching definition in the destination store" as UNVERIFIED / not documented. (A community thread on 2026-09-24 reports category-linked metafields being added as columns for products with a category — https://community.shopify.com/t/686939.json — but it is a forum post, not documentation.)
- No separate metafield export/import file or step exists in the admin. The metafields help section (https://help.shopify.com/en/manual/custom-data/metafields.md) lists no export/import feature; its bulk tooling is the admin bulk editor ("Editing metafields in bulk": "You can use the bulk editor tool to make changes to multiple metafields at the same time. You can edit metafields in bulk for products, variants, collections, and customers."), which edits in place and does not produce a file. → The product CSV is the supported admin mechanism for moving product metafield values.
- Overwrite semantics apply to metafield columns too, and they are destructive. With Overwrite products with matching handles on: "If a non-required column in the import CSV file is blank, then the matching value in the product list is overwritten as blank." So a blank metafield cell in an overwrite import clears the destination value (https://help.shopify.com/en/manual/products/import-export/using-csv.md#overwriting-csv-file).
- Metaobjects are not exported as content. Metafield references to metaobjects are supported as
identifiers (
list.metaobject_referenceaccepts GIDs or handles), but no doc says metaobject definitions/entries travel in the product CSV. UNVERIFIED and not mentioned anywhere in the CSV or metafields help pages.
Metafield-only alternative for moving values between stores: the docs describe no file-based
alternative in the admin. The developer-surface option is the GraphQL Admin API
metafieldsSet (https://shopify.dev/docs/api/admin-graphql/latest/mutations/metafieldsSet) with
MetafieldDefinition creation (https://shopify.dev/docs/api/admin-graphql/latest/input-objects/MetafieldDefinitionInput),
and Shopify's metafields developer guide (https://shopify.dev/docs/apps/build/metafields,
https://shopify.dev/docs/apps/build/custom-data/metafields). This note records only that these exist;
no recommendation is made.
1.7 Images
Primary source: https://help.shopify.com/en/manual/products/import-export/using-csv.md
("Prepare your images", "Adding multiple product images in a CSV file", and the Product image URL,
Image position, Image alt text, Variant image URL rows) and
https://help.shopify.com/en/manual/products/import-export/export-products.md ("Access your product
image files").
- The CSV carries image URLs, not image bytes. Columns:
Product image URL,Image position,Image alt text,Variant image URL. "A CSV file can only contain text, therefore, you need to make sure that all product images are on an existing website. Those image URLs are only used during the CSV file importing process. You can delete the URLs after your import is complete." - Import re-hosts the image. "Enter the URL for the product image. Shopify downloads the images
during the import and re-uploads them in your store." → a
cdn.shopify.comURL from the source store is fetched and copied into the destination store. - The source store must stay alive and its images publicly reachable until the import completes —
this is the documented failure mode for exactly the migration case in question:
- "When you export your products, the images associated with each product aren't included in the CSV file. If you import the products to a new store, then the product images are generated only if they remain viewable on a publicly accessible website."
- "To ensure that your product images remain accessible to you, leave your original store and its products intact until you finish the import process."
- "If you remove products or product images from your Shopify store after exporting, and then try to import those products without updating their image URLs, then your import will fail."
- "Your product images must be uploaded to a publicly accessible URL. That is, they should be behind an
https://protocol with no password protection." - Documented image errors:
Validation failed: An error occurred while trying to download the image("An image file is missing"),Validation failed: getaddrinfo: nodename nor servname provided, or not known(malformed URL / not a direct public link), andIncorrect header check— "Remove the image from that line and try again. If that resolves the issue, then try hosting the image somewhere else." (https://help.shopify.com/en/manual/products/import-export/common-import-issues.md).
- Alt text survives —
Image alt textis a first-class column. Max 512 characters, optimal ≤125. - Image order survives via
Image position(ascending, starting at 1). One row per image. - Filename constraints on import: the image file name "is final: you can't edit it after the image has
been uploaded to your store" and must not contain
_thumb,_small, or_mediumsuffixes. - Cap and media types: up to 250 images per product; "You can use only image URLs in CSV files. 3D models and videos aren't supported for the CSV."
- Files-area duplication: importing an image that lives in the destination's Content > Files area
"is redownloaded and duplicated" (the copy lands in
/products/, the original stays in/files/; documented as expected behaviour). - Rate limits on the image fetch: UNVERIFIED. No primary source found stating a per-import image fetch rate limit or concurrency cap.
- Community-reported (not documentation) silent image loss: a 2026-08-07 forum post from a vendor-affiliated CSV-tool account describes images vanishing after an import that reported "Success", attributing it to the background image-ingestion step (https://community.shopify.com/t/396027.json). Treat as unverified anecdote; note that its author advertises a competing tool.
1.8 Collections — NOT in the export. This is a real gap.
Primary source: https://help.shopify.com/en/manual/products/import-export/using-csv.md ("Collection column exception").
- "When you export a CSV file, the
Collectioncolumn isn't included." — collections and membership are absent from the product CSV export. - The only supported CSV route is a hand-added column on import:
- "The
Collectioncolumn is the only column that you can add to the CSV file that doesn't break the format. You can't add any other columns to your CSV file." - Header must be exactly
Collection; it can go anywhere in the file. - "Enter the name of the collection that you want to add this product to."
- "If it's an existing collection that has conditions, then the product needs to meet the conditions for the collection."
- "If the collection doesn't already exist, then a collection is created."
- Hard limit: "You can add a product to only one collection." Value may be blank; max length 255 characters.
- "The
- Consequence for a 16-collection catalogue with products in more than one collection: the CSV can only
express one membership per product. (Multiple rows for the same handle collide with the
handle-uniqueness rule that produces
Ignored line #-## because handle ... already exists— https://help.shopify.com/en/manual/products/import-export/common-import-issues.md.) - Supporting context on the collections model: a new collections model is replacing legacy manual and smart collections; where it is available, previous collections were auto-converted. Collections can be populated by manual inclusion, inclusion conditions, manual exclusion, and exclusion conditions, and can nest. Collections are managed at https://admin.shopify.com/collections. Smart/conditional collections self-populate from conditions, so membership is reproducible by conditions rather than by a file. Source: https://help.shopify.com/en/manual/products/collections.md and https://help.shopify.com/en/manual/products/collections/create-collection.md.
- The only documented bulk membership mechanism for a product in many collections is the admin bulk
editor (https://help.shopify.com/en/manual/shopify-admin/productivity-tools/bulk-editing.md,
reachable from Products → select products → Edit products), or the GraphQL Admin API
(
collectionAddProducts/CollectionInput; collection reference: https://shopify.dev/docs/api/admin-graphql/latest/objects/Collection). There is no documented collection export/import file (no collections CSV in the help centre, and UNVERIFIED whether one exists anywhere in the admin).
1.9 Other things that silently fail or are commonly lost
All from https://help.shopify.com/en/manual/products/import-export/using-csv.md unless noted.
| Field | Round-trip behaviour |
|---|---|
| Status (active/draft/archived) | Status column. "If this column is present, then it needs a value. If the column isn't present, then the product status is automatically uploaded as active." Blank Status with a present column → import error surface (Status requires a value). |
| Published on online store | Published on online store column, true (default) / false, governs only the online store sales channel. |
| Sales-channel publication beyond online store | "CSV files can't be used to bulk update product availability on other sales channels." The import dialog's Publish new products to all sales channels checkbox (default on) is the only channel control, and it applies to new products only — deselect it to publish new products to the online store only (https://help.shopify.com/en/manual/products/import-export/import-products.md). Per-channel availability must be set in the admin or by API. |
| SEO title / SEO description | Both columns exist and round-trip, with a documented caveat: "The SEO Title and SEO Description fields in exported CSV files are only populated when you've manually customized them in your products. If these fields haven't been edited, then they'll be blank in the export. This is expected behavior, as the CSV can only export saved data. When these fields are blank, SEO information is automatically generated based on your product title and description." (https://help.shopify.com/en/manual/products/import-export/export-products.md). Limits: SEO title ≤70 chars, SEO description ≤320 chars (using-csv). On import, blank SEO title → product Title used; blank SEO description → product Description used. |
| Weight | Weight value (grams) (numeric grams only, no unit, no decimals — e.g. 5125 for 5.125 kg) and Weight unit for display (g/kg/lb/oz; default kg). Default value 0 if blank. |
| Inventory quantity | Inventory quantity — "This applies only to Shopify stores that have a single location." Default 0 if blank. For multi-location stores the docs route you to the inventory CSV (https://help.shopify.com/en/manual/inventory-and-locations/setup/inventory-csv) or the Inventory API. |
| Inventory tracker | Inventory tracker = shopify, shipwire, amazon_marketplace_web, or blank if untracked. "If existing inventory tracking options are removed, then inventory is no longer tracked." On export, third-party-fulfilment variants show manual (or gift_card for gift-card variants); Inventory tracker shows shopify when tracking is on and is blank when it isn't (https://help.shopify.com/en/manual/products/import-export/export-products.md). |
| Tolerances | Continue selling when out of stock = deny (default) / continue. Charge tax and Requires shipping are boolean columns. Cost per item exists. |
| Tags | Tags column; max 250 tags/product; comma-separated in one cell, quoted; "Tags aren't case sensitive." |
| Product type | Type column — free-form label, round-trips. |
| Product category | Product category — must match Shopify's Standard Product Taxonomy breadcrumb or ID exactly, else Not a valid product category. |
| Handle | URL handle is the join key for overwrite behaviour; must be unique across the file. Changing it changes the product URL. |
| SKU / barcodes | SKU (required non-blank with a custom fulfilment service) and Variant Barcodes (up to 20, semicolon-separated, optional type: prefix). A file containing both Barcode and Barcodes columns fails to import. |
| Gift cards | Gift card column exists and can bulk-edit details, but "you can't create a gift card by importing a product CSV file." |
| Media | Videos and 3D models are not in the CSV (images only). |
| Dimension columns | Packed product length/width/height + Packed product dimension unit exist. |
| Sorting the CSV in a spreadsheet | Caution: "Sorting your CSV file in a spreadsheet program can cause product variants or image URLs to become disassociated. Importing a CSV file that has been sorted might overwrite your existing products with bad data, which can't be recovered." (export doc) / "Importing a CSV file that has been sorted by a spreadsheet editor such as Microsoft Excel or Apple Numbers might cause your products to be removed from their relevant image links on the CSV, and your product's images will be lost." (import doc). |
| Excel delimiter trap | "If you use Excel to edit your CSV, then check Excel's export settings when you export the CSV to ensure that your file uses commas between values." |
| Backward-compatibility of column names | "If you use an older CSV template, then you might have different column names than the ones that are listed on this page. Shopify maintains backward compatibility with older column names, but you should consider updating to the current format." |
| Overwrite side effects | Blank non-required cell overwrites the destination value as blank; an omitted column leaves the destination value unchanged; including a column whose dependencies are absent deletes/removes data. |
| Import limits | 15 MB file cap; 10,000 new variants/24h for stores with ≥500,000 variants (excluding Plus); can't be cancelled; no import history; review via activity log. |
| Single-location assumption | Both the sample-file note and the Inventory quantity row tie the CSV's quantity field to single-location stores. UNVERIFIED: no doc says what happens to Inventory quantity on import into a multi-location store (the docs only redirect to the inventory CSV / Inventory API). |
Question 2 — New vs legacy customer accounts, from admin UI evidence
2.1 Which system does that UI describe? New customer accounts. (Two independently primary legs.)
The evidence quoted for the merchant's admin page is from the parent task's description: a Sign-in
links toggle, a Customer accounts section with Configurations / Customize and Authentication /
Manage, Self-serve returns (off), Store credit (on), and a URL row with Change domain
showing https://shopify.com/74467967222/account.
Leg A — feature availability. The help centre's own comparison table marks Self-serve returns and Store credit as available in Customer accounts and not available in legacy customer accounts (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade/compare-features.md):
| Feature | Customer accounts (new) | Legacy customer accounts |
|---|---|---|
| Self-serve returns | ✔ | ✘ |
| Store credit | ✔ | ✘ |
| Saved payment methods | ✔ | ✘ |
| Branding source | checkout settings | online store theme settings |
| Customisation model | app blocks in a visual editor | "Requires editing Liquid code" |
| Sign-in | one-time 6-digit email code; optional Shop / Google / Facebook | email + password; separate register page or invite |
The same page: "There are two versions of customer accounts: Customer accounts is the newest version ... Legacy customer accounts lets your customers sign in using an email and a password."
Leg B — the documented admin surface. The help centre documents the new system's settings page as exactly the set of rows on the merchant's screen. "From your Shopify admin, go to Settings > Customer accounts to manage more settings:" — Self-serve returns, Store credit, URL, Social sign-in, Sign in with Shop, Identity provider; plus the Sign-in links section with the Show sign-in links toggle; plus "Configuring apps and branding for customer accounts" pointing at the checkout and accounts editor (https://help.shopify.com/en/manual/customers/customer-accounts/manage.md):
- "In the Sign-in links section, do either of the following: To display sign-in links on your store, toggle on Show sign-in links."
- "Use the checkout and accounts editor to configure brand settings and add more features with apps. You can also customize the experience by market. You can work on your configuration in draft before publishing." — and "Settings > Checkout > Configurations > Customize" is the documented route into that editor (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md, Steps 2–4).
- The Admin GraphQL object mirrors this page field-for-field:
Shop.customerAccountsV2exposescustomerAccountsVersion(CLASSIC|NEW_CUSTOMER_ACCOUNTS),loginLinksVisibleOnStorefrontAndCheckout,loginRequiredAtCheckout, andurl("The root url for the customer accounts pages") (https://shopify.dev/docs/api/admin-graphql/latest/objects/CustomerAccountsV2.md, https://shopify.dev/docs/api/admin-graphql/latest/enums/CustomerAccountsVersion.md).
Contrast with the legacy surface: legacy customisation lives in theme templates, not a settings
page with feature toggles. The upgrade guide has you review "Online Store > ... > Edit theme ... Legacy
customer accounts" and templates/customers Liquid files (customers/account.liquid,
customers/login.liquid, customers/register.liquid), and it describes the new system as "Managed
independently from your theme" (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md).
The official deprecation announcement likewise groups "Legacy customer account liquid templates" as the
legacy artefact (https://community.shopify.dev/t/legacy-customer-accounts-availability-update/31724).
Note on the admin's actual words. The shopify.dev getting-started guide for the Customer Account API
describes an older/alternate settings layout — "Under Accounts in online store and checkout section,
click on Edit. Choose Customer accounts. Click Save" — which does not match the merchant's
row set, and shows that Shopify has more than one wording for this panel
(https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/getting-started.md).
That mismatch is itself a signal that the merchant's panel is the newer layout, but it makes the
"Sign-in links" toggle alone non-diagnostic: the toggle is a new-system control, yet no primary source
was found that says legacy stores cannot also see a sign-in-links row.
UNVERIFIED: whether a store on legacy accounts can see a Sign-in links row in this panel.
2.2 What https://shopify.com/<numeric-id>/account indicates
New customer accounts use shopify.com/<shop-ID>/account by default. Classic/legacy accounts do NOT use
that format — but a legacy store can display it in settings.
New system, verbatim:
- "By default, your customer accounts pages, such as the sign-in page, the orders page, and the profile
page, use a
shopify.comURL format as their base domain, similar toshopify.com/1234567890/accountwith a unique ID number for your store. For example, the sign-in link at the top of your store is something similar toshopify.com/authentication/1234567890/login, and the URL for the main orders page could be similar toshopify.com/1234567890/account/orders. This also includes the Order status page." — https://help.shopify.com/en/manual/customers/customer-accounts/customize-customer-accounts/connect-domain-customer-account.md - "In the Customer accounts section, the URL field displays a preview of the current URL. Click
Change domain." — same page. The merchant's
URLrow with Change domain is this control. - "If you didn't set up a subdomain, then the default format is
https://shopify.com/{your-store-ID}/account." — https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md, Step 8.
The numeric ID is the shop ID: the sibling probe note establishes gid://shopify/Shop/74467967222 for this
store (shopify-cart-probe-2026-10.md), and the merchant's URL is
https://shopify.com/74467967222/account. The number matches.
Legacy system URLs are on the store's own domain. The docs never show a shopify.com/<id>/account
URL for legacy accounts; legacy account pages are customers/* theme templates served on the storefront
(/account, /account/login, etc.), and "Your legacy customer account pages, such as the sign-in page,
keep their existing URLs until you complete the upgrade." — same connect-domain-customer-account page.
The caveat that makes the URL merely strong, not conclusive on its own:
- The upgrade guide has you configure and publish the new customer-accounts configuration, and set a custom subdomain, before the actual cutover: "Your online store and checkout still link to legacy customer accounts until you complete Step 9." The URL in Settings > Customer accounts is therefore populated for stores that are mid-migration and still serving legacy pages to customers (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md).
- "If you're still using legacy customer accounts, then you can set up your subdomain before you upgrade
to the latest version of customer accounts. Setting up your subdomain first means that your customer
account pages use your own domain as soon as you upgrade, instead of a
shopify.comURL." — and "The Order status page is the exception. It uses the new subdomain as soon as you set the subdomain as the primary domain" (https://help.shopify.com/en/manual/customers/customer-accounts/customize-customer-accounts/connect-domain-customer-account.md). - The upgrade guide describes an Upgrade banner button on Settings > Customer accounts for stores that still need to cut over: "Click Upgrade in the banner at the top of the page." (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md, Step 9). The parent's description of the page does not mention an Upgrade banner, which is consistent with an already-upgraded store — but this note did not observe the page directly.
2.3 Grow plan: new customer accounts and the Customer Account API
New customer accounts on Grow: no plan gate was found, and the system is the only one still available.
- The plan gate that is documented for this area is not new customer accounts itself. The only "Plan requirement" aside on the customer-accounts settings page is for Saved payment methods: "Saved payment methods are available only to stores that use Shopify's Enterprise offering, including commerce components, and have customer accounts set up." (https://help.shopify.com/en/manual/customers/customer-accounts/manage.md#saved-payment-methods). Separately, Identity provider is "available only to stores on the Shopify Plus plan" (https://help.shopify.com/en/manual/customers/customer-accounts/sign-in-options/identity-provider.md), and Multipass is Plus-only (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md).
- New customer accounts is what Shopify now pushes everyone to, including new stores: "New stores can only use the latest version of customer accounts." and "As of February 26, 2026, legacy customer accounts are deprecated. They're no longer available to new stores, and existing stores that weren't using them no longer have access." (https://shopify.dev/docs/apps/build/customer-accounts.md, "Product roadmap".)
- UNVERIFIED: no primary source was found stating "new customer accounts requires plan X" in either direction for Grow specifically. The absence of a plan-requirement aside on the manage page is the evidence, not an explicit statement.
Customer Account API on Grow: available and plan-tiered by rate limit, with a documented 402.
- The Customer Account API's requirements are stated as: "You have Apps and channels permissions on the Shopify store that you're working with" and "You have installed the Headless or Hydrogen sales channel from the Shopify App Store." No plan requirement is listed. (https://shopify.dev/docs/storefronts/headless/building-with-the-customer-account-api/getting-started.md, "Requirements".)
- The API reference publishes per-plan rate limits, which is direct evidence the API is meant for sub-Plus plans: Standard limit: 100 points/second, Advanced Shopify limit: 200 points/second, Shopify Plus limit: 200 points/second, Shopify for enterprise (Commerce Components): 400 points/second; quota 7,500 cost points per app, per store and customer; per-customer limit 3,000 requests/minute. (https://shopify.dev/docs/api/customer/latest.md, "Rate limits".) Shopify's current paid tier between "Standard/Basic" and "Plus" is named Grow; UNVERIFIED that "Advanced Shopify" in this list is the same plan as today's "Grow" — the docs do not use the word "Grow" anywhere on the Customer Account API pages.
- The 402 behaviour the parent asked about exists and is documented for this API, in the Customer
Account API reference, both in prose and as a sample response:
402 Payment Required— "The shop is frozen. The shop owner will need to pay the outstanding balance to unfreeze the shop."- and, under "Sample error codes",
402→"errors": "This shop's plan does not have access to this feature". Source: https://shopify.dev/docs/api/customer/latest.md (HTTP status codes + sample error codes). Note the two statements are not perfectly consistent with each other, and neither names a plan.
- A related gate clause appears on the Admin API mutation for the checkout/accounts editor:
"Also: User must have
manage_checkout_settingspermission and shop must have access to the checkout and accounts editor as well as the contextualized checkouts and customer accounts feature." (https://shopify.dev/docs/api/admin-graphql/latest/mutations/checkoutAndAccountsConfigurationUpdate.md). UNVERIFIED which plans satisfy that clause. - Community, not documentation: a 2026-05-12 Shopify developer-forum thread has a participant describing "We are implementing a B2B portal ... using Shopify Grow and New Customer Accounts" (https://community.shopify.dev/t/34164.json). That is a forum user's setup, useful only as an indication that the combination is in use.
2.4 Legacy lifecycle: deprecation date and sunset date
Deprecation date: February 26, 2026. Confirmed by three independent Shopify-owned sources.
- Shopify Changelog (changelog.shopify.com), post dated February 26, 2026, "Legacy customer accounts are deprecated": "Legacy customer accounts are no longer available to new stores and existing stores not using it. Shopify will stop providing feature updates and technical support for this older version. A final sunset date for legacy customer accounts will be announced later in 2026." — https://changelog.shopify.com/posts/legacy-customer-accounts-are-now-deprecated
shopify.dev, Building apps for customer accounts, "Product roadmap": "As of February 26, 2026, legacy customer accounts are deprecated. They're no longer available to new stores, and existing stores that weren't using them no longer have access. All merchants must upgrade to the latest version of customer accounts." — https://shopify.dev/docs/apps/build/customer-accounts.md- Shopify Developer Community announcement by "Ryan ... from the Customer Accounts team", posted 2026-02-26T15:22Z, titled "Legacy customer accounts: Availability update" (https://community.shopify.dev/t/legacy-customer-accounts-availability-update/31724, readable as https://community.shopify.dev/t/31724.json): "Today, legacy customer accounts are deprecated." ... "Starting February 2026, legacy customer accounts are no longer available to new stores and existing stores not using it. Shopify will stop providing feature updates and technical support for this older version." ... "A sunset date for legacy customer accounts will be announced later in 2026." ... "Legacy customer account liquid templates (customers/account.liquid, customers/login.liquid, customers/register.liquid) will eventually be locked from editing, then removed." ... "The Customer Account API is the only primary source for customer-scoped data and authenticated customer actions. The Storefront API customer mutations will be deprecated, with more details coming soon."
Also on the merchant-facing side, every customer-accounts help page now carries the caution: "Legacy
customer accounts are deprecated. Upgrade to the latest version of customer accounts in your Shopify admin
to leverage more secure sign-in, no-code customizations with apps, and features such as store credit and
self-serve returns. You can revert within 30 days."
(https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md,
https://help.shopify.com/en/manual/customers/customer-accounts/upgrade/compare-features.md).
The legacy settings page itself (/manual/customers/customer-accounts/upgrade/legacy-customer-accounts)
was checked repeatedly and no longer resolves to a document — bare URL 403s behind the bot challenge
and .md returns 404 (9 bytes, "Not Found") — i.e. the legacy setup guide has been withdrawn from the
help centre.
Sunset date: still unannounced as of 2026-10-13. Both the changelog post and the developer-community
announcement say a final sunset date "will be announced later in 2026", and neither has been
updated with one as of this note's date. No shopify.dev release note (checked 2026-10, 2026-01),
no shopify.dev changelog entry, and no help-centre page found states a sunset date. The developer-forum
announcement thread carries follow-up questions from merchants on the same day and no date
(https://community.shopify.dev/t/31724.json).
Corroborating community evidence that the announcement is the source of the "no sunset date yet" claim — a 2026-02-27 Shopify Community post quotes "A sunset date for legacy customer accounts will be announced later in 2026" and asks whether final migration will happen during 2026 (https://community.shopify.com/t/590122.json). In the same thread another merchant reports a store-side message: "You can revert to legacy customer accounts until March 25, 2026." (community, unverified, and store-specific). A 2026-03-23 developer-forum post points to the changelog post above (https://community.shopify.dev/t/32549.json).
UNVERIFIED and worth flagging: whether a concrete sunset date has been announced by any channel
outside the three checked (help centre, shopify.dev changelog/release notes, both community forums). No
such date was found in any of them on 2026-10-13.
2.5 Does shopify.com/<id>/account mean no exposure to the legacy sunset?
Merely strongly indicated — not certain.
What is certain (documented):
shopify.com/<store-ID>/accountis the new customer accounts URL format, and its presence in Settings > Customer accounts > URL with a Change domain button is the documented UI for the new system's account domain (https://help.shopify.com/en/manual/customers/customer-accounts/customize-customer-accounts/connect-domain-customer-account.md).- Legacy customer accounts are the only system being sunset; the new system is the migration target (https://changelog.shopify.com/posts/legacy-customer-accounts-are-now-deprecated).
- Legacy customisation artefacts are theme templates and legacy URL paths, which are not what that panel describes; new customer accounts is "Managed independently from your theme" (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md).
- The Admin GraphQL object backing that panel exposes
customerAccountsVersionwith an explicitCLASSIC/NEW_CUSTOMER_ACCOUNTSdiscriminator — the only machine-checkable answer (https://shopify.dev/docs/api/admin-graphql/latest/enums/CustomerAccountsVersion.md).
Why it is not certain, in the docs' own words:
- The URL can be populated before the cutover. Stores that are still on legacy accounts can configure and publish a new accounts experience, and set a subdomain, in advance: "Your online store and checkout still link to legacy customer accounts until you complete Step 9." The URL field is described as showing "the current URL" — during a migration that can be the not-yet-live new URL (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md, https://help.shopify.com/en/manual/customers/customer-accounts/customize-customer-accounts/connect-domain-customer-account.md).
- The definitive marker of a not-yet-cut-over store is the presence of an
Upgradebanner, and the URL field is explicitly one of the things you copy before upgrading: "To test the new customer accounts experience before completing the upgrade, copy your new customer accounts URL..." (same upgrade page, Steps 8 and 9). If a store can revert "within 30 days", it must also be able to show this page while still serving legacy pages. - No primary source states "a shopify.com//account URL is only shown by stores already on new customer accounts." The inference is from the two facts above plus the absence of an Upgrade-banner mention in the observed UI — strongly indicated, not proven.
The two clean, documented checks to settle it (facts, not recommendations):
- Read Settings > Customer accounts for the Upgrade banner and button; its absence is the documented signal that Step 9 is done (https://help.shopify.com/en/manual/customers/customer-accounts/upgrade.md#step-9).
- Query the Admin GraphQL field
Shop.customerAccountsV2 { customerAccountsVersion }and readNEW_CUSTOMER_ACCOUNTSvsCLASSIC(https://shopify.dev/docs/api/admin-graphql/latest/objects/CustomerAccountsV2.md, https://shopify.dev/docs/api/admin-graphql/latest/enums/CustomerAccountsVersion.md).
3. Verification notes and gaps
Method: all shopify.dev and help.shopify.com pages cited above were fetched 2026-10-13 as raw
Markdown by appending .md; help.shopify.com bare URLs return 403 (bot challenge) and .md returns
200 — see §0.
Explicitly UNVERIFIED in this note:
- Metafield values whose definition does not exist in the destination store. The CSV page only promises columns for defined metafields. Whether an undefined metafield's value is exported, imported, or silently dropped is not documented anywhere found.
- What an export writes into
Option1 valuefor a one-variant product whose option name isTitle(the merchant's exact shape). The docs and the official sample CSV disagree on naming — see §1.5. Only the merchant's own export file settles it. - Export filename (never named) and whether "All products" exports are always emailed (documented as emailed, no size threshold given).
- The import "review" screen's contents — no doc calls it a preview, validation report, or dry run.
- Whether import processing continues after the admin tab closes, and the exact progress surface (docs mention only a confirmation email and the activity log).
- Image fetch rate limits / concurrency caps during import.
Inventory quantitybehaviour into a multi-location store (docs only redirect to the inventory CSV / Inventory API).- Whether a collections CSV export/import exists anywhere in the admin — none is documented; the
product CSV explicitly excludes the
Collectioncolumn and caps import to one collection per product. PublishedvsPublished on online storecolumn naming: the current docs and the official sample usePublished on online store; the legacy header list published in the help centre's troubleshooting article usesPublishedandHandle/Body (HTML)/Image Src. Whether a current export ever writes the legacy names is not stated.- Plan gating of new customer accounts — no primary source says which plans may use it; only adjacent gates were found (Saved payment methods = Enterprise; Identity provider and Multipass = Plus).
- Whether "Advanced Shopify" in the Customer Account API rate-limit table = today's "Grow" plan.
- Whether a legacy-accounts store can see a "Sign-in links" row on the settings panel.
- Any sunset date for legacy customer accounts. As of 2026-10-13 the only statement found is "will be announced later in 2026".
- Metaobject definitions/entries travelling with a product CSV — only reference identifiers are documented, which is not the same thing.
Primary sources consulted (all Shopify-owned):
Community sources used only as labelled corroboration (never as sole support):
https://community.shopify.dev/t/34164.json (Grow + new customer accounts, forum user),
https://community.shopify.com/t/590122.json (sunset-date question, 2026-02-27),
https://community.shopify.com/t/214856.json (staff-authored forum article on Title/Default Title),
https://community.shopify.com/t/396027.json (vendor-affiliated report of silent image loss),
https://community.shopify.dev/t/32549.json (points at the changelog post),
https://community.shopify.com/t/686939.json (category-metafield columns, 2026-09-24).