Bulk mutation tasks
You can call the Create a bulk mutation task API to submit a complex data mutation request to SHOPLINE. A single bulk mutation task can only utilize one type of HTTP method, such as POST, PUT, PATCH or DELETE. Because this is an asynchronous task, the results are not returned immediately. The execution time varies depending on the complexity of the mutation. Once the task is complete, the system generates a temporary file in JSON Lines (JSONL) format containing the mutation results. This file expires after 12 hours.
Once the mutation task is submitted, you can call the Get a valid bulk task API to fetch its execution status and the result file URL. You can download the file via this URL and obtain the mutation result data.
Limits
The following limits apply to bulk mutation tasks:
- Concurrency: Bulk mutation tasks are executed sequentially on a per-store basis. Each store can have only one active bulk mutation task running at any given time. If a task is currently in progress, SHOPLINE will reject any additional bulk mutation tasks submitted for that store (regardless of whether they originate from the same app) until the current task is complete.
- Access scopes: The app must be granted both the
write_bulkoperationandread_bulkoperationaccess scopes. For more information on how to grant access scopes, refer to App authorization. - File restrictions: The file corresponding to the URL provided in the
file_urlrequest parameter must not exceed 10 MB. Additionally, the file must be in JSONL format, and the total number of data lines within the file cannot exceed 10,000. - API version:
v20220901or higher is required.
If your app does not call the Get a valid bulk task API promptly after its bulk mutation task completes, and another app for the same store submits a new bulk mutation task in the interim, subsequent calls to this API made by your app will return the execution results of that new task. To prevent data misalignment, we highly recommend that you call the Get a valid bulk task API immediately upon task completion to fetch your result data.
Procedure
Follow the steps to perform a bulk mutation task:
- Prepare a file: Prepare the mutation file required for the operation.
- Submit a task: Call the Create a bulk mutation task API to submit a bulk mutation task using the prepared mutation file.
- Poll for task status: Call the Get a valid bulk task API to check the task status and obtain the result file URL.
- Retrieve the results: Once the task is complete, download and parse the JSONL file using the returned URL to access the mutation results and proceed with your data processing. If the task is interrupted, the returned result file will be incomplete and only contain partial mutation results. In this case, you must identify the line number of the last entry in the partial result file and submit a new Create a bulk mutation task request.
Example: Import a batch of product data
To import a batch of product data into a SHOPLINE store, complete the process below:
Prerequisites
Make sure that your app has been granted the write_products, read_bulkoperation, and write_bulkoperation access scopes.
Step 1: Prepare a mutation file
Create a JSONL file based on the parameters required by Create a product. Each line in the file represents a single product creation request. The following example contains the data records of two product creation requests, where url, method, and payload map to the endpoint, HTTP method, and request payload of a standard product creation request:
{"url":"https://goodgoods.myshopline.com/admin/openapi/v20230901/products/products.json","method":"post","payload":{"product":{"published_scope":"web","body_html":"<p>Classic T-shirt - Red</p>","images":[{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"Classic T-shirt - Red"}],"vendor":"Demo Brand","subtitle":"Red classic cotton T-shirt","options":[{"values_images":{"Red":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000"},"name":"Color"}],"handle":"classic-t-shirt-red","variants":[{"image":{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"Classic T-shirt - Red"},"required_shipping":true,"compare_at_price":"11","taxable":true,"option5":"","weight":"1.2","inventory_policy":"deny","weight_unit":"kg","price":"10.11","option3":"","option4":"","inventory_tracker":true,"option1":"Red","option2":"","sku":"TSHIRT-RED-001","barcode":"6900000000001"}],"title":"Classic T-shirt - Red","product_category":"T-shirt","status":"active","tags":["t-shirt","red","bulk-import"]}}}
{"url":"https://goodgoods.myshopline.com/admin/openapi/v20230901/products/products.json","method":"post","payload":{"product":{"published_scope":"web","body_html":"<p>Classic T-shirt - Blue</p>","images":[{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"Classic T-shirt - Blue"}],"vendor":"Demo Brand","subtitle":"Blue classic cotton T-shirt","options":[{"values_images":{"Blue":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000"},"name":"Color"}],"handle":"classic-t-shirt-blue","variants":[{"image":{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"Classic T-shirt - Blue"},"required_shipping":true,"compare_at_price":"11","taxable":true,"option5":"","weight":"1.2","inventory_policy":"deny","weight_unit":"kg","price":"10.11","option3":"","option4":"","inventory_tracker":true,"option1":"Blue","option2":"","sku":"TSHIRT-BLUE-001","barcode":"6900000000002"}],"title":"Classic T-shirt - Blue","product_category":"T-shirt","status":"active","tags":["t-shirt","blue","bulk-import"]}}}
Step 2: Submit the mutation task
Call the Create a bulk mutation task API to submit your mutation task, passing the URL of the JSONL file created in the previous step into the file_url field of the request body.
Sample request:
curl --location -g --request POST 'https://{handle}.myshopline.com/admin/openapi/v20260901/bulk_operation_run_mutation_general.json' \
--header 'Authorization: Bearer {accessToken}' \
--header 'Content-Type: application/json; charset=utf-8' \
--data-raw '{
"file_url": "https://xxx.com/products.jsonl"
}'
If an HTTP status code of 200 is returned, it indicates that the task has been submitted successfully.
The file URL provided in the file_url request parameter must be publicly accessible without any authentication. Otherwise, the task execution will fail.
Step 3: Retrieve task status and results
Call the Get a valid bulk task API to obtain the status and results of the mutation task submitted in the previous step.
Alternatively, you can subscribe to the Bulk task status updated webhook notification. When the status of a bulk mutation task changes, the system will trigger this webhook notification. You can inspect the following fields within the notification payload to view the task details and obtain the result file URL:
status: The status of the task.type: The type of the task.url: The result file URL of the task.
Sample request:
curl --location -g --request GET 'https://{handle}.myshopline.com/admin/openapi/v20260901/current_bulk_operation.json?type=MUTATION_GENERAL' \
--header 'Authorization: Bearer {accessToken}' \
--header 'Content-Type: application/json; charset=utf-8' \
--data-raw ''
You must append type=MUTATION_GENERAL to the request URL to specify that you are requesting a bulk mutation task.
Sample response:
{
"partialDataUrl": null,
"createdAt": "2023-05-24T14:53:45+08:00",
"expiredAt": null,
"reason": null,
"completedAt": null,
"errorCode": null,
"id": "gid://shopline/BulkOperation/XX",
"type": "MUTATION_GENERAL",
"completedCount": 0,
"storeId": "xx",
"url": null,
"status": "CREATED"
}
Step 4: Download and parse the JSONL file
If the status field returned by the Get a valid bulk task API or the Bulk task status updated webhook notification is COMPLETED, it indicates that the bulk mutation task is complete. At this point, you can download the JSONL file using the URL provided by the url field in the response. Each line within this file is a standalone, valid JSON value, as shown in the following example:
{"product":{"image":{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"sdf","id":"5949197836163148889"},"body_html":"sdf","images":[{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"sdf","id":"5949197836163148889"}],"created_at":"2023-05-24T19:32:12+08:00","template_path":null,"handle":"t-shirt-2","variants":[{"inventory_quantity":0,"image":{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"sdf","id":"5949197836163148889"},"required_shipping":true,"compare_at_price":"11.00","taxable":true,"option5":null,"created_at":"2023-05-24T19:32:12+08:00","weight":"1.20","title":"Red","inventory_policy":"deny","updated_at":"2023-05-24T19:32:12+08:00","weight_unit":"kg","inventory_item_id":"5949197838801706542","price":"10.11","product_id":"16059491978375601928251954","option3":null,"option4":null,"inventory_tracker":true,"option1":"Red","id":"18059491978379292915831954","option2":null,"sku":"2111341123434","barcode":"1111111123434"}],"title":"sdf","tags":"sdfsdf3","published_scope":"web","product_type":"NORMAL","updated_at":"2023-05-24T19:32:12+08:00","vendor":"sdf","subtitle":"sdf","options":[{"product_id":"16059491978375601928251954","values":["Red"],"values_images":{"Red":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3"},"name":"Color","id":"16159491978379292915851954"}],"spu":null,"id":"16059491978375601928251954","published_at":"2023-05-24T19:32:12+08:00","product_behavior":"","product_category":"sdf","status":"active"}}
{"product":{"image":{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"sdf","id":"5949197836163148889"},"body_html":"sdf","images":[{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"sdf","id":"5949197836163148889"}],"created_at":"2023-05-24T19:32:12+08:00","template_path":null,"handle":"t-shirt-2","variants":[{"inventory_quantity":0,"image":{"src":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3b088a2f5d87658h.jpg?w=1000&h=1000","alt":"sdf","id":"5949197836163148889"},"required_shipping":true,"compare_at_price":"11.00","taxable":true,"option5":null,"created_at":"2023-05-24T19:32:12+08:00","weight":"1.20","title":"Red","inventory_policy":"deny","updated_at":"2023-05-24T19:32:12+08:00","weight_unit":"kg","inventory_item_id":"5949197838801706542","price":"10.11","product_id":"16059491978375601928251954","option3":null,"option4":null,"inventory_tracker":true,"option1":"Red","id":"18059491978379292915831954","option2":null,"sku":"2111341123434","barcode":"1111111123434"}],"title":"sdf","tags":"sdfsdf3","published_scope":"web","product_type":"NORMAL","updated_at":"2023-05-24T19:32:12+08:00","vendor":"sdf","subtitle":"sdf","options":[{"product_id":"16059491978375601928251954","values":["Red"],"values_images":{"Red":"https://img-va.myshopline.com/image/store/2000986376/1663054163488/Hbe20374eba504af8b3"},"name":"Color","id":"16159491978379292915851954"}],"spu":null,"id":"16059491978375601928251954","published_at":"2023-05-24T19:32:12+08:00","product_behavior":"","product_category":"sdf","status":"active"}}
You can use any programming language to parse this JSONL file for subsequent data processing.
Step 5: Handle interrupted tasks
If a bulk mutation task is interrupted for any reason, it will fail to complete the processing of all data. The generated JSONL file will only contain partial results executed up to the point of interruption. In such cases, you can obtain the partial result file URL from the partialDataUrl field returned by the Get a valid bulk task API and download the file.
The JSONL files provided by the url and partialDataUrl fields expire after 12 hours and will be permanently deleted afterwards.
After a bulk mutation task is interrupted, you can resume the mutation operation from where it left off using the partial result file by performing the following steps:
- Parse the last line of the partial result file.
- Locate this specific line number in the original mutation file created in Step 1: Prepare the mutation file.
- Delete all data lines prior to this line number.
- Save the updated file, and use it to call the Create a bulk mutation task API to submit a new request.
Troubleshooting
SHOPLINE may terminate the execution of a bulk mutation task. Common causes include:
- Insufficient access scopes: Your app does not have the access scopes required to modify the target resource. Grant the required access scopes to your app, then resubmit the task.
- Internal errors: The system encounters an unexpected internal error and fails to process your mutation request. You can try resubmitting the request.
- Expired access tokens: Your app's access token expired during task execution. You must obtain a valid access token and resubmit the request.