--- title: Update product data description: 'Learn how to edit products, variants, and options using the GraphQL Admin API.' source_url: html: >- https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data md: >- https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md --- ExpandOn this page * [Requirements](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#requirements) * [How it works](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#how-it-works) * [Step 1: Retrieve product data](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-1-retrieve-product-data) * [Step 2: Update product information](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-2-update-product-information) * [Step 3: Manage product options](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-3-manage-product-options) * [Step 4: Update product variants](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-4-update-product-variants) * [Step 5: Clean up unused option values](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-5-clean-up-unused-option-values) * [Next steps](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#next-steps) # Update product data Use the GraphQL Admin API to update existing products, including their variants and options. The API provides granular control over updates, allowing you to modify only the specific fields or entities that need to change without affecting the rest of the product data. Note If your app syncs product data from an external source, use the [`productSet`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productSet) mutation to update data in a single operation. Learn more about [syncing product data](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/sync-data). *** ## Requirements * Your app can make [authenticated requests](https://shopify.dev/docs/api/admin-graphql#authentication) to the latest version of the GraphQL Admin API or higher. * Your app has the `write_products` [access scope](https://shopify.dev/docs/api/usage/access-scopes). Learn how to [configure your access scopes using Shopify CLI](https://shopify.dev/docs/apps/build/cli-for-apps/app-configuration). * You understand how [products, variants, and options](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections) work in the GraphQL Admin API. * You've created products with variants that you want to update. If you need to create products first, refer to [Add product data](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data). *** ## How it works The GraphQL Admin API provides separate, targeted mutations for updating different parts of a product: * Use [`productUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productUpdate) to modify product-level fields like title or tags. * Use dedicated option mutations to [add](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionsCreate), [rename](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionUpdate), [reorder](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionsReorder), or [remove](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionsDelete) product options. * Use bulk variant mutations to [update](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkUpdate), [delete](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkDelete), or [reorder](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkReorder) multiple variants at once. Each mutation modifies only what you specify, and everything else remains unchanged. This separation gives you precise control. For example, you can update the price on 50 specific variants without touching the other variants, or rename an option without affecting any variant data. *** ## Step 1: Retrieve product data To get the IDs you'll need for update operations, query the product first. The following example shows how to retrieve a product with its options, option values, and variants. The response includes IDs for the product, options, option values, and variants that you'll use in subsequent update steps. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL query ```graphql query GetProduct { product(id: "gid://shopify/Product/456") { id title options { # Get option IDs for renaming, reordering, or deleting. id name position optionValues { # Get option value IDs for updates or cleanup. id name hasVariants } } variants(first: 2048) { edges { node { # Get variant IDs for updates, deletes, or reordering. id title price selectedOptions { name value } } } } } } ``` ## JSON response ```json { "data": { "product": { "id": "gid://shopify/Product/456", "title": "My Cool Socks", "options": [ { "id": "gid://shopify/ProductOption/101", "name": "Color", "position": 1, "optionValues": [ { "id": "gid://shopify/ProductOptionValue/1", "name": "Red", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/2", "name": "Green", "hasVariants": true } ] }, { "id": "gid://shopify/ProductOption/102", "name": "Size", "position": 2, "optionValues": [ { "id": "gid://shopify/ProductOptionValue/4", "name": "Small", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/5", "name": "Medium", "hasVariants": true } ] } ], "variants": { "edges": [ { "node": { "id": "gid://shopify/ProductVariant/101", "title": "Red / Small", "price": "4.99", "selectedOptions": [ { "name": "Color", "value": "Red" }, { "name": "Size", "value": "Small" } ] } }, { "node": { "id": "gid://shopify/ProductVariant/102", "title": "Green / Medium", "price": "4.99", "selectedOptions": [ { "name": "Color", "value": "Green" }, { "name": "Size", "value": "Medium" } ] } } ] } } } } ``` *** ## Step 2: Update product information To update product-level fields without affecting variants or options, use [`productUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productUpdate). The following example shows how to change a product's title from "My Cool Socks" to "My Extra Cool Socks". Only the `title` field is modified, and all other product data remains unchanged. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation UpdateProduct { productUpdate(product: { id: "gid://shopify/Product/456", # Only the title field is updated. # All other fields, options, and variants remain unchanged. title: "My Extra Cool Socks" }) { product { id title } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productUpdate": { "product": { "id": "gid://shopify/Product/456", "title": "My Extra Cool Socks" }, "userErrors": [] } } } ``` *** ## Step 3: Manage product options Options can be managed independently of the product and its variants, giving you control over how products are structured. ### 3.​1 Add a new option To expand a product's characteristics, use [`productOptionsCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionsCreate). The following example shows how to add a `Material` option with two values (`Cotton` and `Wool`) to the product. When you create a new option, all existing variants are automatically updated to include the first value. In this example, all nine variants will get `Material: Cotton` added to their option combinations, while `Wool` becomes unused (`hasVariants: false`) until you assign it to variants. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation CreateProductOption { productOptionsCreate( productId: "gid://shopify/Product/456", options: [ { name: "Material", values: [ # First value: all existing variants are automatically updated to use this. { name: "Cotton" }, # Second value: becomes unused (hasVariants: false) until you assign it. { name: "Wool" } ] } ] ) { product { options { id name optionValues { id name hasVariants } } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productOptionsCreate": { "product": { "options": [ { "id": "gid://shopify/ProductOption/101", "name": "Color", "optionValues": [ { "id": "gid://shopify/ProductOptionValue/1", "name": "Red", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/2", "name": "Green", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/3", "name": "Blue", "hasVariants": true } ] }, { "id": "gid://shopify/ProductOption/102", "name": "Size", "optionValues": [ { "id": "gid://shopify/ProductOptionValue/4", "name": "Small", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/5", "name": "Medium", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/6", "name": "Large", "hasVariants": true } ] }, { "id": "gid://shopify/ProductOption/103", "name": "Material", "optionValues": [ { "id": "gid://shopify/ProductOptionValue/7", "name": "Cotton", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/8", "name": "Wool", "hasVariants": false } ] } ] }, "userErrors": [] } } } ``` ### 3.​2 Update an option To modify an option's properties, use [`productOptionUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionUpdate). The following example shows how to rename the `Material` option to `Fabric` and move it to position 1. The option ID remains the same. Only its name and position change, and all variants that used `Material` now display `Fabric` instead. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation UpdateOptionNameAndPosition { productOptionUpdate( productId: "gid://shopify/Product/456", option: { # The ID of the option you're modifying (Material option). id: "gid://shopify/ProductOption/102", # Rename the option from "Material" to "Fabric". name: "Fabric", # Move to position 1 (first position, displays before other options). position: 1 } ) { product { options { id name position } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productOptionUpdate": { "product": { "options": [ { "id": "gid://shopify/ProductOption/102", "name": "Fabric", "position": 1 }, { "id": "gid://shopify/ProductOption/101", "name": "Color", "position": 2 } ] }, "userErrors": [] } } } ``` ### 3.​3 Reorder options To change the display order of options and their values, use [`productOptionsReorder`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionsReorder). The following example shows how to reorder both options and their values in a single operation. This mutation moves `Color` to position 1, reorders the color values to display `Blue`, `Red`, `Green`, and moves `Fabric` to position 2 with `Wool` before `Cotton`. Variant titles automatically update to reflect the new order. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation ReorderOptionsAndValues { productOptionsReorder( productId: "gid://shopify/Product/456", # The order in this array determines the new option positions. options: [ { # Color moves to position 1 (first). name: "Color", # The order of values here determines how they display. values: [ { name: "Blue" }, { name: "Red" }, { name: "Green" } ] }, { # Fabric moves to position 2 (second). name: "Fabric", # Reordering values to show Wool before Cotton. values: [ { name: "Wool" }, { name: "Cotton" } ] } ] ) { product { options { id name position optionValues { id name } } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productOptionsReorder": { "product": { "options": [ { "id": "gid://shopify/ProductOption/101", "name": "Color", "position": 1, "optionValues": [ { "id": "gid://shopify/ProductOptionValue/3", "name": "Blue" }, { "id": "gid://shopify/ProductOptionValue/1", "name": "Red" }, { "id": "gid://shopify/ProductOptionValue/2", "name": "Green" } ] }, { "id": "gid://shopify/ProductOption/102", "name": "Fabric", "position": 2, "optionValues": [ { "id": "gid://shopify/ProductOptionValue/8", "name": "Wool" }, { "id": "gid://shopify/ProductOptionValue/7", "name": "Cotton" } ] } ] }, "userErrors": [] } } } ``` ### 3.​4 Delete an option To remove an option and automatically resolve duplicate variant combinations, use [`productOptionsDelete`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionsDelete) with the `POSITION` strategy. The following example shows how to delete the `Size` option. The API keeps lower-positioned variants and deletes higher-positioned ones. For example, if you have `Red / Small`, `Red / Medium`, and `Red / Large`, the API keeps `Red / Small` (position 0) and deletes the others, resulting in one variant for each color. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation DeleteOptionsFromProduct { productOptionsDelete( productId: "gid://shopify/Product/456", # Array of option IDs to delete. In this case, the Size option. options: ["gid://shopify/ProductOption/102"], # POSITION strategy keeps lower-positioned variants and deletes higher ones. # This automatically resolves duplicate variant combinations. strategy: POSITION ) { product { options { id name position } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productOptionsDelete": { "product": { "options": [ { "id": "gid://shopify/ProductOption/102", "name": "Fabric", "position": 1 }, { "id": "gid://shopify/ProductOption/101", "name": "Color", "position": 2 } ] }, "userErrors": [] } } } ``` *** ## Step 4: Update product variants Bulk variant mutations let you efficiently update, delete, or reorder multiple variants at once, specifying only what you're changing. ### 4.​1 Update variant fields To modify specific fields on variants, use [`productVariantsBulkUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkUpdate). The following example shows how to update a variant's price from $4.99 to $9.99 and change its `Material` option from `Cotton` to `Wool`. This mutation modifies only the specified variant (`gid://shopify/ProductVariant/102`) using the option value ID for precision. All other variants remain unchanged. You can update up to 250 variants in a single operation. Tip You can reference option values by either their ID or by name: `{ "name": "Wool", "optionName": "Fabric" }` ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation UpdateVariants { productVariantsBulkUpdate( productId: "gid://shopify/Product/456", variants: [ { # The ID of the specific variant you want to update. id: "gid://shopify/ProductVariant/102", # Update the price to $9.99. price: 9.99, # Change the variant's option values. optionValues: [ { # Reference the option by ID (Material option). optionId: "gid://shopify/ProductOption/103", # Reference the specific option value by ID (Wool). id: "gid://shopify/ProductOptionValue/8" } ] } ] ) { productVariants { id title price selectedOptions { name value } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productVariantsBulkUpdate": { "productVariants": [ { "id": "gid://shopify/ProductVariant/102", "title": "Wool / Green", "price": "9.99", "selectedOptions": [ { "name": "Fabric", "value": "Wool" }, { "name": "Color", "value": "Green" } ] } ], "userErrors": [] } } } ``` ### 4.​2 Delete variants To remove variants you no longer need, use [`productVariantsBulkDelete`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkDelete). The following example shows how to delete two specific variants from the product. If these were the only variants using certain option values, those values will become unused (`hasVariants: false`). You can keep them for future use or remove them in [Step 5](#step-5-clean-up-unused-option-values). ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation DeleteVariants { productVariantsBulkDelete( productId: "gid://shopify/Product/456", # Array of variant IDs to permanently delete. variantsIds: [ "gid://shopify/ProductVariant/107", "gid://shopify/ProductVariant/108" ] ) { product { id variants(first: 10) { nodes { id title } } } userErrors { field message code } } } ``` ## JSON response ```json { "data": { "productVariantsBulkDelete": { "product": { "id": "gid://shopify/Product/456", "variants": { "nodes": [ { "id": "gid://shopify/ProductVariant/101", "title": "Red / Small" }, { "id": "gid://shopify/ProductVariant/102", "title": "Wool / Green" } ] } }, "userErrors": [] } } } ``` ### 4.​3 Reorder variants To change the display order of variants, use [`productVariantsBulkReorder`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkReorder). The following example shows how to move two variants to new positions. You only specify the variants whose positions are changing, and the API automatically adjusts the others. The order affects how variants appear in the Shopify admin and on storefronts (depending on theme). ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation ReorderVariants { productVariantsBulkReorder( productId: "gid://shopify/Product/456", # Only include variants whose positions are changing. # The API automatically adjusts other variants. positions: [ { id: "gid://shopify/ProductVariant/102", # Move this variant to position 0 (first). position: 0 }, { id: "gid://shopify/ProductVariant/101", # Move this variant to position 5 (sixth). position: 5 } ] ) { product { id } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productVariantsBulkReorder": { "product": { "id": "gid://shopify/Product/456" }, "userErrors": [] } } } ``` *** ## Step 5: Clean up unused option values When you delete variants or add new options, some option values might become unused. These values exist but aren't assigned to any variants. To remove them, use [`productOptionUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productOptionUpdate) with the `optionValuesToDelete` argument. Caution Regularly audit and remove unused option values. Large numbers of unused option values can impact performance and cause timeouts when updating products. Use the `hasVariants` field to identify option values that aren't assigned to any variants, as shown in [Step 1](#step-1-retrieve-product-data). The following example shows how to remove the unused values `Red` and `Green` from the `Color` option after deleting variants. The mutation keeps the `Color` option itself and any values still assigned to variants (like `Blue`). Only the specified unused values are removed. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation UpdateOptionToDeleteUnusedValues { productOptionUpdate( productId: "gid://shopify/Product/456", option: { # The ID of the option you're modifying (Color option). id: "gid://shopify/ProductOption/101" }, # Array of unused option value IDs to remove. # These are values with hasVariants: false. optionValuesToDelete: [ "gid://shopify/ProductOptionValue/1", # Red "gid://shopify/ProductOptionValue/2" # Green ] ) { product { options { id name optionValues { id name hasVariants } } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productOptionUpdate": { "product": { "options": [ { "id": "gid://shopify/ProductOption/102", "name": "Fabric", "optionValues": [ { "id": "gid://shopify/ProductOptionValue/7", "name": "Cotton", "hasVariants": true }, { "id": "gid://shopify/ProductOptionValue/8", "name": "Wool", "hasVariants": true } ] }, { "id": "gid://shopify/ProductOption/101", "name": "Color", "optionValues": [ { "id": "gid://shopify/ProductOptionValue/3", "name": "Blue", "hasVariants": true } ] } ] }, "userErrors": [] } } } ``` *** ## Next steps * Learn how to [add product data](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data) to create new products with options and variants. * Learn how to [sync product data](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/sync-data) from external sources. * Learn how to [manage media for products](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/manage-media). * Learn how to [link metafields to product options](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/metafield-linked) for enhanced taxonomy. * Learn how to [reorder products in collections](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/reorder-products). * Explore the [`productUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productUpdate) and [`productVariantsBulkUpdate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkUpdate) mutations in the GraphQL Admin API reference. *** * [Requirements](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#requirements) * [How it works](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#how-it-works) * [Step 1: Retrieve product data](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-1-retrieve-product-data) * [Step 2: Update product information](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-2-update-product-information) * [Step 3: Manage product options](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-3-manage-product-options) * [Step 4: Update product variants](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-4-update-product-variants) * [Step 5: Clean up unused option values](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#step-5-clean-up-unused-option-values) * [Next steps](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data.md#next-steps)