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.
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
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.
| Column | What it controls | Example |
|---|---|---|
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:
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:
- Import the definition first using metafield definitions. You get a proper field with a name, a description, validations and a pin in the admin.
-
Add a
typecolumn 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.
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 type | Notes |
|---|---|
PRODUCT | The most common by far. |
PRODUCTVARIANT | Spelled with no underscore. PRODUCT_VARIANT and VARIANT are accepted and normalised. |
COLLECTION | Both manual and automated collections. |
PAGE | Online Store pages. |
ARTICLE | Blog articles. |
BLOG | The blog itself, not its articles. |
SHOP | Store-wide values. Leave owner_reference blank — there's only one shop. |
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 type | Accepted reference | Examples |
|---|---|---|
PRODUCT |
Numeric ID, GID, or handle | merino-crew-neck8123456789gid://shopify/Product/8123456789 |
PRODUCTVARIANT |
Numeric ID, GID, or sku: prefix |
sku:LIN-SHIRT-Mgid://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:
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:
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:
-
Lists.
"Breathable, Pre-washed, Recycled"becomes a three-item array. If the cell contains line breaks, newlines become the separator instead, so items can contain commas. - Rich text. Plain text, HTML or Shopify's own rich text JSON are all accepted and converted appropriately.
-
Structured types.
money,rating,weight,dimensionandvolumetake a small JSON object. Quote the cell. - Blank cells write nothing. You can't clear a value by emptying the cell.
The full value format reference →
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:
| Mode | Result | Charged |
|---|---|---|
| Skip (default) | Reports the current value and leaves it alone. | No |
| Update | Overwrites it. The check shows you the value that would be replaced. | Yes |
| Fail | Reported as a conflict. | No |
A full walkthrough of a bulk update →
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:
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
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