Metafields
Metafields let you attach typed, namespaced data to nine resource kinds — products, variants, collections, customers, orders, pages, blogs, articles, and the shop itself. They are strongly-typed, server-validated, stored in a separate polymorphic table, and exposed in Aqua/Liquid via the standard{owner}.metafields.{namespace}.{key} access pattern.
Use them to:
- attach app-specific data to a customer, order, or product (e.g. loyalty tier, subscription status, AI-generated badge text)
- expose structured fields to merchants under Settings → Custom data that they can fill in per resource and reference in their theme
- store references between resources (
product_reference,collection_reference,file_reference) so themes can link related items
Apps store all per-store runtime data here. The platform does not give
apps a filesystem to write to — install config, feature toggles, per-resource
counters, event logs, etc. all live as metafields under an
app_<handle_with_underscores> namespace. See
Where to store app data in the
Extensions overview for the conventions.Two API contexts
Metafields are exposed through two parallel REST surfaces with different auth and capabilities.
Apps see and edit only the metafields they wrote (scoped by
appId). The
Admin API is what powers the admin’s Settings → Custom data and the
inline editor on resource detail pages — apps cannot use it.
Owner types (nine)
TheownerType field on every metafield identifies the kind of resource it
attaches to. Validation is case-sensitive lowercase — sending "PRODUCT"
returns a validation error.
Supported types (22)
Each metafield carries atype that determines validation, decoding, and
how it renders in Aqua/Liquid.
The full 22-type catalogue below — including
list.* and all six reference
types — is the Admin / merchant API. The OAuth App API
(/api/v1/...) accepts only a 21-value subset: no list.* variants,
and references are limited to product_reference and file_reference
(not collection_reference, variant_reference, customer_reference, or
page_reference). An App API write with an unsupported type is rejected
with HTTP 422. See Create / Upsert
Metafield for the exact
App API enum.Text
Numeric / Boolean / Color
Date / Time
Measurements
Stored as{ unit, value } objects. Renders as "<value> <unit>".
Money / Rating
URL / JSON
References
Stored as id strings; the backend optionally verifies the id exists at write time.product_reference, variant_reference, collection_reference,
customer_reference, page_reference, file_reference
Lists
list.<innerType> — array of items of innerType. Inner-type validations
apply to each item.
Wire format
Compound types are sent as JSON in thevalue field:
Validation errors
Type or validation failures return HTTP 400 with a structurederrors array:
Cache invalidation
Writes to a metafield automatically expire the relevant storefront caches — both the cached copy of the owning resource and any cached page HTML that rendered it. The next storefront render will see the new value. You don’t need to poll — if you need to react to changes, register ametafields/update
webhook instead.
Best practices for apps
- Use your own namespace. Don’t write under
custom(the merchant namespace). Use your app handle (e.g.subscriptions_pro,loyalty_engine) so merchants can see what’s yours and apps don’t collide on key names. - Pre-create definitions during app install. Apps can
POST /metafield-definitions(with merchant scope, not OAuth) on first install if you want the schema to appear in the merchant admin. For OAuth-only apps, write values directly without defining first. - Pin definitions that merchants need to fill in — they show up on the resource detail page in admin.
- Don’t poll. Use webhooks.