curl --request POST \
--url https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/records \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"records": [
{
"phone": "9698XXXXXX",
"external_id": "LN-123",
"variables": {
"borrower_first_name": "Ravi",
"emi_amount": "4574",
"due_date": "2026-11-05"
}
},
{
"phone": "+9198XXXXXX02",
"external_id": "LN-124",
"variables": {
"borrower_first_name": "Sunita",
"emi_amount": "3400",
"due_date": "2026-11-05"
}
}
]
}
'{
"received": 1200,
"added": 1184,
"skipped": {
"invalid_phone": 7,
"duplicate": 3,
"missing_variables": 2,
"do_not_call": 4
},
"invalid": [
{
"row": 41,
"phone": "12345",
"reason": "invalid_phone"
}
],
"missing": [
{
"row": 4,
"phone": "+9198XXXXXX03",
"missing": [
"emi_amount",
"due_date"
]
}
]
}Add records to a campaign
Adds records. A csv campaign takes a CSV file (multipart/form-data, field file, or JSON
{ "csv": "..." }) until its first call is placed. An api campaign takes JSON records
({ "records": [...] } or a plain array, 1 to 5000 per request) until it is completed or canceled, also while
it runs. Sending the other kind answers 422 input_type_mismatch. At most 5000 records and 6 MB per request.
In a CSV file the phone column is csv.phone_column when the campaign names one, else it is found as in
POST /v1/campaigns/csv-preview. Columns are mapped to agent variables by csv.mapping; a column with the
variable’s own name maps itself, and every other column is kept as an extra variable.
Each record is taken in like this, in order:
- The phone number is normalized like a call number. An invalid number is skipped when
execution.skip_invalid_phonesis on; otherwise the whole request is refused with422 invalid_phones. - A number (or
external_id) already in the campaign is skipped as a duplicate whenexecution.skip_duplicatesis on. - A number on your do-not-call list is closed (
result: do_not_call) whenexecution.dnc_enabledis on. - Variables are resolved: the record’s own value, else the campaign’s static value, else the agent’s default.
A record still missing a required variable is skipped (
result: missing_variables). - Every other record is
pending. In a running or paused campaign its first attempt is planned at once, counting today as its day 1.
curl -X POST https://api.voice.mergenlab.com/v1/campaigns/cmp_.../records \
-H "Authorization: Bearer vg_live_..." -F file=@records.csv
curl --request POST \
--url https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/records \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"records": [
{
"phone": "9698XXXXXX",
"external_id": "LN-123",
"variables": {
"borrower_first_name": "Ravi",
"emi_amount": "4574",
"due_date": "2026-11-05"
}
},
{
"phone": "+9198XXXXXX02",
"external_id": "LN-124",
"variables": {
"borrower_first_name": "Sunita",
"emi_amount": "3400",
"due_date": "2026-11-05"
}
}
]
}
'{
"received": 1200,
"added": 1184,
"skipped": {
"invalid_phone": 7,
"duplicate": 3,
"missing_variables": 2,
"do_not_call": 4
},
"invalid": [
{
"row": 41,
"phone": "12345",
"reason": "invalid_phone"
}
],
"missing": [
{
"row": 4,
"phone": "+9198XXXXXX03",
"missing": [
"emi_amount",
"due_date"
]
}
]
}Authorizations
Authorization: Bearer vg_live_<32 hex characters>. Keys are issued by Mergen admins and shown once.
Missing or invalid key: 401 unauthorized. Suspended account: 403 tenant_suspended.
Path Parameters
Campaign id (cmp_ + 32 hex characters).
Body
- Option 1 · object
- Option 2 · object[]
- Option 3 · object
JSON records ({ "records": [...] } or a plain array) for an api campaign, or { "csv": "..." } for a csv campaign.
1 - 5000 elementsShow child attributes
Show child attributes
Response
What was taken in.
What an upload did. received records were read; added are now pending. skipped counts the records not
called and why (do_not_call ones are closed). invalid and missing list up to 100 rows each (the CSV row or
the position in the request).