contacts
Async bulk contact import
POST /v1/contacts/bulk
Auth required
api.contacts.manage
Submits a batch of up to 5 000 contacts for asynchronous upsert.
The endpoint returns immediately with a job id and 202 Accepted;
poll GET /v1/contacts/bulk/{job_id} until status is completed
or failed.
Each row is processed independently — a single row's validation
failure (unknown attribute, bad email) marks that row failed while
the rest of the batch continues. The overall job never returns failed
due to per-row errors.
Supports the Idempotency-Key header: a duplicate key within 24 h
replays the original 202.
Request body
Content type: application/json
{
"contacts": [
{
"email": "user@example.com",
"attributes": {},
"unsubscribe_all": true,
"topic_preferences": [
{
"topic_name": "string",
"subscription_status": "OPT_IN"
}
],
"lists": {
"add": [
"00000000-0000-0000-0000-000000000000"
],
"remove": [
"00000000-0000-0000-0000-000000000000"
],
"set": [
"00000000-0000-0000-0000-000000000000"
]
}
}
]
} Responses
202 Batch accepted for async processing application/json
401 Missing, malformed, or unknown API key application/problem+json
403 Key lacks the required scope or plan limit violated application/problem+json
404 Resource not found application/problem+json
422 Query parameter or path value failed validation application/problem+json
429 Per-org rate limit exceeded application/problem+json
500 Unexpected server-side failure. The
code is internal_error. The
request_id field can be quoted to SendOps support to investigate.
application/problem+json