# productSet - admin-graphql - MUTATION Version: 2024-04 ## Description Creates or updates a product in a single request. Use this mutation when syncing information from an external data source into Shopify. When using this mutation to update a product, specify that product's `id` in the input. Any list field (e.g. [collections](https://shopify.dev/api/admin-graphql/current/input-objects/ProductSetInput#field-productsetinput-collections), [metafields](https://shopify.dev/api/admin-graphql/current/input-objects/ProductSetInput#field-productsetinput-metafields), [variants](https://shopify.dev/api/admin-graphql/current/input-objects/ProductSetInput#field-productsetinput-variants)) will be updated so that all included entries are either created or updated, and all existing entries not included will be deleted. All other fields will be updated to the value passed. Omitted fields will not be updated. When run in synchronous mode, the `productSet` mutation has an input limit of 100 variants. If you anticipate any of your use cases requiring support for more than 100 variants, please use the mutation in asynchronous mode (default). When run in synchronous mode, you will get the product back in the response. In asynchronous mode, you will instead get a [ProductSetOperation](https://shopify.dev/api/admin-graphql/current/objects/ProductSetOperation) object back. You can then use the [productOperation](https://shopify.dev/api/admin-graphql/current/queries/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. If you need to update a subset of variants, use one of the bulk variant mutations: - [productVariantsBulkCreate](https://shopify.dev/api/admin-graphql/current/mutations/productVariantsBulkCreate) - [productVariantsBulkUpdate](https://shopify.dev/api/admin-graphql/current/mutations/productVariantsBulkUpdate) - [productVariantsBulkDelete](https://shopify.dev/api/admin-graphql/current/mutations/productVariantsBulkDelete) If you need to update options, use one of the product option mutations: - [productOptionsCreate](https://shopify.dev/api/admin-graphql/current/mutations/productOptionsCreate) - [productOptionUpdate](https://shopify.dev/api/admin-graphql/current/mutations/productOptionUpdate) - [productOptionsDelete](https://shopify.dev/api/admin-graphql/current/mutations/productOptionsDelete) - [productOptionsReorder](https://shopify.dev/api/admin-graphql/current/mutations/productOptionsReorder) See our guide to [sync product data from an external source](https://shopify.dev/api/admin/migrate/new-product-model/sync-data) for more. ### Access Scopes `write_products` access scope. Also: The user must have a permission to create products. ## Arguments * [input](/docs/api/admin-graphql/2024-04/input-objects/ProductSetInput): ProductSetInput! - The properties of the newly created or updated product. * [synchronous](/docs/api/admin-graphql/2024-04/scalars/Boolean): Boolean - Whether the mutation should be run synchronously or asynchronously. To use this mutation with more than 100 variants in the `input`, the mutation must be run asynchronously. If `true`, the mutation will return the updated `product`. If `false`, the mutation will return a `productSetOperation`. Defaults to `false`. **Note**: When run in the context of a [bulk operation](https://shopify.dev/api/usage/bulk-operations/imports), the mutation will always run synchronously and this argument will be ignored. ## Returns * [product](/docs/api/admin-graphql/2024-04/objects/Product): Product The product object. * [productSetOperation](/docs/api/admin-graphql/2024-04/objects/ProductSetOperation): ProductSetOperation The product set operation, returned when run in asynchronous mode. * [userErrors](/docs/api/admin-graphql/2024-04/objects/ProductSetUserError): ProductSetUserError! The list of errors that occurred from executing the mutation. ## Examples ### Asynchronously create a product with two variants Curl example: "curl -X POST \\\nhttps://your-development-store.myshopify.com/admin/api/2024-04/graphql.json \\\n-H 'Content-Type: application/json' \\\n-H 'X-Shopify-Access-Token: {access_token}' \\\n-d '{\n\"query\": \"mutation createProductAsynchronous($productSet: ProductSetInput!, $synchronous: Boolean!) { productSet(synchronous: $synchronous, input: $productSet) { product { id } productSetOperation { id status userErrors { code field message } } userErrors { code field message } } }\",\n \"variables\": {\n \"synchronous\": false,\n \"productSet\": {\n \"title\": \"Winter hat\",\n \"productOptions\": [\n {\n \"name\": \"Color\",\n \"position\": 1,\n \"values\": [\n {\n \"name\": \"Grey\"\n },\n {\n \"name\": \"Black\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"optionValues\": [\n {\n \"optionName\": \"Color\",\n \"name\": \"Grey\"\n }\n ],\n \"price\": 79.99\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Color\",\n \"name\": \"Black\"\n }\n ],\n \"price\": 69.99\n }\n ]\n }\n }\n}'\n" Node example: "const client = new shopify.clients.Graphql({session});\nconst data = await client.query({\n data: {\n \"query\": `mutation createProductAsynchronous($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n }\n productSetOperation {\n id\n status\n userErrors {\n code\n field\n message\n }\n }\n userErrors {\n code\n field\n message\n }\n }\n }`,\n \"variables\": {\n \"synchronous\": false,\n \"productSet\": {\n \"title\": \"Winter hat\",\n \"productOptions\": [\n {\n \"name\": \"Color\",\n \"position\": 1,\n \"values\": [\n {\n \"name\": \"Grey\"\n },\n {\n \"name\": \"Black\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"optionValues\": [\n {\n \"optionName\": \"Color\",\n \"name\": \"Grey\"\n }\n ],\n \"price\": 79.99\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Color\",\n \"name\": \"Black\"\n }\n ],\n \"price\": 69.99\n }\n ]\n }\n },\n },\n});\n" Ruby example: "session = ShopifyAPI::Auth::Session.new(\n shop: \"your-development-store.myshopify.com\",\n access_token: access_token\n)\nclient = ShopifyAPI::Clients::Graphql::Admin.new(\n session: session\n)\n\nquery = <<~QUERY\n mutation createProductAsynchronous($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n }\n productSetOperation {\n id\n status\n userErrors {\n code\n field\n message\n }\n }\n userErrors {\n code\n field\n message\n }\n }\n }\nQUERY\n\nvariables = {\n \"synchronous\": false,\n \"productSet\": {\n \"title\": \"Winter hat\",\n \"productOptions\": [{\"name\"=>\"Color\", \"position\"=>1, \"values\"=>[{\"name\"=>\"Grey\"}, {\"name\"=>\"Black\"}]}],\n \"variants\": [{\"optionValues\"=>[{\"optionName\"=>\"Color\", \"name\"=>\"Grey\"}], \"price\"=>79.99}, {\"optionValues\"=>[{\"optionName\"=>\"Color\", \"name\"=>\"Black\"}], \"price\"=>69.99}]\n }\n}\n\nresponse = client.query(query: query, variables: variables)\n" Remix example: "const { admin } = await authenticate.admin(request);\n\nconst response = await admin.graphql(\n `#graphql\n mutation createProductAsynchronous($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n }\n productSetOperation {\n id\n status\n userErrors {\n code\n field\n message\n }\n }\n userErrors {\n code\n field\n message\n }\n }\n }`,\n {\n variables: {\n \"synchronous\": false,\n \"productSet\": {\n \"title\": \"Winter hat\",\n \"productOptions\": [\n {\n \"name\": \"Color\",\n \"position\": 1,\n \"values\": [\n {\n \"name\": \"Grey\"\n },\n {\n \"name\": \"Black\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"optionValues\": [\n {\n \"optionName\": \"Color\",\n \"name\": \"Grey\"\n }\n ],\n \"price\": 79.99\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Color\",\n \"name\": \"Black\"\n }\n ],\n \"price\": 69.99\n }\n ]\n }\n },\n },\n);\n\nconst data = await response.json();\n" Graphql query: "mutation createProductAsynchronous($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n }\n productSetOperation {\n id\n status\n userErrors {\n code\n field\n message\n }\n }\n userErrors {\n code\n field\n message\n }\n }\n}" #### Graphql Input { "synchronous": false, "productSet": { "title": "Winter hat", "productOptions": [ { "name": "Color", "position": 1, "values": [ { "name": "Grey" }, { "name": "Black" } ] } ], "variants": [ { "optionValues": [ { "optionName": "Color", "name": "Grey" } ], "price": 79.99 }, { "optionValues": [ { "optionName": "Color", "name": "Black" } ], "price": 69.99 } ] } } #### Graphql Response { "data": { "productSet": { "product": null, "productSetOperation": { "id": "gid://shopify/ProductSetOperation/1010603729", "status": "CREATED", "userErrors": [] }, "userErrors": [] } } } ### Create a product with two options and four variants Curl example: "curl -X POST \\\nhttps://your-development-store.myshopify.com/admin/api/2024-04/graphql.json \\\n-H 'Content-Type: application/json' \\\n-H 'X-Shopify-Access-Token: {access_token}' \\\n-d '{\n\"query\": \"mutation createProductWithTwoOptionsAndVariants($productSet: ProductSetInput!, $synchronous: Boolean!) { productSet(synchronous: $synchronous, input: $productSet) { product { id title options(first: 5) { name position optionValues { name } } variants(first: 5) { nodes { price selectedOptions { name optionValue { id name } } } } } userErrors { field message } } }\",\n \"variables\": {\n \"synchronous\": true,\n \"productSet\": {\n \"title\": \"A humble tie\",\n \"productOptions\": [\n {\n \"name\": \"Pattern\",\n \"position\": 1,\n \"values\": [\n {\n \"name\": \"Plain\"\n },\n {\n \"name\": \"Stripes\"\n }\n ]\n },\n {\n \"name\": \"Width\",\n \"position\": 2,\n \"values\": [\n {\n \"name\": \"Slim\"\n },\n {\n \"name\": \"Classic\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Plain\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Slim\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Plain\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Classic\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Stripes\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Slim\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Stripes\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Classic\"\n }\n ],\n \"price\": 15.0\n }\n ]\n }\n }\n}'\n" Node example: "const client = new shopify.clients.Graphql({session});\nconst data = await client.query({\n data: {\n \"query\": `mutation createProductWithTwoOptionsAndVariants($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n title\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n }`,\n \"variables\": {\n \"synchronous\": true,\n \"productSet\": {\n \"title\": \"A humble tie\",\n \"productOptions\": [\n {\n \"name\": \"Pattern\",\n \"position\": 1,\n \"values\": [\n {\n \"name\": \"Plain\"\n },\n {\n \"name\": \"Stripes\"\n }\n ]\n },\n {\n \"name\": \"Width\",\n \"position\": 2,\n \"values\": [\n {\n \"name\": \"Slim\"\n },\n {\n \"name\": \"Classic\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Plain\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Slim\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Plain\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Classic\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Stripes\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Slim\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Stripes\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Classic\"\n }\n ],\n \"price\": 15.0\n }\n ]\n }\n },\n },\n});\n" Ruby example: "session = ShopifyAPI::Auth::Session.new(\n shop: \"your-development-store.myshopify.com\",\n access_token: access_token\n)\nclient = ShopifyAPI::Clients::Graphql::Admin.new(\n session: session\n)\n\nquery = <<~QUERY\n mutation createProductWithTwoOptionsAndVariants($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n title\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n }\nQUERY\n\nvariables = {\n \"synchronous\": true,\n \"productSet\": {\n \"title\": \"A humble tie\",\n \"productOptions\": [{\"name\"=>\"Pattern\", \"position\"=>1, \"values\"=>[{\"name\"=>\"Plain\"}, {\"name\"=>\"Stripes\"}]}, {\"name\"=>\"Width\", \"position\"=>2, \"values\"=>[{\"name\"=>\"Slim\"}, {\"name\"=>\"Classic\"}]}],\n \"variants\": [{\"optionValues\"=>[{\"optionName\"=>\"Pattern\", \"name\"=>\"Plain\"}, {\"optionName\"=>\"Width\", \"name\"=>\"Slim\"}], \"price\"=>15.0}, {\"optionValues\"=>[{\"optionName\"=>\"Pattern\", \"name\"=>\"Plain\"}, {\"optionName\"=>\"Width\", \"name\"=>\"Classic\"}], \"price\"=>15.0}, {\"optionValues\"=>[{\"optionName\"=>\"Pattern\", \"name\"=>\"Stripes\"}, {\"optionName\"=>\"Width\", \"name\"=>\"Slim\"}], \"price\"=>15.0}, {\"optionValues\"=>[{\"optionName\"=>\"Pattern\", \"name\"=>\"Stripes\"}, {\"optionName\"=>\"Width\", \"name\"=>\"Classic\"}], \"price\"=>15.0}]\n }\n}\n\nresponse = client.query(query: query, variables: variables)\n" Remix example: "const { admin } = await authenticate.admin(request);\n\nconst response = await admin.graphql(\n `#graphql\n mutation createProductWithTwoOptionsAndVariants($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n title\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n }`,\n {\n variables: {\n \"synchronous\": true,\n \"productSet\": {\n \"title\": \"A humble tie\",\n \"productOptions\": [\n {\n \"name\": \"Pattern\",\n \"position\": 1,\n \"values\": [\n {\n \"name\": \"Plain\"\n },\n {\n \"name\": \"Stripes\"\n }\n ]\n },\n {\n \"name\": \"Width\",\n \"position\": 2,\n \"values\": [\n {\n \"name\": \"Slim\"\n },\n {\n \"name\": \"Classic\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Plain\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Slim\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Plain\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Classic\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Stripes\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Slim\"\n }\n ],\n \"price\": 15.0\n },\n {\n \"optionValues\": [\n {\n \"optionName\": \"Pattern\",\n \"name\": \"Stripes\"\n },\n {\n \"optionName\": \"Width\",\n \"name\": \"Classic\"\n }\n ],\n \"price\": 15.0\n }\n ]\n }\n },\n },\n);\n\nconst data = await response.json();\n" Graphql query: "mutation createProductWithTwoOptionsAndVariants($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n title\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n}" #### Graphql Input { "synchronous": true, "productSet": { "title": "A humble tie", "productOptions": [ { "name": "Pattern", "position": 1, "values": [ { "name": "Plain" }, { "name": "Stripes" } ] }, { "name": "Width", "position": 2, "values": [ { "name": "Slim" }, { "name": "Classic" } ] } ], "variants": [ { "optionValues": [ { "optionName": "Pattern", "name": "Plain" }, { "optionName": "Width", "name": "Slim" } ], "price": 15.0 }, { "optionValues": [ { "optionName": "Pattern", "name": "Plain" }, { "optionName": "Width", "name": "Classic" } ], "price": 15.0 }, { "optionValues": [ { "optionName": "Pattern", "name": "Stripes" }, { "optionName": "Width", "name": "Slim" } ], "price": 15.0 }, { "optionValues": [ { "optionName": "Pattern", "name": "Stripes" }, { "optionName": "Width", "name": "Classic" } ], "price": 15.0 } ] } } #### Graphql Response { "data": { "productSet": { "product": { "id": "gid://shopify/Product/1072481210", "title": "A humble tie", "options": [ { "name": "Pattern", "position": 1, "optionValues": [ { "name": "Plain" }, { "name": "Stripes" } ] }, { "name": "Width", "position": 2, "optionValues": [ { "name": "Slim" }, { "name": "Classic" } ] } ], "variants": { "nodes": [ { "price": "15.00", "selectedOptions": [ { "name": "Pattern", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673110", "name": "Plain" } }, { "name": "Width", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673112", "name": "Slim" } } ] }, { "price": "15.00", "selectedOptions": [ { "name": "Pattern", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673110", "name": "Plain" } }, { "name": "Width", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673113", "name": "Classic" } } ] }, { "price": "15.00", "selectedOptions": [ { "name": "Pattern", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673111", "name": "Stripes" } }, { "name": "Width", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673112", "name": "Slim" } } ] }, { "price": "15.00", "selectedOptions": [ { "name": "Pattern", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673111", "name": "Stripes" } }, { "name": "Width", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673113", "name": "Classic" } } ] } ] } }, "userErrors": [] } } } ### Remove custom options and variants from a product Curl example: "curl -X POST \\\nhttps://your-development-store.myshopify.com/admin/api/2024-04/graphql.json \\\n-H 'Content-Type: application/json' \\\n-H 'X-Shopify-Access-Token: {access_token}' \\\n-d '{\n\"query\": \"mutation updateProductToLeaveDefaultVariant($productSet: ProductSetInput!, $synchronous: Boolean!) { productSet(synchronous: $synchronous, input: $productSet) { product { id hasOnlyDefaultVariant } userErrors { field message } } }\",\n \"variables\": {\n \"synchronous\": true,\n \"productSet\": {\n \"id\": \"gid://shopify/Product/20995642\",\n \"productOptions\": [],\n \"variants\": []\n }\n }\n}'\n" Node example: "const client = new shopify.clients.Graphql({session});\nconst data = await client.query({\n data: {\n \"query\": `mutation updateProductToLeaveDefaultVariant($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n hasOnlyDefaultVariant\n }\n userErrors {\n field\n message\n }\n }\n }`,\n \"variables\": {\n \"synchronous\": true,\n \"productSet\": {\n \"id\": \"gid://shopify/Product/20995642\",\n \"productOptions\": [],\n \"variants\": []\n }\n },\n },\n});\n" Ruby example: "session = ShopifyAPI::Auth::Session.new(\n shop: \"your-development-store.myshopify.com\",\n access_token: access_token\n)\nclient = ShopifyAPI::Clients::Graphql::Admin.new(\n session: session\n)\n\nquery = <<~QUERY\n mutation updateProductToLeaveDefaultVariant($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n hasOnlyDefaultVariant\n }\n userErrors {\n field\n message\n }\n }\n }\nQUERY\n\nvariables = {\n \"synchronous\": true,\n \"productSet\": {\n \"id\": \"gid://shopify/Product/20995642\",\n \"productOptions\": [],\n \"variants\": []\n }\n}\n\nresponse = client.query(query: query, variables: variables)\n" Remix example: "const { admin } = await authenticate.admin(request);\n\nconst response = await admin.graphql(\n `#graphql\n mutation updateProductToLeaveDefaultVariant($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n hasOnlyDefaultVariant\n }\n userErrors {\n field\n message\n }\n }\n }`,\n {\n variables: {\n \"synchronous\": true,\n \"productSet\": {\n \"id\": \"gid://shopify/Product/20995642\",\n \"productOptions\": [],\n \"variants\": []\n }\n },\n },\n);\n\nconst data = await response.json();\n" Graphql query: "mutation updateProductToLeaveDefaultVariant($productSet: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $productSet) {\n product {\n id\n hasOnlyDefaultVariant\n }\n userErrors {\n field\n message\n }\n }\n}" #### Graphql Input { "synchronous": true, "productSet": { "id": "gid://shopify/Product/20995642", "productOptions": [], "variants": [] } } #### Graphql Response { "data": { "productSet": { "product": { "id": "gid://shopify/Product/20995642", "hasOnlyDefaultVariant": true }, "userErrors": [] } } } ### Update product variant pricing referencing options and variants by Ids Curl example: "curl -X POST \\\nhttps://your-development-store.myshopify.com/admin/api/2024-04/graphql.json \\\n-H 'Content-Type: application/json' \\\n-H 'X-Shopify-Access-Token: {access_token}' \\\n-d '{\n\"query\": \"mutation updateProductVariantPricing($input: ProductSetInput!, $synchronous: Boolean!) { productSet(synchronous: $synchronous, input: $input) { product { id title description handle options(first: 5) { name position optionValues { name } } variants(first: 5) { nodes { price compareAtPrice selectedOptions { name optionValue { id name } } } } } userErrors { field message } } }\",\n \"variables\": {\n \"synchronous\": true,\n \"input\": {\n \"id\": \"gid://shopify/Product/1072481182\",\n \"title\": \"Bike frame\",\n \"descriptionHtml\": \"Blending durability with aerodynamics\",\n \"handle\": \"bike-frame\",\n \"productType\": \"parts\",\n \"tags\": [\n \"cycling\",\n \"bike\",\n \"parts\"\n ],\n \"vendor\": \"Your cycling company\",\n \"status\": \"ACTIVE\",\n \"productOptions\": [\n {\n \"id\": \"gid://shopify/ProductOption/1064576743\",\n \"values\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673030\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673031\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673032\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductOption/1064576744\",\n \"values\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673034\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673033\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673035\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"id\": \"gid://shopify/ProductVariant/1070325697\",\n \"position\": 1,\n \"price\": 94.99,\n \"compareAtPrice\": 99.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673030\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673033\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductVariant/1070325698\",\n \"position\": 2,\n \"price\": 259.99,\n \"compareAtPrice\": 299.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673031\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673034\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductVariant/1070325699\",\n \"position\": 3,\n \"price\": 169.99,\n \"compareAtPrice\": 199.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673032\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673035\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n }\n ]\n }\n }\n}'\n" Node example: "const client = new shopify.clients.Graphql({session});\nconst data = await client.query({\n data: {\n \"query\": `mutation updateProductVariantPricing($input: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $input) {\n product {\n id\n title\n description\n handle\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n compareAtPrice\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n }`,\n \"variables\": {\n \"synchronous\": true,\n \"input\": {\n \"id\": \"gid://shopify/Product/1072481182\",\n \"title\": \"Bike frame\",\n \"descriptionHtml\": \"Blending durability with aerodynamics\",\n \"handle\": \"bike-frame\",\n \"productType\": \"parts\",\n \"tags\": [\n \"cycling\",\n \"bike\",\n \"parts\"\n ],\n \"vendor\": \"Your cycling company\",\n \"status\": \"ACTIVE\",\n \"productOptions\": [\n {\n \"id\": \"gid://shopify/ProductOption/1064576743\",\n \"values\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673030\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673031\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673032\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductOption/1064576744\",\n \"values\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673034\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673033\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673035\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"id\": \"gid://shopify/ProductVariant/1070325697\",\n \"position\": 1,\n \"price\": 94.99,\n \"compareAtPrice\": 99.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673030\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673033\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductVariant/1070325698\",\n \"position\": 2,\n \"price\": 259.99,\n \"compareAtPrice\": 299.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673031\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673034\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductVariant/1070325699\",\n \"position\": 3,\n \"price\": 169.99,\n \"compareAtPrice\": 199.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673032\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673035\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n }\n ]\n }\n },\n },\n});\n" Ruby example: "session = ShopifyAPI::Auth::Session.new(\n shop: \"your-development-store.myshopify.com\",\n access_token: access_token\n)\nclient = ShopifyAPI::Clients::Graphql::Admin.new(\n session: session\n)\n\nquery = <<~QUERY\n mutation updateProductVariantPricing($input: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $input) {\n product {\n id\n title\n description\n handle\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n compareAtPrice\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n }\nQUERY\n\nvariables = {\n \"synchronous\": true,\n \"input\": {\n \"id\": \"gid://shopify/Product/1072481182\",\n \"title\": \"Bike frame\",\n \"descriptionHtml\": \"Blending durability with aerodynamics\",\n \"handle\": \"bike-frame\",\n \"productType\": \"parts\",\n \"tags\": [\"cycling\", \"bike\", \"parts\"],\n \"vendor\": \"Your cycling company\",\n \"status\": \"ACTIVE\",\n \"productOptions\": [{\"id\"=>\"gid://shopify/ProductOption/1064576743\", \"values\"=>[{\"id\"=>\"gid://shopify/ProductOptionValue/1054673030\"}, {\"id\"=>\"gid://shopify/ProductOptionValue/1054673031\"}, {\"id\"=>\"gid://shopify/ProductOptionValue/1054673032\"}]}, {\"id\"=>\"gid://shopify/ProductOption/1064576744\", \"values\"=>[{\"id\"=>\"gid://shopify/ProductOptionValue/1054673034\"}, {\"id\"=>\"gid://shopify/ProductOptionValue/1054673033\"}, {\"id\"=>\"gid://shopify/ProductOptionValue/1054673035\"}]}],\n \"variants\": [{\"id\"=>\"gid://shopify/ProductVariant/1070325697\", \"position\"=>1, \"price\"=>94.99, \"compareAtPrice\"=>99.99, \"optionValues\"=>[{\"id\"=>\"gid://shopify/ProductOptionValue/1054673030\", \"optionId\"=>\"gid://shopify/ProductOption/1064576743\"}, {\"id\"=>\"gid://shopify/ProductOptionValue/1054673033\", \"optionId\"=>\"gid://shopify/ProductOption/1064576744\"}]}, {\"id\"=>\"gid://shopify/ProductVariant/1070325698\", \"position\"=>2, \"price\"=>259.99, \"compareAtPrice\"=>299.99, \"optionValues\"=>[{\"id\"=>\"gid://shopify/ProductOptionValue/1054673031\", \"optionId\"=>\"gid://shopify/ProductOption/1064576743\"}, {\"id\"=>\"gid://shopify/ProductOptionValue/1054673034\", \"optionId\"=>\"gid://shopify/ProductOption/1064576744\"}]}, {\"id\"=>\"gid://shopify/ProductVariant/1070325699\", \"position\"=>3, \"price\"=>169.99, \"compareAtPrice\"=>199.99, \"optionValues\"=>[{\"id\"=>\"gid://shopify/ProductOptionValue/1054673032\", \"optionId\"=>\"gid://shopify/ProductOption/1064576743\"}, {\"id\"=>\"gid://shopify/ProductOptionValue/1054673035\", \"optionId\"=>\"gid://shopify/ProductOption/1064576744\"}]}]\n }\n}\n\nresponse = client.query(query: query, variables: variables)\n" Remix example: "const { admin } = await authenticate.admin(request);\n\nconst response = await admin.graphql(\n `#graphql\n mutation updateProductVariantPricing($input: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $input) {\n product {\n id\n title\n description\n handle\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n compareAtPrice\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n }`,\n {\n variables: {\n \"synchronous\": true,\n \"input\": {\n \"id\": \"gid://shopify/Product/1072481182\",\n \"title\": \"Bike frame\",\n \"descriptionHtml\": \"Blending durability with aerodynamics\",\n \"handle\": \"bike-frame\",\n \"productType\": \"parts\",\n \"tags\": [\n \"cycling\",\n \"bike\",\n \"parts\"\n ],\n \"vendor\": \"Your cycling company\",\n \"status\": \"ACTIVE\",\n \"productOptions\": [\n {\n \"id\": \"gid://shopify/ProductOption/1064576743\",\n \"values\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673030\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673031\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673032\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductOption/1064576744\",\n \"values\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673034\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673033\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673035\"\n }\n ]\n }\n ],\n \"variants\": [\n {\n \"id\": \"gid://shopify/ProductVariant/1070325697\",\n \"position\": 1,\n \"price\": 94.99,\n \"compareAtPrice\": 99.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673030\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673033\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductVariant/1070325698\",\n \"position\": 2,\n \"price\": 259.99,\n \"compareAtPrice\": 299.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673031\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673034\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n },\n {\n \"id\": \"gid://shopify/ProductVariant/1070325699\",\n \"position\": 3,\n \"price\": 169.99,\n \"compareAtPrice\": 199.99,\n \"optionValues\": [\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673032\",\n \"optionId\": \"gid://shopify/ProductOption/1064576743\"\n },\n {\n \"id\": \"gid://shopify/ProductOptionValue/1054673035\",\n \"optionId\": \"gid://shopify/ProductOption/1064576744\"\n }\n ]\n }\n ]\n }\n },\n },\n);\n\nconst data = await response.json();\n" Graphql query: "mutation updateProductVariantPricing($input: ProductSetInput!, $synchronous: Boolean!) {\n productSet(synchronous: $synchronous, input: $input) {\n product {\n id\n title\n description\n handle\n options(first: 5) {\n name\n position\n optionValues {\n name\n }\n }\n variants(first: 5) {\n nodes {\n price\n compareAtPrice\n selectedOptions {\n name\n optionValue {\n id\n name\n }\n }\n }\n }\n }\n userErrors {\n field\n message\n }\n }\n}" #### Graphql Input { "synchronous": true, "input": { "id": "gid://shopify/Product/1072481182", "title": "Bike frame", "descriptionHtml": "Blending durability with aerodynamics", "handle": "bike-frame", "productType": "parts", "tags": [ "cycling", "bike", "parts" ], "vendor": "Your cycling company", "status": "ACTIVE", "productOptions": [ { "id": "gid://shopify/ProductOption/1064576743", "values": [ { "id": "gid://shopify/ProductOptionValue/1054673030" }, { "id": "gid://shopify/ProductOptionValue/1054673031" }, { "id": "gid://shopify/ProductOptionValue/1054673032" } ] }, { "id": "gid://shopify/ProductOption/1064576744", "values": [ { "id": "gid://shopify/ProductOptionValue/1054673034" }, { "id": "gid://shopify/ProductOptionValue/1054673033" }, { "id": "gid://shopify/ProductOptionValue/1054673035" } ] } ], "variants": [ { "id": "gid://shopify/ProductVariant/1070325697", "position": 1, "price": 94.99, "compareAtPrice": 99.99, "optionValues": [ { "id": "gid://shopify/ProductOptionValue/1054673030", "optionId": "gid://shopify/ProductOption/1064576743" }, { "id": "gid://shopify/ProductOptionValue/1054673033", "optionId": "gid://shopify/ProductOption/1064576744" } ] }, { "id": "gid://shopify/ProductVariant/1070325698", "position": 2, "price": 259.99, "compareAtPrice": 299.99, "optionValues": [ { "id": "gid://shopify/ProductOptionValue/1054673031", "optionId": "gid://shopify/ProductOption/1064576743" }, { "id": "gid://shopify/ProductOptionValue/1054673034", "optionId": "gid://shopify/ProductOption/1064576744" } ] }, { "id": "gid://shopify/ProductVariant/1070325699", "position": 3, "price": 169.99, "compareAtPrice": 199.99, "optionValues": [ { "id": "gid://shopify/ProductOptionValue/1054673032", "optionId": "gid://shopify/ProductOption/1064576743" }, { "id": "gid://shopify/ProductOptionValue/1054673035", "optionId": "gid://shopify/ProductOption/1064576744" } ] } ] } } #### Graphql Response { "data": { "productSet": { "product": { "id": "gid://shopify/Product/1072481182", "title": "Bike frame", "description": "Blending durability with aerodynamics", "handle": "bike-frame", "options": [ { "name": "Material", "position": 1, "optionValues": [ { "name": "Aluminium" }, { "name": "Carbon" }, { "name": "Steel" } ] }, { "name": "Color", "position": 2, "optionValues": [ { "name": "Grey" }, { "name": "Black" }, { "name": "Silver" } ] } ], "variants": { "nodes": [ { "price": "94.99", "compareAtPrice": "99.99", "selectedOptions": [ { "name": "Material", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673030", "name": "Aluminium" } }, { "name": "Color", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673033", "name": "Grey" } } ] }, { "price": "259.99", "compareAtPrice": "299.99", "selectedOptions": [ { "name": "Material", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673031", "name": "Carbon" } }, { "name": "Color", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673034", "name": "Black" } } ] }, { "price": "169.99", "compareAtPrice": "199.99", "selectedOptions": [ { "name": "Material", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673032", "name": "Steel" } }, { "name": "Color", "optionValue": { "id": "gid://shopify/ProductOptionValue/1054673035", "name": "Silver" } } ] } ] } }, "userErrors": [] } } }