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.