data object whose keys become script variables. This guide covers every contact operation in the API and the rules behind them.
Contacts can only be added to outbound agents. Inbound agents reject contact uploads with
400 Not allowed to create contacts on incoming campaigns.Contact object
When you add a contact, you send:string
required
The contact’s name. Available in scripts as
{{name}}.string
Primary phone number in international format, for example
+14155552671. Required for Voice and Text agents unless you send phoneNumbers.string[]
Several numbers for the same person. The first valid number becomes the primary number; the agent tries the numbers in order. Takes precedence over
phoneNumber.string
IANA time zone, such as
Europe/London. If omitted, Callers detects it from the phone number. Used when the agent calls in the contact’s time zone.object
required
Key/value pairs of strings that become script variables. Send
{} if you have none. For Email agents, include email.boolean
default:"false"
Create or update the contact as archived. Archived contacts aren’t called.
id, name, phoneNumber, status, attempts, lastAttempt, createdAt, failedReason, failedReasonDetails, and both campaignId and agentId (the same value).
Add a single contact
POST /agents/{agentId}/contacts
Response
400 with the reason, for example No contacts were added or modified. phoneNumber: Phone number is not valid: 225747466045.
Add contacts in bulk
POST /agents/{agentId}/contacts/bulk with { "contacts": [ ... ] }.
number
Contacts in the request.
number
New contacts created.
number
Existing contacts updated.
string[]
IDs of created or updated contacts. Returned when
verbose is false (default).object[]
Returned when
verbose=true.added + modified with requested to detect skips. Invalid data is the exception: if any contact’s data breaks the rules below, the whole request is rejected with 400.
Request bodies are limited to 1 MB. Split large lists into batches and send them one after another.
Validation rules
Phone numbers
- 7–20 characters: digits,
(,),-, optional leading+. Stored as digits only. - Must be a valid international number including the country code, unless the agent uses local dialing or you pass
ignorePhoneNumberValidation=true(single contact only). - Duplicates within one contact’s
phoneNumbersare ignored.
The data object
Values must be strings. Time zone keys inside
data are ignored; use the top-level timezone field.
Each validation problem appears in the error’s data array with a path (including the contact index for bulk) and a machine-readable params.code:
Duplicates and updates
Within an agent, a contact is identified by its primary phone number (for Email agents without a phone number, by its email address). When you add a contact that already exists:name,data, phone numbers, time zone, andarchivedare replaced with what you send.status,attempts, and call history are kept.- The response reports it as
modified/updated.
data is replaced, not merged: send every key you want to keep.
List and filter contacts
GET /agents/{agentId}/contacts
Contact statuses:
NEW, PENDING, PENDING_RETRY, SCHEDULED, IN_PROGRESS, COMPLETED, INTERESTED, NOT_INTERESTED, CALL_ME_LATER, DO_NOT_CALL, WRONG_NUMBER, VOICE_MAIL, UNREACHED, FAILED, SKIPPED. See Statuses and outcomes for what each means.
Calls across the agent
To reconcile outcomes without a contact ID, list calls for the whole agent and page through them:contactId, so you can join calls back to contacts. For the complete outcome of a call in the same shape your webhook receives, fetch /webhook-payload; see Backfill missed webhooks.
The report for an outbound agent returns totalContacts, totalCallsCount, answeredCallsCount, and contactsByStatuses (a count for each status: NEW, PENDING_RETRY, SCHEDULED, IN_PROGRESS, FAILED, UNREACHED, NOT_INTERESTED, INTERESTED, COMPLETED, SKIPPED, CALL_ME_LATER, WRONG_NUMBER, DO_NOT_CALL). See Launch outbound calls for a full example.
Archive contacts
Archiving removes contacts from the calling queue but keeps them and their history. All archive endpoints accept an optionalarchiveReason.
Bulk archive endpoints return
{ "archivedCount": n }.
Restore an archived contact
Add the contact again with the same phone number. Because uploads update existing contacts andarchived defaults to false, the contact is restored with its history, and the archive reason is cleared.
Do Not Call
Archiving stops one agent from calling a contact. To make sure nobody in your account calls a number, add it to the account’s Do Not Call list in the dashboard. See Do Not Call.Troubleshooting
'Contact has missing required fields: …'
'Contact has missing required fields: …'
The agent marks those variables as required. Add them to
data, or make them optional in the agent’s variables settings.'Phone number is not valid'
'Phone number is not valid'
The number lacks a country code or isn’t a real number for its country. Send
+ and the country code, or use fixUSPhoneNumber=true for 10-digit US numbers.My list filter returns 400
My list filter returns 400
Use
statuses[]=VALUE (with brackets), and check the values are uppercase status names.A variable is empty during calls
A variable is empty during calls
The key in
data must match the variable name exactly, including case. Keys with spaces are rejected; use first_name, not first name.Related
Launch outbound calls
The end-to-end outbound workflow.
Contact memory
Store facts the agent remembers across conversations.
Upload contacts in the dashboard
CSV import and manual entry.
Variables
How contact data reaches your script.