Skip to main content

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 mutation to add data in a single operation. Learn more about syncing product data.



The GraphQL Admin API separates product creation from variant creation, giving you control over your product structure.

When you create a product with 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 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 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.


Anchor to Step 1: Create a product with optionsStep 1: Create a product with options

Use 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.

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

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

{
"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": []
}
}
}

Anchor to Step 2: Create product variantsStep 2: Create product variants

Use productVariantsBulkCreate to create your variants. The mutation accepts up to 2,048 variants in a single operation. You have two options:

Anchor to Option A: Replace the standalone variantOption A: Replace the standalone variant

Use the 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

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

{
"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": []
}
}
}

Anchor to Option B: Keep the standalone variantOption 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.

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

GraphQL mutation

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

{
"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": []
}
}
}


Was this page helpful?