Metafield values

One row sets one metafield value on one resource that already exists. This is the import that fills in the fields — care guides on products, reading times on articles, a motto on the shop itself.

This import never creates resources

The product, page, collection or article you're tagging has to exist first. ImportKit does not create products. If a row's owner can't be found, that row errors and the rest of the file continues.

A worked example

metafield-values.csv
owner_type,owner_reference,namespace,key,value
PRODUCT,merino-crew-neck,custom,care_guide,"Hand wash cold. Lay flat to dry."
PRODUCT,linen-shirt,custom,highlights,"Breathable, Pre-washed, Recycled buttons"
PRODUCTVARIANT,sku:LIN-SHIRT-M,custom,fit_note,Runs slightly large
SHOP,,custom,store_motto,Built to last

Four values on four different kinds of owner: two products by handle, a variant by SKU, and the shop itself. Four rows, four credits.

Note there's no type column. That's fine as long as a metafield definition already exists for each owner type, namespace and key — see the type column.

Columns

These columns use snake_case, unlike the definition importers. The template and column guide will always tell you the current names.

ColumnWhat it controlsExample
owner_type Required The resource this metafield attaches to. See owner types. PRODUCT
owner_reference Usually required Identifies which resource. Accepted formats depend on the owner type — see referencing the owner. Leave blank only for SHOP. merino-crew-neck
key Required The metafield's key within its namespace. care_guide
value Required What to store. list.* types accept a comma- or newline-separated cell or a JSON array; rich_text_field accepts plain text, HTML or Shopify rich text JSON. All value formats → Hand wash cold
namespace Groups related metafields. Defaults to custom when blank. Must match an existing definition's namespace if one exists. custom
type Only needed when no definition exists yet for this owner type, namespace and key. See below. single_line_text_field

The type column, and when you need it

Shopify needs to know a metafield's type. If a definition already exists for that owner type, namespace and key, ImportKit reads the type from it and you can leave the column out entirely. If no definition exists, Shopify has nothing to infer from and the row fails with:

error
No metafield definition exists yet for PRODUCT custom.store_motto,
and no type column was given.

Two ways to fix it, and the first is usually better:

  1. Import the definition first using metafield definitions. You get a proper field with a name, a description, validations and a pin in the admin.
  2. Add a type column to your values file. The metafield gets created without a definition — it works, and your theme can read it, but it won't appear as a labelled field in the admin editor.
Mixing is fine

You can include a type column and leave it blank on rows that don't need it. Blank cells are skipped, so those rows use the existing definition's type as usual.

Owner types

You can set metafield values on these seven owner types:

Owner typeNotes
PRODUCTThe most common by far.
PRODUCTVARIANTSpelled with no underscore. PRODUCT_VARIANT and VARIANT are accepted and normalised.
COLLECTIONBoth manual and automated collections.
PAGEOnline Store pages.
ARTICLEBlog articles.
BLOGThe blog itself, not its articles.
SHOPStore-wide values. Leave owner_reference blank — there's only one shop.
Customers and orders are out of reach

ImportKit doesn't request the customer or order permissions, so CUSTOMER and ORDER metafields can't be written. A row targeting one is reported like this, and the rest of the file still imports:

CUSTOMER metafields need the "write_customers" access scope, which this app hasn't been granted.

The owner type dropdown on the mapping step lists only the owner types your store's granted permissions cover, so you'll see this constraint before you build a file around it. Full permissions reference →

Referencing the owner

What you can put in owner_reference depends on the owner type, and the differences aren't arbitrary — handle lookups exist only where Shopify provides a query that accepts one.

Owner typeAccepted referenceExamples
PRODUCT Numeric ID, GID, or handle merino-crew-neck
8123456789
gid://shopify/Product/8123456789
PRODUCTVARIANT Numeric ID, GID, or sku: prefix sku:LIN-SHIRT-M
gid://shopify/ProductVariant/45123
COLLECTION Numeric ID, GID, or handle summer-essentials
PAGE, ARTICLE, BLOG Numeric ID or GID only gid://shopify/Article/5566778899
SHOP Leave blank (empty cell)

Why pages, articles and blogs need IDs

Shopify's Admin API has no documented lookup that turns a page, article or blog handle into an ID. Rather than guessing, ImportKit rejects a handle up front with a message telling you to use the numeric ID. You can get IDs from the URL in the Shopify admin: the last number in /admin/pages/123456789 is the page's ID.

SKU lookups

sku: is convenient, but SKUs aren't guaranteed unique in Shopify. If two variants share one you'll get:

error
More than one product variant has SKU "LIN-SHIRT-M" — use its ID or gid instead

Deliberately an error rather than a guess, since the wrong variant is worse than no variant.

A GID that doesn't match the owner type

Paste a customer GID into a row that says PRODUCT and ImportKit catches it before the write:

error
owner_reference "gid://shopify/Customer/1" is not a PRODUCT

This is the guard that stops a mis-sorted spreadsheet writing metafields onto the wrong resources.

Value formats

Values are converted based on the metafield's type, taken from the existing definition or your type column. The short version:

The full value format reference →

Shopify limits how large a value can be

Most metafield types cap at 64 KB per value — bytes, not characters — and any list.* value at 128 items. The pre-import check measures both against the value as it will actually be sent, so an over-long value is reported as a row error before anything is written. Shopify's limits →

Re-importing values that already exist

A value is identified by owner_type + owner_reference + namespace + key. The pre-import check compares against the value currently in your store and shows what it is, which makes it genuinely useful before a bulk update:

ModeResultCharged
Skip (default)Reports the current value and leaves it alone.No
UpdateOverwrites it. The check shows you the value that would be replaced.Yes
FailReported as a conflict.No

A full walkthrough of a bulk update →

Screenshot

Pre-import check on a values file

Check results for metafield values in Skip mode, where a couple of rows show the existing value that would be left in place. Include one scope-blocked CUSTOMER row to show the per-row permission error.

assets/screenshots/check-metafield-values.png

Common patterns

Several metafields on the same product

One row per value, repeating the owner reference:

multiple-values.csv
owner_type,owner_reference,namespace,key,value
PRODUCT,merino-crew-neck,custom,care_guide,Hand wash cold
PRODUCT,merino-crew-neck,custom,fabric,100% merino wool
PRODUCT,merino-crew-neck,custom,country_of_origin,Portugal

Reshaping a wide export into rows

Exports usually have one row per product and one column per field. ImportKit needs one row per value. In a spreadsheet, the quickest route is to build one block per field and stack them: copy the handle column, add a constant key column, and paste the values. Repeat for each field, then concatenate the blocks into one sheet.

Store-wide values

shop-values.csv
owner_type,owner_reference,namespace,key,value,type
SHOP,,custom,store_motto,Built to last,single_line_text_field
SHOP,,custom,support_hours,"Mon-Fri, 9am-5pm CET",single_line_text_field

Next