curl --request POST \
--url https://{companyName}.api.joinluminous.com/external/api/v1/imports \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form type=master_skus \
--form file='@example-file' \
--form 'column_mapping={"MASTER_SKU":"Product ID","PRODUCT_NAME":"Name"}' \
--form email=jsmith@example.com \
--form 'job_name=<string>' \
--form 'options=<string>'import requests
url = "https://{companyName}.api.joinluminous.com/external/api/v1/imports"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"type": "master_skus",
"column_mapping": "{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}",
"email": "jsmith@example.com",
"job_name": "<string>",
"options": "<string>"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('type', 'master_skus');
form.append('file', '<string>');
form.append('column_mapping', '{"MASTER_SKU":"Product ID","PRODUCT_NAME":"Name"}');
form.append('email', 'jsmith@example.com');
form.append('job_name', '<string>');
form.append('options', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://{companyName}.api.joinluminous.com/external/api/v1/imports', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{companyName}.api.joinluminous.com/external/api/v1/imports",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{companyName}.api.joinluminous.com/external/api/v1/imports"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{companyName}.api.joinluminous.com/external/api/v1/imports")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://{companyName}.api.joinluminous.com/external/api/v1/imports")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"data": {
"id": 8421,
"type": "master_skus",
"stats": {
"total_rows": 1240,
"success_count": 1235,
"error_count": 5
},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"email": "ops@example.com",
"options": {},
"imported_by": "Jane Doe",
"job": {
"id": 123,
"job_id": "<string>",
"type": "<string>",
"status": "<string>",
"queue": "<string>",
"attempts": 123,
"progress_now": 123,
"progress_max": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"finished_at": "2023-11-07T05:31:56Z"
}
}
}{
"message": "<string>"
}{
"message": "<string>"
}Submit a bulk import
Create and queue a bulk-import job. Two payload formats are supported:
- CSV (recommended) —
multipart/form-datawith a.csvfile (up to 20 MB), the importtype, and an optionalcolumn_mappingJSON string (system field → CSV header). File uploads are recommended for speed: the server streams rows directly from disk rather than parsing a JSON array in memory, so throughput is significantly higher for non-trivial datasets. - JSON —
application/jsonwithtypeandrows(up to 10,000 items).column_mappinghere maps system field names → keys present in each row object. Use CSV upload for anything larger.
File support
| Extension | Accepted | Notes |
|---|---|---|
.csv | ✅ | Preferred. Comma-delimited, UTF-8, header row required. |
.txt | ✅ | Treated as CSV (same parser, same expectations). |
.xlsx / .xls | ❌ | Excel files are not accepted — export to CSV first. |
Other CSV details:
- Max upload size: 20 MB. Larger files are rejected with
422. - Header row: the first row must contain column names. Headers are trimmed of whitespace.
- Delimiter / quoting: standard CSV — comma delimiter, double-quote enclosure.
Use double quotes to wrap fields that contain commas, newlines, or quotes
(escape an embedded quote by doubling it:
""). - Empty rows are skipped automatically.
- Encoding: UTF-8 is strongly recommended. Other encodings may parse but can corrupt non-ASCII characters.
On success the endpoint returns 201 with the import record (including its
job progress fields). Poll GET /imports/{id} to track progress.
curl --request POST \
--url https://{companyName}.api.joinluminous.com/external/api/v1/imports \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form type=master_skus \
--form file='@example-file' \
--form 'column_mapping={"MASTER_SKU":"Product ID","PRODUCT_NAME":"Name"}' \
--form email=jsmith@example.com \
--form 'job_name=<string>' \
--form 'options=<string>'import requests
url = "https://{companyName}.api.joinluminous.com/external/api/v1/imports"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"type": "master_skus",
"column_mapping": "{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}",
"email": "jsmith@example.com",
"job_name": "<string>",
"options": "<string>"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('type', 'master_skus');
form.append('file', '<string>');
form.append('column_mapping', '{"MASTER_SKU":"Product ID","PRODUCT_NAME":"Name"}');
form.append('email', 'jsmith@example.com');
form.append('job_name', '<string>');
form.append('options', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://{companyName}.api.joinluminous.com/external/api/v1/imports', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{companyName}.api.joinluminous.com/external/api/v1/imports",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://{companyName}.api.joinluminous.com/external/api/v1/imports"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://{companyName}.api.joinluminous.com/external/api/v1/imports")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://{companyName}.api.joinluminous.com/external/api/v1/imports")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nmaster_skus\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"column_mapping\"\r\n\r\n{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"email\"\r\n\r\njsmith@example.com\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"job_name\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"options\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"data": {
"id": 8421,
"type": "master_skus",
"stats": {
"total_rows": 1240,
"success_count": 1235,
"error_count": 5
},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"email": "ops@example.com",
"options": {},
"imported_by": "Jane Doe",
"job": {
"id": 123,
"job_id": "<string>",
"type": "<string>",
"status": "<string>",
"queue": "<string>",
"attempts": 123,
"progress_now": 123,
"progress_max": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"finished_at": "2023-11-07T05:31:56Z"
}
}
}{
"message": "<string>"
}{
"message": "<string>"
}Authorizations
Authenticate using a bearer token. To create a token, navigate to /settings/api-tokens and click Create API Token.
Body
Import type key (see GET /imports/types)
"master_skus"
CSV file (.csv or .txt, max 20 MB)
JSON object as a string — system field name → CSV header name
"{\"MASTER_SKU\":\"Product ID\",\"PRODUCT_NAME\":\"Name\"}"
Email address to notify when the import finishes
Human-readable name for the job
255JSON object as a string — additional per-type options
Response
Import created and job queued
Bulk import job record. Returned from the imports endpoints and reflects the
async ImportJob that processes the rows.
Show child attributes
Show child attributes