Queues an import and returns at once with 202 Accepted. The job upserts contacts by phone number in the background with the same merge rules as Import contacts. Poll Get contact import job for progress and per-row errors.
Request#
Send one of three forms:
| Form | Content type | Description |
|---|---|---|
| CSV file | multipart/form-data |
One file part holding the CSV. Up to 50 MB. |
| CSV text | application/json |
{ "csv": "<csv text>" }. Up to 20,000,000 characters. |
| JSON rows | application/json |
{ "contacts": [ ... ] }. Each row takes the fields of Create contact. |
JSON bodies are limited to 25 MB. A job holds at most 50,000 rows.
CSV columns#
The first row is the header. These header names map to contact fields (case-insensitive; spaces and hyphens count as underscores):
| Header | Field |
|---|---|
phone, phone_number, number, mobile |
phone_number |
first_name, firstname, first |
first_name |
last_name, lastname, last |
last_name |
email, email_address |
email |
do_not_call, dnc |
do_not_call. 1, true, yes or y mean true. |
Every other column with a value becomes a custom field. Characters other than letters, digits and underscores in its name become underscores. Quoted fields, escaped quotes and CRLF line endings are supported.
Example request#
curl -X POST https://api.tried.com.au/create-contact-import-job \
-H "Authorization: Bearer $TRIED_API_KEY" \
-F "file=@contacts.csv;type=text/csv"import { readFile } from "node:fs/promises";
const form = new FormData();
form.append("file", new Blob([await readFile("contacts.csv")], { type: "text/csv" }), "contacts.csv");
const res = await fetch("https://api.tried.com.au/create-contact-import-job", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TRIED_API_KEY}` },
body: form,
});
const job = await res.json();import os, requests
with open("contacts.csv", "rb") as f:
res = requests.post(
"https://api.tried.com.au/create-contact-import-job",
headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
files={"file": ("contacts.csv", f, "text/csv")},
)
job = res.json()Example CSV:
phone number,first_name,appointment_time
+61412345678,Sam,Tuesday 3pm
+61498765432,Priya,Wednesday 10amResponse#
202 Accepted
{
"job_id": "contact_import_6d5c4b3a2f1e0d9c8b7a6f5e",
"status": "pending",
"source": "csv",
"total": 2,
"processed": 0,
"created": 0,
"updated": 0,
"errors": [],
"error": null,
"progress": 0,
"created_timestamp": 1760850000000,
"completed_timestamp": null
}The fields are described in Get contact import job.
Errors#
| Status | When |
|---|---|
400 |
No contacts to import (no rows after parsing), At most 50000 contacts per import, or Upload a CSV file (multipart request with no file). |
401 |
Missing or invalid API key. |
403 |
The key's IP allowlist or scopes reject the request, or the caller has the read-only member role. This route needs the calls scope. |
413 |
The JSON body is larger than 25 MB, or the file is larger than 50 MB. |
429 |
Rate limit exceeded. See Rate limits. |
See Errors for the body format.