Skip to main content
POST
Create or Upsert Metafield

Create or Upsert Metafield

This endpoint upserts: if a metafield with the same (ownerType, namespace, key, ownerId) already exists for your app, the value is updated; otherwise a new metafield is created. There is always at most one metafield per (resource, namespace, key) per app.

Request

Required scope

write_metafields

Body parameters

string
required
Namespace. Use your app handle (e.g. subscriptions_pro) — custom is the merchant-managed namespace.
string
required
Field key. Unique per (ownerType, namespace, ownerId).
string
The OAuth App API accepts a 21-value subset of the type catalogue: string, integer, json, boolean, color, date, date_time, dimension, file_reference, json_string, money, multi_line_text_field, number_decimal, number_integer, product_reference, rating, rich_text_field, single_line_text_field, url, volume, weight. It has no list.* variants, and among references only product_reference and file_reference (not collection_reference, variant_reference, customer_reference, or page_reference). An unsupported type is rejected with HTTP 422. The full 22-type catalogue and list.* are available only on the Admin API. Stored verbatim and used by the storefront when decoding/rendering the value. If omitted, type defaults to string.
any
required
The value. Scalars are sent as-is (string, number, boolean). Compound types (weight, dimension, volume, money, rating, lists, JSON) are sent as JSON.An empty string is rejected with 422. To represent “nothing selected”, either delete the metafield or store an explicit sentinel (e.g. "*" for “all”). Writing "" is the common way apps break a “select none / select everything” toggle — the save silently fails while the UI shows the new state.
string
required
One of shop, product, variant, collection, customer, order, page, blog, article, cart. Lowercase only.
string
required
The id of the owning resource. Required for every owner type except shop.

Examples by type

Scalar text

Number

Boolean

Rich text (HTML, rendered unescaped in Aqua)

Measurement

Money

Reference

The App API supports only product_reference and file_reference. Other reference types (collection_reference, variant_reference, customer_reference, page_reference) are Admin API only and are rejected by the OAuth App API with 422.

List (Admin API only)

list.* types are not supported by the OAuth App API — an App API request with type: "list.single_line_text_field" is rejected with 422. Lists are available only on the Admin API:

JSON (free-form structured data)

Response

The response is the standard envelope. On success the created/updated metafield is returned under data.metafield.
integer
201 if created, 200 if updated.
string
success or error.
string
Human-readable message, or null on success.
object
The created or updated metafield row. value is returned as the stored string form (scalars stringified, compound types JSON-encoded). See List Metafields for shape.

Example response

The type name is validated against the App API enum: an unsupported type (e.g. any list.*, collection_reference, variant_reference, customer_reference, page_reference) is rejected with HTTP 422. Only the value-vs-type validation is skipped on this OAuth App API path — values are stored as provided, so it is your app’s responsibility to send a well-formed value for the declared type. A missing required field (namespace, key, value, ownerType, ownerId) still returns 400.

Cache invalidation

A successful upsert automatically expires the cached copy of the owning resource and any cached page HTML that rendered it. The next storefront render sees the new value.

Error codes