Write metafields with metafieldsSet

Create or update up to 25 metafields on any resource in one atomic call with metafieldsSet, with compareDigest to avoid overwriting newer values.

API
Admin GraphQL API
Operation
metafieldsSet
Access scope
Write access to the owner resource, such as products or customers
Replaces (REST)
POST /admin/api/products/{id}/metafields.json and PUT /admin/api/metafields/{id}.json
API version
2026-10
Last checked

In short

To write metafields, call the metafieldsSet mutation with a list of inputs: ownerId, namespace, key, type and value. It creates the metafield if it doesn’t exist and updates it if it does. One call takes up to 25 metafields across any owners and is atomic: if one fails, none are saved. Pass compareDigest to update only when the stored value hasn’t changed.

How to use it

  1. Build one input per value: ownerId (any resource with metafields), namespace, key, type and value. The value is always a string, also for JSON, numbers and lists.
  2. If a metafield definition exists for that namespace and key, you can leave out type; otherwise it’s required.
  3. Send SetProductMetafields and check userErrors; nothing is saved when it isn’t empty.
  4. For safe updates, read compareDigest first and send it back. Send compareDigest: null to write only if the metafield doesn’t exist yet.

Code

metafields-set.graphql
mutation SetProductMetafields($metafields: [MetafieldsSetInput!]!) {
  metafieldsSet(metafields: $metafields) {
    metafields {
      id
      namespace
      key
      type
      value
      compareDigest
    }
    userErrors {
      code
      field
      message
    }
  }
}
metafields-set.variables.json
{
  "metafields": [
    {
      "ownerId": "gid://shopify/Product/1234567890",
      "namespace": "custom",
      "key": "material",
      "type": "single_line_text_field",
      "value": "100% linen"
    },
    {
      "ownerId": "gid://shopify/Product/1234567890",
      "namespace": "custom",
      "key": "care_guide",
      "type": "multi_line_text_field",
      "value": "Wash at 30°C.\nDo not tumble dry.",
      "compareDigest": null
    }
  ]
}
metafields-set.response.json
{
  "data": {
    "metafieldsSet": {
      "metafields": [
        {
          "id": "gid://shopify/Metafield/1111111111",
          "namespace": "custom",
          "key": "material",
          "type": "single_line_text_field",
          "value": "100% linen",
          "compareDigest": "<digest from the response>"
        },
        {
          "id": "gid://shopify/Metafield/1111111112",
          "namespace": "custom",
          "key": "care_guide",
          "type": "multi_line_text_field",
          "value": "Wash at 30°C.\nDo not tumble dry.",
          "compareDigest": "<digest from the response>"
        }
      ],
      "userErrors": []
    }
  }
}

Written by Lintel. MIT license: free to use in your own store and in client work.

Limits and edge cases

  • At most 25 metafields per call and a 10 MB request.
  • Leaving out namespace uses your app’s reserved namespace, not custom.
  • Values must match the type: list types take a JSON array as a string, references take GIDs, and the request fails when one doesn’t parse.
  • To remove a metafield, use the metafieldsDelete mutation.

Questions

How do I update a product metafield with GraphQL?
Call metafieldsSet with the product’s GID as ownerId, plus namespace, key, type and the new value. It updates the existing metafield in place.
Can I set metafields on different products in one call?
Yes. Each input has its own ownerId, so one call can write up to 25 metafields across many resources.
What is compareDigest for?
It stops you from overwriting a value someone else changed after you read it. If the stored value no longer matches the digest, the mutation returns an error instead of saving.
  • Validated against the Admin or Storefront API schema for version 2026-10 on the date shown. Check the version in your request URL.
  • IDs and store addresses in the examples are placeholders. Replace them with your own.
  • Admin API calls need an access token from your app. Never put an Admin API token in a storefront or theme.
  • MIT license. Use the code in your own store or in client work.

Need this built, tested and maintained for your store? See API integrations.

Have something to build? Let’s talk it through.

Taking a limited number of projects at a time. Every brief is read by an engineer, not a salesperson.

Gencer KarakayaShopify Engineer

An engineer reads your brief, and we reply by email.