--- title: Add product data description: >- Learn how to create products with options and variants using the GraphQL Admin API. source_url: html: >- https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data md: >- https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md --- ExpandOn this page * [Requirements](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#requirements) * [How it works](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#how-it-works) * [Step 1: Create a product with options](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#step-1-create-a-product-with-options) * [Step 2: Create product variants](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#step-2-create-product-variants) * [Next steps](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#next-steps) # Add product data Use the GraphQL Admin API to create products with multiple options, option values, and variants. The API provides flexibility in how you structure your product creation workflow, from single operations that create everything at once to incremental mutations that build products step by step. 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 add 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're familiar with Shopify's [product model](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections#product-model), where products contain options (like color and size) and variants represent specific purchasable combinations. *** ## How it works The GraphQL Admin API separates product creation from variant creation, giving you control over your product structure. When you create a product with [`productCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productCreate), you define the product's options (like color and size) and their possible values. The API automatically creates one standalone variant using the first value from each option, ensuring the product is immediately purchasable. You then use [`productVariantsBulkCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkCreate) to create the specific variant combinations you need. This approach gives you flexibility: you can keep the standalone variant as part of your product matrix, or remove it using the [`REMOVE_STANDALONE_VARIANT`](https://shopify.dev/docs/api/admin-graphql/latest/enums/ProductVariantsBulkCreateStrategy#enums-REMOVE_STANDALONE_VARIANT) strategy if you want to define all variants yourself. The separation also means you can add variants to existing products without modifying the product itself. *** ## Step 1: Create a product with options Use [`productCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productCreate) to create a product with options and option values. The following example creates a product with two options: `Color` (`Red`, `Green`, `Blue`) and `Size` (`Small`, `Medium`, `Large`). Only `Red` and `Small` are assigned to the standalone variant—the other values are unused until you create variants in [Step 2](#step-2-create-product-variants). Caution Avoid leaving option values unused. Always create variants for all option values you define, or remove option values that you don't need. Unused option values can cause confusion and unexpected behavior. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation CreateProductWithOptions { productCreate(product: { title: "My cool socks", # Define the product's options and all their possible values. # This creates the option structure for variants. productOptions: [ { name: "Color", values: [ { name: "Red" }, { name: "Green" }, { name: "Blue" } ] }, { name: "Size", values: [ { name: "Small" }, { name: "Medium" }, { name: "Large" } ] } ] }) { product { id title # Request the options field to get option value IDs. # You'll need these IDs when creating variants. options { id name position optionValues { id name # hasVariants indicates if the value is assigned to any variant. # false = unused (not used by any variant yet) # true = assigned to at least one variant hasVariants } } # Request the variants field to see the standalone variant. # The API automatically creates one variant using the first value from each option. variants(first: 2048) { edges { node { id title price } } } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productCreate": { "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": false }, { "id": "gid://shopify/ProductOptionValue/3", "name": "Blue", "hasVariants": false } ] }, { "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": false }, { "id": "gid://shopify/ProductOptionValue/6", "name": "Large", "hasVariants": false } ] } ], "variants": { "edges": [ { "node": { "id": "gid://shopify/ProductVariant/101", "title": "Red / Small", "price": "0.00" } } ] } }, "userErrors": [] } } } ``` *** ## Step 2: Create product variants Use [`productVariantsBulkCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkCreate) to create your variants. The mutation accepts up to 2,048 variants in a single operation. You have two options: * [**Option A: Replace the standalone variant**](#option-a-replace-the-standalone-variant) (recommended): Use the `REMOVE_STANDALONE_VARIANT` strategy to remove the auto-created variant and define all variants yourself. This gives you full control over your variant matrix. * [**Option B: Keep the standalone variant**](#option-b-keep-the-standalone-variant): Add up to 2,047 additional variants alongside the auto-created standalone variant. ### Option A: Replace the standalone variant Use the [`REMOVE_STANDALONE_VARIANT`](https://shopify.dev/docs/api/admin-graphql/latest/enums/ProductVariantsBulkCreateStrategy#enums-REMOVE_STANDALONE_VARIANT) strategy to remove the auto-created variant and create all variants yourself. This approach gives you full control over your product's variant matrix. The following example removes the standalone variant and creates all nine variants for the 3x3 color/size matrix. ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation CreateAllVariants { productVariantsBulkCreate( productId: "gid://shopify/Product/456", # REMOVE_STANDALONE_VARIANT removes the auto-created Red / Small variant, # giving you full control over all variants. strategy: REMOVE_STANDALONE_VARIANT, # Define all nine variants for the 3x3 matrix. variants: [ { price: 4.99, optionValues: [ { name: "Red", optionName: "Color" }, { name: "Small", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Red", optionName: "Color" }, { name: "Medium", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Red", optionName: "Color" }, { name: "Large", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Green", optionName: "Color" }, { name: "Small", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Green", optionName: "Color" }, { name: "Medium", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Green", optionName: "Color" }, { name: "Large", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Blue", optionName: "Color" }, { name: "Small", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Blue", optionName: "Color" }, { name: "Medium", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Blue", optionName: "Color" }, { name: "Large", optionName: "Size" } ] } ] ) { productVariants { id title selectedOptions { name value } } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productVariantsBulkCreate": { "productVariants": [ { "id": "gid://shopify/ProductVariant/101", "title": "Red / Small", "selectedOptions": [ { "name": "Color", "value": "Red" }, { "name": "Size", "value": "Small" } ] }, { "id": "gid://shopify/ProductVariant/102", "title": "Red / Medium", "selectedOptions": [ { "name": "Color", "value": "Red" }, { "name": "Size", "value": "Medium" } ] }, { "id": "gid://shopify/ProductVariant/103", "title": "Red / Large", "selectedOptions": [ { "name": "Color", "value": "Red" }, { "name": "Size", "value": "Large" } ] }, { "id": "gid://shopify/ProductVariant/104", "title": "Green / Small", "selectedOptions": [ { "name": "Color", "value": "Green" }, { "name": "Size", "value": "Small" } ] }, { "id": "gid://shopify/ProductVariant/105", "title": "Green / Medium", "selectedOptions": [ { "name": "Color", "value": "Green" }, { "name": "Size", "value": "Medium" } ] }, { "id": "gid://shopify/ProductVariant/106", "title": "Green / Large", "selectedOptions": [ { "name": "Color", "value": "Green" }, { "name": "Size", "value": "Large" } ] }, { "id": "gid://shopify/ProductVariant/107", "title": "Blue / Small", "selectedOptions": [ { "name": "Color", "value": "Blue" }, { "name": "Size", "value": "Small" } ] }, { "id": "gid://shopify/ProductVariant/108", "title": "Blue / Medium", "selectedOptions": [ { "name": "Color", "value": "Blue" }, { "name": "Size", "value": "Medium" } ] }, { "id": "gid://shopify/ProductVariant/109", "title": "Blue / Large", "selectedOptions": [ { "name": "Color", "value": "Blue" }, { "name": "Size", "value": "Large" } ] } ], "userErrors": [] } } } ``` ### Option B: Keep the standalone variant If you want to keep the auto-created standalone variant as part of your product matrix, omit the `strategy` argument and create only the additional variants you need. The following example adds eight variants to complete the 3x3 matrix, keeping the auto-created Red / Small variant from [Step 1](#step-1-create-a-product-with-options). ## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json ## GraphQL mutation ```graphql mutation CreateAdditionalVariants { productVariantsBulkCreate( productId: "gid://shopify/Product/456", # Without the REMOVE_STANDALONE_VARIANT strategy, the auto-created # Red / Small variant is kept. Add only the remaining variants. variants: [ { price: 4.99, optionValues: [ { name: "Red", optionName: "Color" }, { name: "Medium", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Red", optionName: "Color" }, { name: "Large", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Green", optionName: "Color" }, { name: "Small", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Green", optionName: "Color" }, { name: "Medium", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Green", optionName: "Color" }, { name: "Large", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Blue", optionName: "Color" }, { name: "Small", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Blue", optionName: "Color" }, { name: "Medium", optionName: "Size" } ] }, { price: 4.99, optionValues: [ { name: "Blue", optionName: "Color" }, { name: "Large", optionName: "Size" } ] } ] ) { productVariants { id title } userErrors { field message } } } ``` ## JSON response ```json { "data": { "productVariantsBulkCreate": { "productVariants": [ { "id": "gid://shopify/ProductVariant/102", "title": "Red / Medium" }, { "id": "gid://shopify/ProductVariant/103", "title": "Red / Large" }, { "id": "gid://shopify/ProductVariant/104", "title": "Green / Small" }, { "id": "gid://shopify/ProductVariant/105", "title": "Green / Medium" }, { "id": "gid://shopify/ProductVariant/106", "title": "Green / Large" }, { "id": "gid://shopify/ProductVariant/107", "title": "Blue / Small" }, { "id": "gid://shopify/ProductVariant/108", "title": "Blue / Medium" }, { "id": "gid://shopify/ProductVariant/109", "title": "Blue / Large" } ], "userErrors": [] } } } ``` *** ## Next steps * Learn how to [update product data](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/update-data). * Learn how to [manage media for products](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/manage-media). * Explore the [`Product`](https://shopify.dev/docs/api/admin-graphql/latest/objects/Product) and [`ProductVariant`](https://shopify.dev/docs/api/admin-graphql/latest/objects/ProductVariant) objects in the GraphQL Admin API reference. *** * [Requirements](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#requirements) * [How it works](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#how-it-works) * [Step 1: Create a product with options](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#step-1-create-a-product-with-options) * [Step 2: Create product variants](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#step-2-create-product-variants) * [Next steps](https://shopify.dev/docs/apps/build/product-merchandising/products-and-collections/add-data.md#next-steps)