# Create and update many variants at once

> Add new sizes or colors with productVariantsBulkCreate and change prices on many variants with productVariantsBulkUpdate, one product per call.

Page: https://lintelagency.com/resources/graphql/bulk-create-update-variants

## In short

To add variants to a product, call productVariantsBulkCreate with the productId and a list of variants: optionValues, price, inventoryItem (SKU) and starting stock per location. To change existing variants, call productVariantsBulkUpdate with each variant’s id and the fields to change, such as price and compareAtPrice. Both work on one product per call and return userErrors for invalid variants.

## Facts

- **API:** Admin GraphQL API
- **Operations:** productVariantsBulkCreate, productVariantsBulkUpdate
- **Access scope:** write_products
- **Replaces (REST):** POST /admin/api/products/{id}/variants.json and PUT /admin/api/variants/{id}.json
- **API version:** 2026-10
- **Last checked:** 2 November 2026

## How to use it

1. Send AddVariants with the product ID and one entry per new variant. A new option value, such as XL, is added to the product’s Size option automatically.
2. Set the SKU under inventoryItem; the variant input has no sku field of its own. inventoryQuantities sets the starting stock per location.
3. Use strategy REMOVE_STANDALONE_VARIANT when the product only has its single placeholder variant and you want it gone.
4. To change prices later, send UpdateVariantPrices with the variant IDs and the new price and compareAtPrice.

## Code

### product-variants-bulk-create.graphql

```graphql
mutation AddVariants($productId: ID!, $variants: [ProductVariantsBulkInput!]!, $strategy: ProductVariantsBulkCreateStrategy) {
  productVariantsBulkCreate(productId: $productId, variants: $variants, strategy: $strategy) {
    productVariants {
      id
      title
      price
      inventoryItem {
        sku
      }
    }
    userErrors {
      code
      field
      message
    }
  }
}
```

### product-variants-bulk-create.variables.json

```json
{
  "productId": "gid://shopify/Product/1234567890",
  "strategy": "REMOVE_STANDALONE_VARIANT",
  "variants": [
    {
      "optionValues": [{"optionName": "Size", "name": "XL"}],
      "price": "52.00",
      "inventoryItem": {"sku": "LS-XL", "tracked": true},
      "inventoryQuantities": [{"locationId": "gid://shopify/Location/1234567890", "availableQuantity": 8}]
    },
    {
      "optionValues": [{"optionName": "Size", "name": "XXL"}],
      "price": "52.00",
      "inventoryItem": {"sku": "LS-XXL", "tracked": true},
      "inventoryQuantities": [{"locationId": "gid://shopify/Location/1234567890", "availableQuantity": 4}]
    }
  ]
}
```

### product-variants-bulk-create.response.json

```json
{
  "data": {
    "productVariantsBulkCreate": {
      "productVariants": [
        {"id": "gid://shopify/ProductVariant/1111111114", "title": "XL", "price": "52.00", "inventoryItem": {"sku": "LS-XL"}},
        {"id": "gid://shopify/ProductVariant/1111111115", "title": "XXL", "price": "52.00", "inventoryItem": {"sku": "LS-XXL"}}
      ],
      "userErrors": []
    }
  }
}
```

### product-variants-bulk-update.graphql

```graphql
mutation UpdateVariantPrices($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
  productVariantsBulkUpdate(productId: $productId, variants: $variants) {
    productVariants {
      id
      price
      compareAtPrice
    }
    userErrors {
      code
      field
      message
    }
  }
}
```

### product-variants-bulk-update.variables.json

```json
{
  "productId": "gid://shopify/Product/1234567890",
  "variants": [
    {"id": "gid://shopify/ProductVariant/1111111111", "price": "39.00", "compareAtPrice": "49.00"},
    {"id": "gid://shopify/ProductVariant/1111111112", "price": "39.00", "compareAtPrice": "49.00"}
  ]
}
```

### product-variants-bulk-update.response.json

```json
{
  "data": {
    "productVariantsBulkUpdate": {
      "productVariants": [
        {"id": "gid://shopify/ProductVariant/1111111111", "price": "39.00", "compareAtPrice": "49.00"},
        {"id": "gid://shopify/ProductVariant/1111111112", "price": "39.00", "compareAtPrice": "49.00"}
      ],
      "userErrors": []
    }
  }
}
```

## Limits and edge cases

- Each call works on one product. For many products, run the mutation in a bulk operation or call productSet per product.
- Stores can have up to 2048 variants per product by default.
- By default, one invalid variant stops the whole update. Pass allowPartialUpdates: true to save the valid ones.
- Prices are Money scalars: send and receive them as strings such as "49.00".

## Questions

### How do I add a new size to a Shopify product with GraphQL?

Call productVariantsBulkCreate with the product ID and a variant whose optionValues name the option and the new value, for example Size: XL. Shopify adds the value to the option.

### How do I bulk update variant prices?

Call productVariantsBulkUpdate per product with each variant’s id and new price. For thousands of products, run that mutation in a bulk operation with a JSONL file.

### Where do I set the SKU and barcode?

The SKU goes in inventoryItem.sku. Barcodes go in the barcodes list of the variant input.

## Shopify documentation

- [productVariantsBulkCreate](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkCreate)
- [productVariantsBulkUpdate](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productVariantsBulkUpdate)

## Related

- [Create or update a whole product with productSet](https://lintelagency.com/resources/graphql/product-set)
- [Import data with a staged upload and bulkOperationRunMutation](https://lintelagency.com/resources/graphql/bulk-import-with-staged-upload)
- [Set stock levels from an external system](https://lintelagency.com/resources/graphql/set-inventory-quantities)

License: MIT. Free to use in your own store and in client work.
