Skip to main content

Sync product data from an external source

Legacy

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.

Use the productSet mutation to sync the desired state of a product with data from an external source in a single operation

This mutation is suited for apps and use cases where the state of the product model is managed outside of Shopify, for example with an Enterprise Resource Planning (ERP) system or Worksheet, and you want to update Shopify's product model to reflect your external state.

The mutation is available in both asynchronous and synchronous modes. The default is asynchronous.

The productSet mutation has an input limit of 2K variants when run asynchronously and only 100 variants when run synchronously.

This guide provides examples of how to create and update products asynchronously and synchronously, with data from an external source.


Anchor to Create a product with variants and options asynchronouslyCreate a product with variants and options asynchronously

The following productSet mutation initiates an asynchronous operation to create a product with an option named Color. The option has three possible values: Red, Green, and Blue. The mutation also sets up product variants, each associated with one of the color options.

The response to the mutation indicates that the operation has been successfully initiated with the status CREATED.

Products, variants, and options
Variant GIDOption nameOption value name
gid://shopify/ProductVariant/1ColorRed
gid://shopify/ProductVariant/2ColorGreen
gid://shopify/ProductVariant/3ColorBlue

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation setProduct {
productSet(
input: {
id: "gid://shopify/Product/1",
title: "My Cool Product",
productOptions: [
{
name: "Color",
values: [
{ name: "Red" },
{ name: "Green" },
{ name: "Blue" }
]
}
],
variants: [
{ optionValues: [{ optionName: "Color", name: "Red" }] },
{ optionValues: [{ optionName: "Color", name: "Green" }] },
{ optionValues: [{ optionName: "Color", name: "Blue" }] }
]
}
) {
productSetOperation {
id
status
userErrors {
code
field
message
}
}
userErrors {
field
message
}
}
}

JSON response

{
"data": {
"productSet": {
"productSetOperation": {
"id": "gid://shopify/ProductSetOperation/1",
"status": "CREATED",
"userErrors": []
},
"userErrors": []
}
}
}

Anchor to Check the status of the operationCheck the status of the operation

Use the productOperation query to check the status of the operation, using the ID that was returned when the product was created.

The query response indicates that the operation is COMPLETE and provides the details of the created product.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query productSetOperation {
productOperation(id: "gid://shopify/ProductSetOperation/1") {
... on ProductSetOperation {
id
status
product {
id
title
options {
id
name
optionValues {
id
name
}
}
variants(first: 100) {
edges {
node {
id
selectedOptions {
name
value
}
}
}
}
}
userErrors {
code
field
message
}
}
}
}

JSON response

