Edit product data using the new product model
The REST Admin API is a legacy API as of October 1, 2024. All apps and integrations should be built with the GraphQL Admin API. For details and migration steps, visit our migration guide.
Learn how to use the new product model to edit the product, variant, and option data that you created.
Anchor to What you'll learnWhat you'll learn
In this guide, you'll learn how to update data for an existing product either by overwriting the data in a single mutation, or by updating its individual fields incrementally through multiple mutations.
You'll also learn the workflow for updating a product and its variants and operations using updated product operations.
If your app or use case aligns with the database sync workflow, then use the productSet
mutation to edit data in a single operation.
Anchor to ScenarioScenario
You've created a new product with variants and options. Now you want to make the following changes:
-
Change the title from
My Cool Socks
toMy Extra Cool Socks
. -
Get rid of sizing, and switch to a one-size-fits-all model.
-
Add a new
Material
option with values ofCotton
andWool
, listing all existing socks asCotton
. -
Rename the
Material
option toFabric
. -
Swap
Color
andMaterial
’s positions to makeMaterial
options and variants display first in the product. -
Remove two color options.
-
Add two new colors of cotton socks.
-
Add five new colors of wool socks.
Anchor to Shape of the product dataShape of the product data
The following diagram represents the original shape of the product data:

The diagram displays the "OptionValues" that are assigned to each variant, and the "Values" that belong to each "Option" relationship of the product's variants to their option values. On the right, there's the relationship of the product's options to their option values. The values that are represented in "OptionValues" correspond with a value in the product's options.
The following is the corresponding data structure:
Product data structure
Anchor to Several mutations to update the product dataSeveral mutations to update the product data
The following mutations should be used when Shopify is the system for managing product domain information. The mutations are designed for smaller changes per request. Consequently, the valid calls are easier to construct and their individual execution duration is shorter.
Anchor to Update the product titleUpdate the product title
Update the product title with the productUpdate
mutation. This example updates the product title from My Cool Socks
to My Extra Cool Socks
:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
The following diagram illustrates the product data after the update:

Anchor to Remove the Size optionRemove the Size option
Because you're moving the product to a one-size-fits-all model, you can remove the Size
option.
Remove an option with the productOptionsDelete
mutation, passing the the ID of the Size
option. However, the product is already offered in multiple sizes, so you need to decide which variants no longer need to be offered.
You can delete unneeded variants in the following ways:
-
Delete the variants that you don’t want to preserve, until each product variant remaining represents a unique
Color
. Update the remaining variants to all have oneSize
. Then, delete theSize
option.You might want to delete variants manually if you need fine-grained control over which variants you want to delete, For example, to preserve variants with specific SKUs or prices to be preserved.
TipWhen there are more than two options, delete variants until each product variant represents a unique option combination.
-
Use the
strategy
argument with a value ofPOSITION
. This strategy automatically resolves duplicate option combinations for you, by deleting any duplicated option combinations by position (descending).This behavior uses the same strategy that the Shopify admin uses to automatically delete any product variants that would be a duplicate of another variant after a product option is deleted. The
POSITION
strategy enables you to implement the same approach in your app with minimal effort.TipWhen you don't care which of the variants is deleted, use this option. This helps avoid round trip calls to the API.
The following example deletes the Size
option using strategy: POSITION
:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
After the product option and its variants are deleted, the product has the following structure:

Consider using the NON_DESTRUCTIVE
strategy when all option combinations, excluding Size
, would be unique after Size
is removed. This strategy automatically updates the remaining variants, removing the Size
option and ensuring a unique set of option combinations.
Anchor to Add the Material optionAdd the Material option
Add a new Material
option with the productOptionsCreate
mutation. When you run this mutation, all existing variants are backfilled to use the first specified option value for the new option. In this example, the option is Cotton
.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
Arguments
JSON response
After the new product option is added, the product has the following structure:

Anchor to Update the Material optionUpdate the Material option
You can also use the productOptionUpdate
mutation to rename a product option or reorder the options. This example renames Material
to Fabric
and changes its position to display first in the product:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
Arguments
JSON response
After the option is renamed and the options are reordered, your product has the following structure:

Anchor to Update variant option values by IDUpdate variant option values by ID
Each time you query a product option's optionValues
, both Wool
and Cotton
are returned.
Because Cotton
was backfilled for existing variants, its hasVariants
value is true, where Wool
's hasVariants
value is false
. Option values with a hasVariants
value of false
are referred to as orphaned option values.
Orphaned option values still have a GID associated with them. In subsequent requests, you can reference orphaned option values by ID, such as for data integrity purposes, local storage, and reflection in the UI.
The following example uses the productVariantsBulkUpdate
mutation to update the Green
color sock to be Wool
. The option value is referenced by its id
.
You can also reference your product options or option values by name.
For example, optionValues: { "name": "Wool", "optionName": "Fabric" }
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
Arguments
JSON response
In the response, Wool
’s hasVariants
value is now true
because the option is no longer orphaned.
After the Wool
option value is assigned to a variant, your product has the following structure:

Anchor to Reorder the optionsReorder the options
Use the productOptionUpdate
mutation to set the new position of each individual option manually. However, if you only need to reorder options and option values, or need to reorder multiple options and option values, then you might want to use the productOptionsReorder
instead.
The following example switches the order of all of the options and option values, displays Color
first with a value order of Blue
, Red
, Green
, and then displays Fabric
with a value order of Wool
, Cotton
:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
Arguments
JSON response
After the options and option values are reordered, your product has the following structure:

Anchor to Remove colorsRemove colors
The following example uses the productVariantsBulkDelete
mutation to remove the variants that use the Red
and Green
color options:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
Arguments
JSON response
The option values for which all variants were deleted are preserved as orphaned option values.
After the variants are removed, your product has the following structure:

Anchor to Tip: Clean up unused option valuesTip: Clean up unused option values
You can preserve unused option values to reference by ID or name at a later point. Alternatively, you can remove the values from the option using the productOptionUpdate
mutation. The following is an example:
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
Arguments
JSON response
Anchor to Add variantsAdd variants
This example uses the productVariantsBulkCreate
mutation to add the following new variants:
-
Cotton socks available in yellow and orange
-
Wool socks of different colors
For the mix of existing and new variants, new colors are applied using a reference value or ID. Any new values are added as option values automatically.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
Arguments
JSON response
After the new variants are added, your product has the following structure:

Anchor to Next stepsNext steps
Learn more about how to migrate from GraphQL to REST with the following resources:
Learn how you can sync product data from an external source into Shopify.
Learn about the differences between using GraphQL and REST to interact with products, variants, and related API components.
If you're new to using GraphQL at Shopify, review guides and resources for migrating your app to the GraphQL Admin API from the REST Admin API.
Learn about the basics of GraphQL, including its benefits over REST.