curl --request POST \
--url https://api.parallellabs.app/api/v0/lists/{listId}/import \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"projectId": "<string>",
"path": "<string>",
"sheet": "<string>",
"companyId": "<string>",
"headerMapping": {}
}
'import requests
url = "https://api.parallellabs.app/api/v0/lists/{listId}/import"
payload = {
"projectId": "<string>",
"path": "<string>",
"sheet": "<string>",
"companyId": "<string>",
"headerMapping": {}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
projectId: '<string>',
path: '<string>',
sheet: '<string>',
companyId: '<string>',
headerMapping: {}
})
};
fetch('https://api.parallellabs.app/api/v0/lists/{listId}/import', 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://api.parallellabs.app/api/v0/lists/{listId}/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'projectId' => '<string>',
'path' => '<string>',
'sheet' => '<string>',
'companyId' => '<string>',
'headerMapping' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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://api.parallellabs.app/api/v0/lists/{listId}/import"
payload := strings.NewReader("{\n \"projectId\": \"<string>\",\n \"path\": \"<string>\",\n \"sheet\": \"<string>\",\n \"companyId\": \"<string>\",\n \"headerMapping\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.parallellabs.app/api/v0/lists/{listId}/import")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"projectId\": \"<string>\",\n \"path\": \"<string>\",\n \"sheet\": \"<string>\",\n \"companyId\": \"<string>\",\n \"headerMapping\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.parallellabs.app/api/v0/lists/{listId}/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"projectId\": \"<string>\",\n \"path\": \"<string>\",\n \"sheet\": \"<string>\",\n \"companyId\": \"<string>\",\n \"headerMapping\": {}\n}"
response = http.request(request)
puts response.read_body{
"status": "<string>",
"taskId": "<string>",
"message": "<string>",
"rowCount": 123,
"msg": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Import CSV or Excel rows into a list.
Rows are added to the list, with file columns mapped by headerMapping. Imports over 100 rows run in the background: poll the returned taskId with lists_getTaskStatus. Confirm the mapping with lists_importPreview first.
curl --request POST \
--url https://api.parallellabs.app/api/v0/lists/{listId}/import \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"projectId": "<string>",
"path": "<string>",
"sheet": "<string>",
"companyId": "<string>",
"headerMapping": {}
}
'import requests
url = "https://api.parallellabs.app/api/v0/lists/{listId}/import"
payload = {
"projectId": "<string>",
"path": "<string>",
"sheet": "<string>",
"companyId": "<string>",
"headerMapping": {}
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
projectId: '<string>',
path: '<string>',
sheet: '<string>',
companyId: '<string>',
headerMapping: {}
})
};
fetch('https://api.parallellabs.app/api/v0/lists/{listId}/import', 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://api.parallellabs.app/api/v0/lists/{listId}/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'projectId' => '<string>',
'path' => '<string>',
'sheet' => '<string>',
'companyId' => '<string>',
'headerMapping' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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://api.parallellabs.app/api/v0/lists/{listId}/import"
payload := strings.NewReader("{\n \"projectId\": \"<string>\",\n \"path\": \"<string>\",\n \"sheet\": \"<string>\",\n \"companyId\": \"<string>\",\n \"headerMapping\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.parallellabs.app/api/v0/lists/{listId}/import")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"projectId\": \"<string>\",\n \"path\": \"<string>\",\n \"sheet\": \"<string>\",\n \"companyId\": \"<string>\",\n \"headerMapping\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.parallellabs.app/api/v0/lists/{listId}/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"projectId\": \"<string>\",\n \"path\": \"<string>\",\n \"sheet\": \"<string>\",\n \"companyId\": \"<string>\",\n \"headerMapping\": {}\n}"
response = http.request(request)
puts response.read_body{
"status": "<string>",
"taskId": "<string>",
"message": "<string>",
"rowCount": 123,
"msg": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Authorizations
Company API key - scoped to a specific company. Generate from the Integrations page in your dashboard.
Path Parameters
Body
The CSV or Excel file to import and its column mapping
Request body for importing CSV or Excel rows into a list. Send a CSV or Excel file (.csv, .xlsx, .xls) as multipart file, or name one saved in a project with projectId and path (files uploaded to a chat are saved under /uploads/ in the chat's project). For a workbook, sheet picks the sheet; the first sheet is the default. Imports over 100 rows run in the background and respond 202 with a taskId. Only one file import runs per list at a time (409 otherwise).
Project (UUID) holding the file. Use with path instead of uploading a file.
Path of the file in the project, e.g. "/uploads/contacts.csv".
Workbook sheet to read. Defaults to the first sheet; ignored for CSV.
Company ID that owns the list. Required when authenticating with a personal access key (pak_…) — the key is not tied to a specific company so the server cannot infer it. Required when authenticating with a company API key only if the key belongs to a user who has access to multiple companies; otherwise it defaults to the key's company. Optional for JWT (dashboard) auth — defaults to the user's active company.
Maps each file column name to the id of an existing list column, "new" to add it as a new column, or "ignore" to skip it. Get the suggested mapping from lists_importPreview. When omitted, the suggested mapping is used. In multipart requests, send it as a JSON string.
Response
Import finished (200) or started in the background (202)
Result of a file import: "background" with a taskId (202) for imports over 100 rows, otherwise msg "Success" (200) once the rows are imported.
"background" when the import runs asynchronously.
Background task ID (UUID). Poll it with lists_getTaskStatus until status is "completed", "failed", or "cancelled".
Human-readable status message.
Number of rows being imported.
"Success" when a small import finished immediately.