{
"data": {
"productOperation": {
"id": "gid://shopify/ProductSetOperation/1",
"status": "COMPLETE",
"product": {
"id": "gid://shopify/Product/1",
"title": "My Cool Product",
"options": [
{
"id": "gid://shopify/ProductOption/1",
"name": "Color",
"optionValues": [
{
"id": "gid://shopify/ProductOptionValue/1",
"name": "Red"
},
{
"id": "gid://shopify/ProductOptionValue/2",
"name": "Green"
},
{
"id": "gid://shopify/ProductOptionValue/3",
"name": "Blue"
}
]
}
],
"variants": {
"edges": [
{
"node": {
"id": "gid://shopify/ProductVariant/1",
"selectedOptions": [
{
"name": "Color",
"value": "Red"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/2",
"selectedOptions": [
{
"name": "Color",
"value": "Green"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/3",
"selectedOptions": [
{
"name": "Color",
"value": "Blue"
}
]
}
}
]
}
},
"userErrors": []
}
}
}

Anchor to Update the product data asynchronouslyUpdate the product data asynchronously

The following productSet mutation initiates an asynchronous operation to update an existing product's Color option. The original color values of Red, Green, and Blue are replaced with new values of Maroon, Forest Green, and Deep Sea Blue. The mutation also updates the product variants from the old color values to the new ones. Each variant retains its original GID.

Updated products, variants, and options
Variant GIDOption nameOption value name
gid://shopify/ProductVariant/1ColorDeep Sea Blue
gid://shopify/ProductVariant/2ColorForest Green
gid://shopify/ProductVariant/3ColorMaroon

The response to the mutation indicates that the operation has been successfully initiated with the status CREATED.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation setProduct {
productSet(
input: {
id: "gid://shopify/Product/1",
title: "My Extra Cool Product",
productOptions: [
{
name: "Color",
values: [
{ name: "Maroon" },
{ name: "Forest Green" },
{ name: "Deep Sea Blue" }
]
}
],
variants: [
{ optionValues: [{ optionName: "Color", name: "Deep Sea Blue" }] },
{ optionValues: [{ optionName: "Color", name: "Forest Green" }] },
{ optionValues: [{ optionName: "Color", name: "Maroon" }] }
]
}
) {
productSetOperation {
id
status
userErrors {
code
field
message
}
}
userErrors {
field
message
}
}
}

JSON response

{
"data": {
"productSet": {
"productSetOperation": {
"id": "gid://shopify/ProductSetOperation/2",
"status": "CREATED",
"userErrors": []
},
"userErrors": []
}
},
"extensions": {
"cost": {
"requestedQueryCost": 11,
"actualQueryCost": 11
}
}
}

Anchor to Query the updated product asynchronouslyQuery the updated product asynchronously

After the product has been updated asynchronously, use the productOperation query to retrieve the updated product data. This query uses the ProductSetOperation object to check the status of the operation and to retrieve the details of the updated product and its variants.

The response to this query indicates that the operation is COMPLETE, and indicates that the product's title has been updated, and the color options have been updated to Deep Sea Blue, Forest Green, and Maroon.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query productSetOperation {
productOperation(id: "gid://shopify/ProductSetOperation/2") {
... on ProductSetOperation {
id
status
product {
id
title
options {
id
name
optionValues {
id
name
}
}
variants(first: 100) {
edges {
node {
id
selectedOptions {
name
value
}
}
}
}
}
userErrors {
code
field
message
}
}
}
}

JSON response

{
"data": {
"productOperation": {
"id": "gid://shopify/ProductSetOperation/2",
"status": "COMPLETE",
"product": {
"id": "gid://shopify/Product/1",
"title": "My Extra Cool Product",
"options": [
{
"id": "gid://shopify/ProductOption/1",
"name": "Color",
"optionValues": [
{
"id": "gid://shopify/ProductOptionValue/1",
"name": "Deep Sea Blue"
},
{
"id": "gid://shopify/ProductOptionValue/2",
"name": "Forest Green"
},
{
"id": "gid://shopify/ProductOptionValue/3",
"name": "Maroon"
}
]
}
],
"variants": {
"edges": [
{
"node": {
"id": "gid://shopify/ProductVariant/1",
"selectedOptions": [
{
"name": "Color",
"value": "Deep Sea Blue"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/2",
"selectedOptions": [
{
"name": "Color",
"value": "Forest Green"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/3",
"selectedOptions": [
{
"name": "Color",
"value": "Maroon"
}
]
}
}
]
}
},
"userErrors": []
}
}
}

Anchor to Create a product with variants and options synchronouslyCreate a product with variants and options synchronously

The following productSet mutation creates a product with an option named Color. The option has three possible values, Red, Green, and Blue. The mutation creates product variants where each is associated with one of the color options. Each variant is identified by a globally-unique ID.

The mutation runs synchronously because the synchronous field is set.

Products, variants, and options
Variant GIDOption nameOption value name
gid://shopify/ProductVariant/1ColorRed
gid://shopify/ProductVariant/2ColorGreen
gid://shopify/ProductVariant/3ColorBlue
Note

synchronous: true executes the mutation in synchronous mode.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

mutation setProductSync {
productSet(
synchronous: true,
input: {
title: "My Cool Product",
productOptions: [
{
name: "Color",
values: [
{ name: "Red" },
{ name: "Green" },
{ name: "Blue" }
]
}
],
variants: [
{ optionValues: [{ optionName: "Color", name: "Red" }] },
{ optionValues: [{ optionName: "Color", name: "Green" }] },
{ optionValues: [{ optionName: "Color", name: "Blue" }] }
]
}
) {
product {
id
title
description
options {
id
name
position
values
optionValues {
id
name
hasVariants
}
}
variants(first: 100) {
edges {
node {
id
selectedOptions {
name
value
}
}
}
}
}
userErrors {
field
message
}
}
}

JSON response

{
"data": {
"productSet": {
"product": {
"id": "gid://shopify/Product/1",
"title": "My Cool Product",
"description": "",
"options": [
{
"id": "gid://shopify/ProductOption/1",
"name": "Color",
"position": 1,
"values": [
"Red",
"Green",
"Blue"
],
"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
}
]
}
],
"variants": {
"edges": [
{
"node": {
"id": "gid://shopify/ProductVariant/1",
"selectedOptions": [
{
"name": "Color",
"value": "Red"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/2",
"selectedOptions": [
{
"name": "Color",
"value": "Green"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/3",
"selectedOptions": [
{
"name": "Color",
"value": "Blue"
}
]
}
}
]
}
},
"userErrors": []
}
}
}

Anchor to Update the product data synchronouslyUpdate the product data synchronously

Note

Because this mutation encapsulates many domain entities and their relationships, forming valid product inputs requires more care and attention and the mutations will take longer to execute.

The following productSet mutation updates the existing product's Color option. The original color values Red, Green, and Blue are replaced with new values of Maroon, Forest Green, and Deep Sea Blue. The mutation also updates the product variants from the old color values to the new ones. Each variant retains its original GID.

The mutation runs synchronously because the synchronous field is set.

Updated products, variants, and options
Variant GIDOption nameOption value name
gid://shopify/ProductVariant/1ColorDeep Sea Blue
gid://shopify/ProductVariant/2ColorForest Green
gid://shopify/ProductVariant/3ColorMaroon

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

mutation setProductSync {
productSet(
synchronous: true,
input: {
id: "gid://shopify/Product/1",
title: "My Extra Cool Product",
productOptions: [
{
name: "Color",
values: [
{ name: "Maroon" },
{ name: "Forest Green" },
{ name: "Deep Sea Blue" }
]
}
],
variants: [
{ optionValues: [{ optionName: "Color", name: "Deep Sea Blue" }] },
{ optionValues: [{ optionName: "Color", name: "Forest Green" }] },
{ optionValues: [{ optionName: "Color", name: "Maroon" }] }
]
}
) {
product {
id
title
description
options {
id
name
position
values
optionValues {
id
name
hasVariants
}
}
variants(first: 100) {
edges {
node {
id
selectedOptions {
name
value
}
}
}
}
}
userErrors {
field
message
}
}
}

JSON response

{
"data": {
"productSet": {
"product": {
"id": "gid://shopify/Product/1",
"title": "My Extra Cool Product",
"description": "",
"options": [
{
"id": "gid://shopify/ProductOption/1",
"name": "Color",
"position": 1,
"values": [
"Deep Sea Blue",
"Forest Green",
"Maroon"
],
"optionValues": [
{
"id": "gid://shopify/ProductOptionValue/1",
"name": "Deep Sea Blue",
"hasVariants": true
},
{
"id": "gid://shopify/ProductOptionValue/2",
"name": "Forest Green",
"hasVariants": true
},
{
"id": "gid://shopify/ProductOptionValue/3",
"name": "Maroon",
"hasVariants": true
}
]
}
],
"variants": {
"edges": [
{
"node": {
"id": "gid://shopify/ProductVariant/1",
"selectedOptions": [
{
"name": "Color",
"value": "Deep Sea Blue"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/2",
"selectedOptions": [
{
"name": "Color",
"value": "Forest Green"
}
]
}
},
{
"node": {
"id": "gid://shopify/ProductVariant/3",
"selectedOptions": [
{
"name": "Color",
"value": "Maroon"
}
]
}
}
]
}
},
"userErrors": []
}
}
}

Product management in GraphQL versus REST

Learn about the differences between using GraphQL and REST to interact with products, variants, and related API components.

Migrate to GraphQL

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.

GraphQL basics

Learn about the basics of GraphQL, including its benefits over REST.


Was this page helpful?