API Bulk Product Import

I am successfully uploading a JSONL file via the GQL API (only 1 product for testing):

{
“input”: {
“title”: “shopify1l”,
“descriptionHtml”: “

shopify1l

”,
“giftCard”: false,
“status”: “ACTIVE”,
“metafields”: {
“namespace”: “custom”,
“key”: “productid”,
“type”: “single_line_text_field”,
“value”: “352243”
},
“variants”: [
{
“price”: 19.99,
“sku”: “shopify1003800049”,
“inventoryItem”: {
“tracked”: false
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “L”
},
{
“optionName”: “Color”,
“name”: “Black”
}
]
},
{
“price”: 19.99,
“sku”: “shopify1003800259”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “L”
},
{
“optionName”: “Color”,
“name”: “Brown”
}
]
},
{
“price”: 19.99,
“sku”: “shopify100389”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “L”
},
{
“optionName”: “Color”,
“name”: “Dark Red”
}
]
},
{
“price”: 19.99,
“sku”: “shopify1004000049”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “M”
},
{
“optionName”: “Color”,
“name”: “Black”
}
]
},
{
“price”: 19.99,
“sku”: “shopify1004000259”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “M”
},
{
“optionName”: “Color”,
“name”: “Brown”
}
]
},
{
“price”: 19.99,
“sku”: “shopify100409”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “M”
},
{
“optionName”: “Color”,
“name”: “Dark Red”
}
]
},
{
“price”: 19.99,
“sku”: “shopify1004500049”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “S”
},
{
“optionName”: “Color”,
“name”: “Black”
}
]
},
{
“price”: 19.99,
“sku”: “shopify1004500259”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “S”
},
{
“optionName”: “Color”,
“name”: “Brown”
}
]
},
{
“price”: 19.99,
“sku”: “shopify100459”,
“inventoryItem”: {
“tracked”: true
},
“inventoryQuantities”: {
“locationId”: “gid://shopify/Location/71707263157”,
“name”: “available”,
“quantity”: 20
},
“optionValues”: [
{
“optionName”: “Size”,
“name”: “S”
},
{
“optionName”: “Color”,
“name”: “Dark Red”
}
]
}
]
}
}

and then requesting that it gets processed:
Dim bulkProductMutation
bulkProductMutation = “mutation call($input: ProductSetInput!) {”
bulkProductMutation = bulkProductMutation & " productSet(input: $input) {"
bulkProductMutation = bulkProductMutation & " product {"
bulkProductMutation = bulkProductMutation & " id"
bulkProductMutation = bulkProductMutation & " }"
bulkProductMutation = bulkProductMutation & " productSetOperation {"
bulkProductMutation = bulkProductMutation & " id"
bulkProductMutation = bulkProductMutation & " status"
bulkProductMutation = bulkProductMutation & " userErrors {"
bulkProductMutation = bulkProductMutation & " code"
bulkProductMutation = bulkProductMutation & " field"
bulkProductMutation = bulkProductMutation & " message"
bulkProductMutation = bulkProductMutation & " }"
bulkProductMutation = bulkProductMutation & " }"
bulkProductMutation = bulkProductMutation & " userErrors {"
bulkProductMutation = bulkProductMutation & " code"
bulkProductMutation = bulkProductMutation & " field"
bulkProductMutation = bulkProductMutation & " message"
bulkProductMutation = bulkProductMutation & " }"
bulkProductMutation = bulkProductMutation & " }"
bulkProductMutation = bulkProductMutation & “}”

	runMutation=" {""query"": ""mutation bulkOperationRunMutation { bulkOperationRunMutation( mutation: \""" & bulkProductMutation & "\"","
	runMutation=runMutation & "stagedUploadPath: \""" & keytmp & "\"") { "
	runMutation=runMutation & " bulkOperation {"
	runMutation=runMutation & "id "
	runMutation=runMutation & "url "
	runMutation=runMutation & "status "
	runMutation=runMutation & "}"
	runMutation=runMutation & " userErrors {"
	runMutation=runMutation & "message "
	runMutation=runMutation & "field "
	runMutation=runMutation & "}"
	runMutation=runMutation & "}"
	runMutation=runMutation & "}""}"

and then receive the following response back:

{“data”:{“bulkOperationRunMutation”:{“bulkOperation”:{“id”:“gid://shopify/BulkOperation/4508594143413”,“url”:null,“status”:“CREATED”},“userErrors”:}},“extensions”:{“cost”:{“requestedQueryCost”:10,“actualQueryCost”:10,“throttleStatus”:{“maximumAvailable”:2000.0,“currentlyAvailable”:1990,“restoreRate”:100.0}}}}

so shouldn’t the product appear in Products in the store?

1 Like

Long day, I forgot to check the results file. When I did, it had this to say:

{“data”:{“productSet”:{“product”:null,“productSetOperation”:null,“userErrors”:[{“code”:“PRODUCT_OPTIONS_INPUT_MISSING”,“field”:[“input”,“productOptions”],“message”:“Product options input is required when updating variants”}]}},“__lineNumber”:0}

Hi @Kevin_Cook

You change the JSON data to one line, with one line for each product

It is in one line, in a JSONL file. It just spread out when I pasted it.

The issue was that I was missing productOptions node. It’s in there now but now I’m getting the following error:
{“data”:{“productSet”:{“product”:null,“productSetOperation”:null,“userErrors”:[{“code”:“OPTIONS_OVER_LIMIT”,“field”:[“input”,“productOptions”],“message”:“Can only specify a maximum of 3 options”}]}},“__lineNumber”:0}

Hey @Kevin_Cook, even when working with increased variants, the current limit for options is still 3.

To confirm, you can query the ShopResourceLimits to see how many variants and options are possible on a particular shop.

So this is where I’m at now. This is the JSONL line:
{“productSet”: {“title”:“shopify1l”,“descriptionHtml”:“

shopify1l</p>”,“giftCard”:false,“status”:“ACTIVE”,“productOptions”:[{“name”:“Color”,“position”:1,“values”:[{“name”:“Black”},{“name”:“Brown”},{“name”:“Dark Red”}]},{“name”:“Size”,“position”:2,“values”:[{“name”:“L”},{“name”:“M”},{“name”:“S”}]}],“variants”:[{“price”:1.999000000000000e+001,“sku”:“shopify1003800049”,“inventoryItem”:{“tracked”:false},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"L"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify1003800259”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"L"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify100389”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"L"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify1004000049”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"M"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify1004000259”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"M"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify100409”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"M"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify1004500049”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"S"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify1004500259”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"S"}]”},{“price”:1.999000000000000e+001,“sku”:“shopify100459”,“inventoryItem”:{“tracked”:true},“inventoryQuantities”:{“locationId”:“gid://shopify/Location/71707263157”,“name”:“available”,“quantity”:20},“optionValues”:“[{"optionName":"Size","name":"S"}]”}]}}

I’m getting the error:
(Expected "[{\"optionName\":\"Size\",\"name\":\"L\"}]" to be a key-value object.)

Hey, looks like you’re passing your optionValues in a String instead of an Array

You’re using

"optionValues": "[{\"optionName\":\"Size\",\"name\":\"S\"}]"

instead of

"optionValues": [
  {"optionName": "Size", "name": "L"}
]

You’re right, thanks. Too long in code and couldn’t see the obvious!

Yep, that fixed it! Woo hoo!

1 Like