Bulk Product Import
This guide describes mutations allowing users to create multiple products and variants in Saleor.
To perform bulk operations on products and variants, you need the MANAGE_PRODUCTS
permission.
Error Policy
productBulkCreate
, productVariantBulkCreate
, and productVariantBulkUpdate
mutations accept errorPolicy
argument, which determines how to handle errors.
productBulkCreate
Mutation productBulkCreate
allows to create multiple products in a single operation. This is particularly useful when you need to:
- Import products from another system
- Create multiple products with their variants at once
- Set up initial product catalog
The mutation supports creating products with their:
- Basic information (name, description, etc.)
- Attributes and values
- Channel listings and pricing
- Media files
- Variants with their own attributes, stocks, and channel listings
Example Mutation
mutation ProductBulkCreate($products: [ProductBulkCreateInput!]!, $errorPolicy: ErrorPolicyEnum) {
productBulkCreate(products: $products, errorPolicy: $errorPolicy) {
count
results {
errors {
...Error
}
product {
id
}
}
}
}
fragment Error on ProductBulkCreateError {
path
message
code
attributes
values
warehouses
channels
}
Input example:
{
"errorPolicy": "REJECT_FAILED_ROWS",
"products": [
{
"productType": "UHJvZHVjdFR5cGU6MTg=",
"name": "Barebarics Zing - White & Beige",
"attributes": [
{
"id": "QXR0cmlidXRlOjM2",
"values": ["Vegan"]
}
],
"category": "Q2F0ZWdvcnk6Mjg=",
"channelListings": [
{
"channelId": "Q2hhbm5lbDoy",
"isPublished": true,
"visibleInListings": true,
"isAvailableForPurchase": true
},
{
"channelId": "Q2hhbm5lbDox",
"isPublished": true,
"visibleInListings": true,
"isAvailableForPurchase": true
}
],
"media": [
{"mediaUrl": "https://user-images.githubusercontent.com/4006792/214636328-8e4f83e8-66cb-4114-a3d8-473eb908b9c3.png"}
]
},
{
"productType": "UHJvZHVjdFR5cGU6MTg=",
"name": "Zing - Black & White - Leather",
"attributes": [
{
"id": "QXR0cmlidXRlOjM2",
"values": [
"Leather"
]
}
],
"category": "Q2F0ZWdvcnk6Mjg=",
"channelListings": [
{
"channelId": "Q2hhbm5lbDoy",
"isPublished": true,
"visibleInListings": true,
"isAvailableForPurchase": true
},
{
"channelId": "Q2hhbm5lbDox",
"isPublished": true,
"visibleInListings": true,
"isAvailableForPurchase": true
}
],
"variants": [
{
"sku": "60217252-00-42",
"attributes": [
{
"id": "QXR0cmlidXRlOjM3",
"values": [
"40"
]
}
],
"stocks": [
{
"warehouse": "V2FyZWhvdXNlOjJiNDY1OTU2LWYzMmUtNGU4OC04ZWQyLTBhN2I4ODBlMTkxYg==",
"quantity": 100
}
],
"channelListings": [
{
"channelId": "Q2hhbm5lbDoy",
"price": 599
},
{
"channelId": "Q2hhbm5lbDox",
"price": 149
}
]
},
{
"sku": "60217252-00-43",
"attributes": [
{
"id": "QXR0cmlidXRlOjM3",
"values": [
"41"
]
}
],
"stocks": [
{
"warehouse": "V2FyZWhvdXNlOjJiNDY1OTU2LWYzMmUtNGU4OC04ZWQyLTBhN2I4ODBlMTkxYg==",
"quantity": 100
}
],
"channelListings": [
{
"channelId": "Q2hhbm5lbDoy",
"price": 599
},
{
"channelId": "Q2hhbm5lbDox",
"price": 149
}
]
},
{
"sku": "60217252-00-44",
"attributes": [
{
"id": "QXR0cmlidXRlOjM3",
"values": [
"42"
]
}
],
"stocks": [
{
"warehouse": "V2FyZWhvdXNlOjJiNDY1OTU2LWYzMmUtNGU4OC04ZWQyLTBhN2I4ODBlMTkxYg==",
"quantity": 100
}
],
"channelListings": [
{
"channelId": "Q2hhbm5lbDoy",
"price": 599
},
{
"channelId": "Q2hhbm5lbDox",
"price": 149
}
]
}
]
}
]
}
Input details
For detailed information about all available fields, see the ProductBulkCreateInput
.
The productType
field is required and must reference a valid product type ID.
Product name
must be provided when importing products.
Key fields to consider:
- Attributes: Allows to define product attributes. Each attribute should include its ID and values. See
AttributeValueInput
for details. - Channel Listings: Allows to specify where and how the product is available. See
ProductChannelListingCreateInput
for details. Each listing requires:channelId
: ID of the channelisPublished
: Whether the product is published in this channelvisibleInListings
: Whether the product is visible in channel listingsisAvailableForPurchase
: Whether the product can be purchased in this channel
- Taxes: Allows to assign tax class to the product. Must reference a valid tax class ID.
- Media: Allows to add images and other media files to the product.
- Variants: Allows to create variants along with product creation. See
ProductVariantBulkCreateInput
for details.
Error handling
Each product in the bulk operation can have its own set of errors.
These errors appear in results[].errors
array and are specific to individual products.
Common error scenarios include:
-
Channel-related errors:
NOT_FOUND
: Channel ID doesn't existPRODUCT_NOT_ASSIGNED_TO_CHANNEL
: Product variant channel listing references a channel where the product is not availableDUPLICATED_INPUT_ITEM
: Channel ID is duplicated in the input
-
Variant-related errors:
UNIQUE
: SKU already exists in the systemREQUIRED
: Missing required fields for variant creationINVALID_PRICE
: Price value is invalid
-
Attribute-related errors:
INVALID
: Invalid attribute valueREQUIRED
: Missing required attribute
productVariantBulkCreate
Mutation productVariantBulkCreate
allows to create multiple variants for an existing product in a single operation. This is particularly useful when you need to:
- Add new variants to an existing product
- Import variants from another system
- Create multiple variants with different attributes and prices
The mutation supports creating variants with their:
- Basic information (SKU, name)
- Attributes and values
- Stocks and quantities
- Channel listings and pricing
Example Mutation
mutation ProductVariantBulkCreate($variants: [ProductVariantBulkCreateInput!]!, $errorPolicy: ErrorPolicyEnum, $product: ID!) {
productVariantBulkCreate(
product: $product
variants: $variants
errorPolicy: $errorPolicy
) {
count
errors {
field
code
message
}
results {
errors {
...Error
}
productVariant {
id
}
}
}
}
fragment Error on ProductVariantBulkError {
field
path
code
message
attributes
values
warehouses
channels
channelListings
}
Input example:
{
"product": "UHJvZHVjdDoxOTg=",
"errorPolicy": "REJECT_FAILED_ROWS",
"variants": [
{
"sku": "60217252-00-50",
"attributes": [
{
"id": "QXR0cmlidXRlOjM3",
"values": ["42"]
}
],
"stocks": [
{
"warehouse": "V2FyZWhvdXNlOjJiNDY1OTU2LWYzMmUtNGU4OC04ZWQyLTBhN2I4ODBlMTkxYg==",
"quantity": 100
}
],
"channelListings": [
{
"channelId": "Q2hhbm5lbDoy",
"price": 599
},
{
"channelId": "Q2hhbm5lbDox",
"price": 149
}
]
},
{
"sku": "60217252-00-51",
"attributes": [
{
"id": "QXR0cmlidXRlOjM3",
"values": ["43"]
}
],
"stocks": [
{
"warehouse": "V2FyZWhvdXNlOjJiNDY1OTU2LWYzMmUtNGU4OC04ZWQyLTBhN2I4ODBlMTkxYg==",
"quantity": 100
}
],
"channelListings": [
{
"channelId": "Q2hhbm5lbDoy",
"price": 599
},
{
"channelId": "Q2hhbm5lbDox",
"price": 149
}
]
}
]
}
Input details
For detailed information about all available fields, see the ProductVariantBulkCreateInput
.
The product
field is required and must reference a valid product ID.
The variants
list is required.
Key fields to consider:
- Attributes: Allows to define variant attributes. Attributes list is required when creating new variants but can be empty.
Each attribute should include its ID and values. See
BulkAttributeValueInput
for details. - Stocks: Allows to set initial stock quantities for warehouses. Each stock requires:
warehouse
: ID of the warehousequantity
: Initial stock quantity
- Channel Listings: Allows to set prices for channels. Each listing requires:
channelId
: ID of the channelprice
: Price in the channel's currency
Error handling
When creating variants, errors can occur at different levels:
-
Operation-level errors: Appear in the top-level
errors
array and affect the entire operation. These include:- Invalid product ID
- Missing required fields for the entire operation
-
Variant-level errors: Appear in
results[].errors
and are specific to individual variants.
Common error scenarios include:
-
Variant-related errors:
UNIQUE
: SKU already exists in the systemREQUIRED
: Missing required fields for variant creationINVALID_PRICE
: Price value is invalid
-
Channel-related errors:
NOT_FOUND
: Channel ID doesn't existPRODUCT_NOT_ASSIGNED_TO_CHANNEL
: Variant channel listing references a channel where the product is not availableDUPLICATED_INPUT_ITEM
: Channel ID is duplicated in the input
-
Attribute-related errors:
REQUIRED
: Missing required attribute field:id
orexternal_references
NOT_FOUND
: Attribute ID doesn't existATTRIBUTE_CANNOT_BE_ASSIGNED
: Given attributes are not variant attributes
-
Stock-related errors:
NOT_FOUND
: Warehouse ID doesn't exist
productVariantBulkUpdate
Mutation productVariantBulkUpdate
allows to update multiple variants in a single operation. This is particularly useful when you need to:
- Update prices across multiple variants
- Modify stock quantities in bulk
- Update variant attributes
- Change channel availability
The mutation supports updating variants with their:
- Basic information (SKU, name)
- Attributes and values
- Stocks and quantities
- Channel listings and pricing
- And many more available variant fields
Example Mutation
mutation ProductVariantBulkUpdate($product: ID!, $variants: [ProductVariantBulkUpdateInput!]!, $errorPolicy: ErrorPolicyEnum) {
productVariantBulkUpdate(
product: $product
variants: $variants
errorPolicy: $errorPolicy
) {
count
errors {
field
code
message
}
results {
errors {
...Error
}
productVariant {
id
}
}
}
}
fragment Error on ProductVariantBulkError {
field
path
code
message
attributes
values
warehouses
channels
channelListings
}
Input example:
{
"product": "UHJvZHVjdDoxOTg=",
"errorPolicy": "REJECT_FAILED_ROWS",
"variants": [
{
"id": "UHJvZHVjdFZhcmlhbnQ6NDE4",
"channelListings": {
"create": [],
"update": [{
"channelListing": "UHJvZHVjdFZhcmlhbnRDaGFubmVsTGlzdGluZzo0MzE=",
"price": 100
}],
"remove": ["UHJvZHVjdFZhcmlhbnRDaGFubmVsTGlzdGluZzo0MzI="]
},
"stocks": {
"create": [{
"warehouse": "V2FyZWhvdXNlOjJkNTE0YWI0LWNhNTMtNDNjYy1hYWI2LWRlNzllZTYxMjBkOQ==",
"quantity": 150
}],
"update": [],
"remove": []
}
},
{
"id": "UHJvZHVjdFZhcmlhbnQ6NDE3",
"channelListings": {
"create": [],
"update": [{
"channelListing": "UHJvZHVjdFZhcmlhbnRDaGFubmVsTGlzdGluZzo0MzE=",
"price": 100
}],
"remove": ["UHJvZHVjdFZhcmlhbnRDaGFubmVsTGlzdGluZzo0MzI="]
},
"stocks": {
"create": [{
"warehouse": "V2FyZWhvdXNlOjJkNTE0YWI0LWNhNTMtNDNjYy1hYWI2LWRlNzllZTYxMjBkOQ==",
"quantity": 150
}],
"update": [],
"remove": []
}
}
]
}
Input details
For detailed information about all available fields, see the ProductVariantBulkUpdateInput
.
The product
field is required and must reference a valid product ID.
The id
field in variants list is required and must reference a valid variant ID.
Key fields to consider:
-
Channel Listings: Allows to manage variant channel listings with three operations:
create
: Add new channel listingsupdate
: Modify existing channel listings by providing:channelListing
: ID of the channel listing to updateprice
: New price in the channel's currency
remove
: Remove channel listings by providing their IDs
-
Stocks: Allows to manage variant stocks with three operations:
create
: Add new stock entries with:warehouse
: ID of the warehousequantity
: Initial stock quantity
update
: Modify existing stock entriesremove
: Remove stock entries by providing their IDs
-
Attributes: Allows to update variant attributes. Each attribute should include its ID and values. See
BulkAttributeValueInput
for details.
Error handling
When updating variants, errors can occur at different levels:
-
Operation-level errors: Appear in the top-level
errors
array and affect the entire operation. These include:- Invalid product ID
- Missing required fields for the entire operation
-
Variant-level errors: Appear in
results[].errors
and are specific to individual variants.
Common error scenarios include:
-
Variant-related errors:
UNIQUE
: SKU already exists in the systemREQUIRED
: Missing required fields for variant updateINVALID_PRICE
: Price value is invalid
-
Channel-related errors:
NOT_FOUND
: Channel ID doesn't existPRODUCT_NOT_ASSIGNED_TO_CHANNEL
: Variant channel listing references a channel where the product is not availableDUPLICATED_INPUT_ITEM
: Channel ID is duplicated in the input
-
Attribute-related errors:
REQUIRED
: Missing required attribute field:id
orexternal_references
NOT_FOUND
: Attribute ID doesn't existATTRIBUTE_CANNOT_BE_ASSIGNED
: Given attributes are not variant attributes
-
Stock-related errors:
NOT_FOUND
: Warehouse ID doesn't existSTOCK_ALREADY_EXISTS
: Warehouse is already assigned to given variant
Webhooks
Bulk operations emit webhook events for each created entity. The following mutations trigger these events:
-
productBulkCreate
:PRODUCT_CREATED
: For each created productPRODUCT_VARIANT_CREATED
: For each created variant (if variants are included in the input)
-
productVariantBulkCreate
:PRODUCT_VARIANT_CREATED
: For each created variant
-
productVariantBulkUpdate
:PRODUCT_VARIANT_UPDATED
: For each updated variant
For large bulk imports, consider disabling webhooks to improve performance. Each created entity will trigger a webhook event, which might impact the overall import speed.