Sync product data
Use the GraphQL Admin API productSet mutation to synchronize the complete state of a product with data from an external source in a single operation. This mutation is specifically designed for scenarios where Shopify acts as a downstream system that mirrors product data from an authoritative external database.
Unlike incremental mutations like productCreate or productVariantsBulkUpdate, productSet treats each operation as a complete product state declaration. The mutation creates, updates, or removes options and variants as needed to make Shopify's product data match exactly what you provide in the input.
Anchor to RequirementsRequirements
- Your app can make authenticated requests to the latest version of the GraphQL Admin API or higher.
- Your app has the
write_productsaccess scope. Learn how to configure your access scopes using Shopify CLI. - You're familiar with Shopify's product model, where products contain options (like color and size) and variants represent specific purchasable combinations.
- Your app manages product data in an external system (ERP, PIM, spreadsheet, or custom database) and needs to sync that data to Shopify.
Anchor to How it worksHow it works
The productSet mutation updates only the fields you explicitly include in the input. For options and variants, the mutation replaces the complete state—any options or variants not included in your input are removed. For other product fields (like description or tags), omitted fields remain unchanged while included fields are updated to match your input, even if you provide an empty value.
For example, if an existing product has a description and tags, and you call productSet with only title, productOptions, and variants, the description and tags remain unchanged. However, if you include tags: [] in your input, the tags are cleared.
The mutation supports both synchronous mode (returns results immediately) and asynchronous mode (processes in the background). Choose the mode that best fits your needs.
Anchor to Step 1: Create or update a productStep 1: Create or update a product
Use productSet to sync product data from an external system. The mutation supports two modes:
- Synchronous mode (default): Returns product data immediately.
- Asynchronous mode (
synchronous: false): Processes in the background. You'll query for completion separately in Step 2.
Anchor to Option A: Use synchronous modeOption A: Use synchronous mode
The following example shows how to create a product synchronously. The mutation waits until processing completes, then returns the complete product data in a single response. No polling is required.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
Anchor to Option B: Use asynchronous modeOption B: Use asynchronous mode
The following example shows how to create a product with three color variants in asynchronous mode. The mutation returns immediately with a ProductSetOperation object (status "CREATED") while Shopify processes the product in the background. You'll use the operation ID to poll for completion in Step 2.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
Anchor to Step 2: Poll for completion (asynchronous mode only)Step 2: Poll for completion (asynchronous mode only)
Poll the productOperation query with the operation ID from Step 1 until the status changes to COMPLETE or FAILED.
The following example queries the operation status. When COMPLETE, the response includes the full product data. If FAILED, check userErrors for details.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL query
JSON response (when COMPLETE)
Anchor to Step 3 (Optional): Update existing productsStep 3 (Optional): Update existing products
To update an existing product's complete state, use productSet with the product ID in the input. The mutation replaces all product data with what you provide.
The following example shows how to update a product's title and replace its color options and variants. If the product previously had 5 variants and you provide 3, it will have exactly 3 variants (2 deleted). Any options or variants not included in the input are removed.
POST https://{shop}.myshopify.com/api/{api_version}/graphql.json
GraphQL mutation
JSON response
Anchor to Next stepsNext steps
- Learn how to add product data using incremental mutations.
- Learn how to update product data with targeted mutations.
- Explore the
productSetmutation andproductOperationquery in the GraphQL Admin API reference.