curl -X POST "https://api.sayvy.ai/api/v1/contacts/bulk-upload" \
-H "Authorization: Bearer <token>" \
-F "file=@/path/to/contacts.csv"
import requests
url = "https://api.sayvy.ai/api/v1/contacts/bulk-upload"
headers = {
"Authorization": "Bearer <token>"
}
with open("contacts.csv", "rb") as f:
files = {"file": ("contacts.csv", f, "text/csv")}
response = requests.post(url, headers=headers, files=files)
print(response.status_code)
print(response.json())
const formData = new FormData();
formData.append("file", fileInputElement.files[0]);
const response = await fetch("https://api.sayvy.ai/api/v1/contacts/bulk-upload", {
method: "POST",
headers: {
"Authorization": "Bearer <token>"
},
body: formData
});
const data = await response.json();
console.log(data);
// Using Java 11+ HttpClient with multipart body publisher
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sayvy.ai/api/v1/contacts/bulk-upload"))
.header("Authorization", "Bearer <token>")
.POST(ofMimeMultipartData(Map.of("file", Paths.get("contacts.csv")), boundary))
.build();
HttpResponse<String> response =
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
{
"message": "Bulk upload completed. Processed 250 contacts.",
"total_processed": 250,
"created": 210,
"updated": 38,
"failed": 2,
"errors": [
"Row 42: Missing phone_number or name",
"Row 118: Invalid phone number format"
]
}
{
"detail": "Unsupported file format. Please upload CSV or Excel file."
}
{
"detail": "Missing required columns: phone_number, name"
}
{
"detail": "Unauthorized"
}
Contacts
Bulk upload contacts
Batch import contacts from CSV or Excel (.xlsx/.xls) spreadsheets with automatic deduplication
POST
/
api
/
v1
/
contacts
/
bulk-upload
curl -X POST "https://api.sayvy.ai/api/v1/contacts/bulk-upload" \
-H "Authorization: Bearer <token>" \
-F "file=@/path/to/contacts.csv"
import requests
url = "https://api.sayvy.ai/api/v1/contacts/bulk-upload"
headers = {
"Authorization": "Bearer <token>"
}
with open("contacts.csv", "rb") as f:
files = {"file": ("contacts.csv", f, "text/csv")}
response = requests.post(url, headers=headers, files=files)
print(response.status_code)
print(response.json())
const formData = new FormData();
formData.append("file", fileInputElement.files[0]);
const response = await fetch("https://api.sayvy.ai/api/v1/contacts/bulk-upload", {
method: "POST",
headers: {
"Authorization": "Bearer <token>"
},
body: formData
});
const data = await response.json();
console.log(data);
// Using Java 11+ HttpClient with multipart body publisher
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sayvy.ai/api/v1/contacts/bulk-upload"))
.header("Authorization", "Bearer <token>")
.POST(ofMimeMultipartData(Map.of("file", Paths.get("contacts.csv")), boundary))
.build();
HttpResponse<String> response =
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
{
"message": "Bulk upload completed. Processed 250 contacts.",
"total_processed": 250,
"created": 210,
"updated": 38,
"failed": 2,
"errors": [
"Row 42: Missing phone_number or name",
"Row 118: Invalid phone number format"
]
}
{
"detail": "Unsupported file format. Please upload CSV or Excel file."
}
{
"detail": "Missing required columns: phone_number, name"
}
{
"detail": "Unauthorized"
}
Upload a CSV or Excel spreadsheet to import or update large cohorts of contacts simultaneously. If a contact with an identical phone number already exists within your organization, their name and tags are updated in-place; otherwise, a new contact record is created.
Authentication
This endpoint requires Bearer token authentication.Authorization: Bearer <token>
| Header | Type | Required | Description | Format |
|---|---|---|---|---|
Authorization | string | Yes | Scoped organization API key or Bearer JWT token | Bearer <token> |
File Requirements
- Supported Formats:
.csv,.xlsx,.xls - Required Columns (case-insensitive headers):
phone_number: Destination telephone number (E.164 format recommended).name: Contact full name or display name.
- Optional Columns:
tags: Tag strings separated by commas or semicolons (e.g.vip; enterprise; q3_leads).
Example CSV Structure
phone_number,name,tags
+14155550101,Alice Smith,vip;retail
+14155550102,Bob Jones,lead;inbound
+14155550103,Carol White,enterprise
Input parameters
string
required
Bearer token for authentication. Format:
Bearer <token>.file
required
The multipart form file upload (
.csv, .xlsx, or .xls).Response Fields
string
Human-readable summary of upload completion.
number
Total number of row records parsed from the file.
number
Number of brand new contacts provisioned.
number
Number of existing contacts whose profile or tags were updated.
number
Number of invalid rows that failed to import.
string[]
Itemized error descriptions for rows that failed validation (e.g.
["Row 4: Missing phone_number or name"]).curl -X POST "https://api.sayvy.ai/api/v1/contacts/bulk-upload" \
-H "Authorization: Bearer <token>" \
-F "file=@/path/to/contacts.csv"
import requests
url = "https://api.sayvy.ai/api/v1/contacts/bulk-upload"
headers = {
"Authorization": "Bearer <token>"
}
with open("contacts.csv", "rb") as f:
files = {"file": ("contacts.csv", f, "text/csv")}
response = requests.post(url, headers=headers, files=files)
print(response.status_code)
print(response.json())
const formData = new FormData();
formData.append("file", fileInputElement.files[0]);
const response = await fetch("https://api.sayvy.ai/api/v1/contacts/bulk-upload", {
method: "POST",
headers: {
"Authorization": "Bearer <token>"
},
body: formData
});
const data = await response.json();
console.log(data);
// Using Java 11+ HttpClient with multipart body publisher
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sayvy.ai/api/v1/contacts/bulk-upload"))
.header("Authorization", "Bearer <token>")
.POST(ofMimeMultipartData(Map.of("file", Paths.get("contacts.csv")), boundary))
.build();
HttpResponse<String> response =
HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
{
"message": "Bulk upload completed. Processed 250 contacts.",
"total_processed": 250,
"created": 210,
"updated": 38,
"failed": 2,
"errors": [
"Row 42: Missing phone_number or name",
"Row 118: Invalid phone number format"
]
}
{
"detail": "Unsupported file format. Please upload CSV or Excel file."
}
{
"detail": "Missing required columns: phone_number, name"
}
{
"detail": "Unauthorized"
}
‹ PreviousOverview ›
Contacts Overview
Back to Contacts documentation hub
Was this page helpful?