curl --request POST \
--url https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/cancel \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/cancel', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/cancel"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"id": "cmp_7c1d2e3f4a5b4c6d8e9f0a1b2c3d4e5f",
"tenant_id": "ten_credfin",
"name": "Credfin pre-due Nov",
"description": "EMI due 5 Nov",
"status": "canceled",
"input_type": "csv",
"agent": {
"id": "agt_credfin_predue_m",
"name": "Credfin pre-due (Hindi, male)"
},
"agent_contract": {
"required_variables": [
"borrower_first_name",
"emi_amount",
"due_date"
],
"optional_variables": [
"lender_name"
],
"default_variables": {
"lender_name": "Credfin"
},
"post_call_variables": [
{
"name": "payment_date",
"type": "date",
"description": "Date the customer said they will pay",
"options": []
},
{
"name": "callback_at",
"type": "datetime",
"description": "When the customer asked to be called back",
"options": []
}
],
"outcomes": [
"confirmed_on_time",
"paid_early",
"callback_scheduled",
"do_not_call",
"wrong_number",
"refused",
"not_reached"
],
"read_at": "2026-10-24T05:00:00.000Z"
},
"goal": {
"outcomes": [
"confirmed_on_time",
"paid_early"
],
"label": "Confirmed or paid"
},
"variables": {
"static": {
"lender_name": "Credfin"
}
},
"csv": {
"phone_column": "phone_number",
"mapping": {
"borrower_first_name": "Name",
"emi_amount": "EMI"
},
"external_id_column": "loan_id"
},
"schedule": {
"start_date": "2026-10-26",
"end_date": "2026-11-05",
"timezone": "Asia/Kolkata",
"time_window_enabled": true,
"daily_start_time": "09:00",
"daily_end_time": "18:00",
"active_days": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday"
]
},
"execution": {
"max_concurrency": 20,
"max_attempts": 3,
"dnc_enabled": true,
"reschedule_enabled": true,
"dial_first_attempt_immediately": false,
"skip_duplicates": true,
"skip_invalid_phones": true,
"budget_micros": 5000000000,
"pause_reason": null,
"pause_details": null
},
"attempts": [
{
"attempt_number": 1,
"day": 1,
"start_time": "10:00",
"instant_redial": true,
"instant_redial_delay_minutes": 5,
"instant_redial_on_statuses": [
"no_answer",
"busy"
],
"conditions": {}
},
{
"attempt_number": 2,
"day": 1,
"start_time": "16:00",
"instant_redial": false,
"instant_redial_delay_minutes": 0,
"instant_redial_on_statuses": [],
"conditions": {
"previous_status_in": [
"no_answer",
"busy"
]
}
},
{
"attempt_number": 3,
"day": 2,
"start_time": "11:00",
"instant_redial": false,
"instant_redial_delay_minutes": 0,
"instant_redial_on_statuses": [],
"conditions": {}
}
],
"retry": {
"retry_on_no_answer": true,
"retry_on_busy": true,
"retry_on_short_call": true,
"short_call_threshold_seconds": 10,
"retry_delay_minutes": 30,
"insight_based_retry_conditions": []
},
"outcome_rules": {
"do_not_call": [
"do_not_call"
],
"callback": [
"callback_scheduled"
],
"wrong_number": [
"wrong_number"
],
"callback_variable": "callback_at"
},
"metadata": {
"portfolio": "nov-predue"
},
"counts": {
"total": 1200,
"pending": 0,
"calling": 0,
"completed": 431,
"exhausted": 25,
"closed": 732,
"skipped": 12
},
"results": {
"success": 286,
"wrong_number": 24,
"final_outcome": 121,
"exhausted": 25,
"end_date": 0,
"do_not_call": 6,
"paid": 6,
"canceled": 720,
"invalid_phone": 7,
"duplicate": 3,
"missing_variables": 2
},
"success_rate": 24.1,
"spend": {
"amount_micros": 1840000000,
"status": "pending",
"calls": 412,
"budget_micros": 5000000000
},
"collected": {
"amount_micros": 91480000000,
"events": 20
},
"window": {
"open_now": true,
"closes_at": "2026-10-26T12:30:00.000Z",
"next_open_at": null
},
"pause_reason": null,
"pause_details": null,
"test_report": {
"status": "passed_with_warnings",
"ran_at": "2026-10-25T10:00:00.000Z",
"checks": [
{
"id": "agent",
"level": "ok",
"title": "Agent",
"detail": "Credfin pre-due (Hindi, male) is active."
},
{
"id": "numbers",
"level": "ok",
"title": "Outbound numbers",
"detail": "2 usable numbers."
},
{
"id": "goal",
"level": "ok",
"title": "Goal",
"detail": "Success: confirmed_on_time, paid_early."
},
{
"id": "records",
"level": "ok",
"title": "Records",
"detail": "1188 of 1200 records will be called."
},
{
"id": "skipped",
"level": "warning",
"title": "Skipped records",
"detail": "12 (1%) will not be called: 7 invalid phone, 3 duplicate, 2 missing variables."
},
{
"id": "dnc",
"level": "warning",
"title": "Do-not-call list",
"detail": "4 records are on the do-not-call list and will be closed."
},
{
"id": "window",
"level": "ok",
"title": "Calling hours",
"detail": "First calls possible 2026-10-26 09:00 (Asia/Kolkata)."
},
{
"id": "ladder",
"level": "ok",
"title": "Attempt ladder",
"detail": "3 attempts per record."
},
{
"id": "capacity",
"level": "ok",
"title": "Capacity",
"detail": "About 2138 attempts, roughly 3.6 calling hours at 20 parallel calls."
}
],
"timeline": [
{
"attempt_number": 1,
"at": "2026-10-26T04:30:00.000Z",
"local": "2026-10-26 10:00",
"note": "day 1 from 10:00; redials 5 min later on no_answer, busy"
},
{
"attempt_number": 2,
"at": "2026-10-26T10:30:00.000Z",
"local": "2026-10-26 16:00",
"note": "day 1 from 16:00; only if its conditions hold"
},
{
"attempt_number": 3,
"at": "2026-10-27T05:30:00.000Z",
"local": "2026-10-27 11:00",
"note": "day 2 from 11:00"
}
],
"samples": [
{
"phone": "+9198XXXXXX01",
"variables": {
"borrower_first_name": "Ravi",
"emi_amount": "4574",
"due_date": "2026-11-05",
"lender_name": "Credfin"
}
}
],
"estimate": {
"records": 1188,
"expected_attempts": 2138,
"calls_per_hour": 600,
"open_hours": 81,
"hours_needed": 3.6,
"fits_schedule": true
}
},
"locked": true,
"actions": [
"duplicate"
],
"duplicated_from": null,
"launched_at": "2026-10-25T09:55:00.000Z",
"tested_at": "2026-10-25T10:00:00.000Z",
"locked_at": "2026-10-26T04:30:05.000Z",
"started_at": "2026-10-26T04:30:00.000Z",
"paused_at": null,
"completed_at": null,
"canceled_at": "2026-10-26T06:00:00.000Z",
"created_at": "2026-10-24T05:00:00.000Z",
"updated_at": "2026-10-26T06:00:00.000Z",
"canceling": false
}Cancel a campaign
Cancels a created, tested, running or paused campaign. Pending records are closed
(result: canceled), calls still waiting in the queue are withdrawn, and calls already ringing or on the line
finish. While those last calls finish the campaign shows canceling: true; it is canceled once none is left.
A canceled campaign cannot start again, but you can copy it with duplicate. A draft is deleted instead.
No body.
curl --request POST \
--url https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/cancel \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/cancel', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.voice.mergenlab.ai/v1/campaigns/{campaignId}/cancel"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"id": "cmp_7c1d2e3f4a5b4c6d8e9f0a1b2c3d4e5f",
"tenant_id": "ten_credfin",
"name": "Credfin pre-due Nov",
"description": "EMI due 5 Nov",
"status": "canceled",
"input_type": "csv",
"agent": {
"id": "agt_credfin_predue_m",
"name": "Credfin pre-due (Hindi, male)"
},
"agent_contract": {
"required_variables": [
"borrower_first_name",
"emi_amount",
"due_date"
],
"optional_variables": [
"lender_name"
],
"default_variables": {
"lender_name": "Credfin"
},
"post_call_variables": [
{
"name": "payment_date",
"type": "date",
"description": "Date the customer said they will pay",
"options": []
},
{
"name": "callback_at",
"type": "datetime",
"description": "When the customer asked to be called back",
"options": []
}
],
"outcomes": [
"confirmed_on_time",
"paid_early",
"callback_scheduled",
"do_not_call",
"wrong_number",
"refused",
"not_reached"
],
"read_at": "2026-10-24T05:00:00.000Z"
},
"goal": {
"outcomes": [
"confirmed_on_time",
"paid_early"
],
"label": "Confirmed or paid"
},
"variables": {
"static": {
"lender_name": "Credfin"
}
},
"csv": {
"phone_column": "phone_number",
"mapping": {
"borrower_first_name": "Name",
"emi_amount": "EMI"
},
"external_id_column": "loan_id"
},
"schedule": {
"start_date": "2026-10-26",
"end_date": "2026-11-05",
"timezone": "Asia/Kolkata",
"time_window_enabled": true,
"daily_start_time": "09:00",
"daily_end_time": "18:00",
"active_days": [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday"
]
},
"execution": {
"max_concurrency": 20,
"max_attempts": 3,
"dnc_enabled": true,
"reschedule_enabled": true,
"dial_first_attempt_immediately": false,
"skip_duplicates": true,
"skip_invalid_phones": true,
"budget_micros": 5000000000,
"pause_reason": null,
"pause_details": null
},
"attempts": [
{
"attempt_number": 1,
"day": 1,
"start_time": "10:00",
"instant_redial": true,
"instant_redial_delay_minutes": 5,
"instant_redial_on_statuses": [
"no_answer",
"busy"
],
"conditions": {}
},
{
"attempt_number": 2,
"day": 1,
"start_time": "16:00",
"instant_redial": false,
"instant_redial_delay_minutes": 0,
"instant_redial_on_statuses": [],
"conditions": {
"previous_status_in": [
"no_answer",
"busy"
]
}
},
{
"attempt_number": 3,
"day": 2,
"start_time": "11:00",
"instant_redial": false,
"instant_redial_delay_minutes": 0,
"instant_redial_on_statuses": [],
"conditions": {}
}
],
"retry": {
"retry_on_no_answer": true,
"retry_on_busy": true,
"retry_on_short_call": true,
"short_call_threshold_seconds": 10,
"retry_delay_minutes": 30,
"insight_based_retry_conditions": []
},
"outcome_rules": {
"do_not_call": [
"do_not_call"
],
"callback": [
"callback_scheduled"
],
"wrong_number": [
"wrong_number"
],
"callback_variable": "callback_at"
},
"metadata": {
"portfolio": "nov-predue"
},
"counts": {
"total": 1200,
"pending": 0,
"calling": 0,
"completed": 431,
"exhausted": 25,
"closed": 732,
"skipped": 12
},
"results": {
"success": 286,
"wrong_number": 24,
"final_outcome": 121,
"exhausted": 25,
"end_date": 0,
"do_not_call": 6,
"paid": 6,
"canceled": 720,
"invalid_phone": 7,
"duplicate": 3,
"missing_variables": 2
},
"success_rate": 24.1,
"spend": {
"amount_micros": 1840000000,
"status": "pending",
"calls": 412,
"budget_micros": 5000000000
},
"collected": {
"amount_micros": 91480000000,
"events": 20
},
"window": {
"open_now": true,
"closes_at": "2026-10-26T12:30:00.000Z",
"next_open_at": null
},
"pause_reason": null,
"pause_details": null,
"test_report": {
"status": "passed_with_warnings",
"ran_at": "2026-10-25T10:00:00.000Z",
"checks": [
{
"id": "agent",
"level": "ok",
"title": "Agent",
"detail": "Credfin pre-due (Hindi, male) is active."
},
{
"id": "numbers",
"level": "ok",
"title": "Outbound numbers",
"detail": "2 usable numbers."
},
{
"id": "goal",
"level": "ok",
"title": "Goal",
"detail": "Success: confirmed_on_time, paid_early."
},
{
"id": "records",
"level": "ok",
"title": "Records",
"detail": "1188 of 1200 records will be called."
},
{
"id": "skipped",
"level": "warning",
"title": "Skipped records",
"detail": "12 (1%) will not be called: 7 invalid phone, 3 duplicate, 2 missing variables."
},
{
"id": "dnc",
"level": "warning",
"title": "Do-not-call list",
"detail": "4 records are on the do-not-call list and will be closed."
},
{
"id": "window",
"level": "ok",
"title": "Calling hours",
"detail": "First calls possible 2026-10-26 09:00 (Asia/Kolkata)."
},
{
"id": "ladder",
"level": "ok",
"title": "Attempt ladder",
"detail": "3 attempts per record."
},
{
"id": "capacity",
"level": "ok",
"title": "Capacity",
"detail": "About 2138 attempts, roughly 3.6 calling hours at 20 parallel calls."
}
],
"timeline": [
{
"attempt_number": 1,
"at": "2026-10-26T04:30:00.000Z",
"local": "2026-10-26 10:00",
"note": "day 1 from 10:00; redials 5 min later on no_answer, busy"
},
{
"attempt_number": 2,
"at": "2026-10-26T10:30:00.000Z",
"local": "2026-10-26 16:00",
"note": "day 1 from 16:00; only if its conditions hold"
},
{
"attempt_number": 3,
"at": "2026-10-27T05:30:00.000Z",
"local": "2026-10-27 11:00",
"note": "day 2 from 11:00"
}
],
"samples": [
{
"phone": "+9198XXXXXX01",
"variables": {
"borrower_first_name": "Ravi",
"emi_amount": "4574",
"due_date": "2026-11-05",
"lender_name": "Credfin"
}
}
],
"estimate": {
"records": 1188,
"expected_attempts": 2138,
"calls_per_hour": 600,
"open_hours": 81,
"hours_needed": 3.6,
"fits_schedule": true
}
},
"locked": true,
"actions": [
"duplicate"
],
"duplicated_from": null,
"launched_at": "2026-10-25T09:55:00.000Z",
"tested_at": "2026-10-25T10:00:00.000Z",
"locked_at": "2026-10-26T04:30:05.000Z",
"started_at": "2026-10-26T04:30:00.000Z",
"paused_at": null,
"completed_at": null,
"canceled_at": "2026-10-26T06:00:00.000Z",
"created_at": "2026-10-24T05:00:00.000Z",
"updated_at": "2026-10-26T06:00:00.000Z",
"canceling": false
}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).
Response
The campaign after the cancel.
A campaign. agent_contract is what the campaign read from its agent. counts and results count its records
by status and by result. success_rate is the share of callable records that ended as a success, in percent
(null until a call was answered). window says whether the schedule allows a call now. test_report is
the latest dry run (null before the first). locked is true once the first call was placed (see PATCH).
actions lists what the status allows now. canceling is true while a canceled campaign waits for its last
calls to finish. intake is present only in the create answer, when the request carried records.
cmp_ + 32 hex characters.
Your account id.
draft (being set up; everything can change), created (launched; the configuration passed its blocking
checks), testing (the dry run is working), tested (the dry run finished; see test_report), running,
paused, completed (no record is left to call, or the end date passed) and canceled. A campaign moves from
draft to created with launch, may be tested any number of times, then goes to running with start.
draft, created, testing, tested, running, paused, completed, canceled csv: records come from a file uploaded before the first call. api: records are posted as JSON at any time until the campaign ends.
csv, api Show child attributes
Show child attributes
What the campaign read from its agent (on create, and again on launch, test and start).
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
When calls are allowed. start_date and end_date are calendar dates in timezone (end_date included;
null means no end). With time_window_enabled, calls are placed only between daily_start_time and
daily_end_time on active_days; without it, all day on active days. The agent's own calling window and your
account's limits still apply.
Show child attributes
Show child attributes
The campaign's execution limits, plus why it is paused.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Which unsuccessful attempts are tried again (with the next attempt of the ladder, while attempts are left).
no_answer (also voicemail) with retry_on_no_answer, busy with retry_on_busy, an answered call shorter
than short_call_threshold_seconds with retry_on_short_call, any of insight_based_retry_conditions that
holds, and always an attempt that failed on our side. retry_delay_minutes is the least time between the end of
one attempt and the next (except an instant redial).
Show child attributes
Show child attributes
What some outcomes mean. After an answered call: an outcome in do_not_call (with execution.dnc_enabled)
closes the record and adds the number to your do-not-call list; an outcome in callback (with
execution.reschedule_enabled) schedules the next attempt at the time in the post-call variable
callback_variable (a callback may use one attempt beyond the ladder, at most 2 per record); an outcome in
goal.outcomes completes the record as a success; an outcome in wrong_number completes it as a wrong number.
Defaults come from the agent's outcome_roles.
Show child attributes
Show child attributes
Records by status.
Show child attributes
Show child attributes
Records by result (records still open have none).
Show child attributes
Show child attributes
Your cost of the campaign's calls. status is pending while any cost is still pending, final once every
cost is known, and no_rule (with amount_micros: null) while your account has no pricing.
Show child attributes
Show child attributes
What was paid, from your customer events (POST /v1/customer-events).
Show child attributes
Show child attributes
Whether the schedule allows a call right now, when the current window closes, or when the next one opens.
Show child attributes
Show child attributes
Same as execution.pause_reason.
manual, credits, unroutable, budget, failures, disabled Same as execution.pause_details.
The result of the dry run. status is failed when any check is an error, passed_with_warnings when any is
a warning, else passed. timeline shows when each attempt of a sample record would be placed if no call were
answered (at is null for an attempt that falls after the end date). samples shows the resolved variables
of up to 5 records. estimate compares the expected attempts with the calling hours of the schedule.
Show child attributes
Show child attributes
An action the campaign's status allows right now.
edit, add_records, launch, delete, test, start, pause, resume, cancel, duplicate The campaign this one was copied from.
prerecorded campaigns have no agent (agent is { id: "prerecorded", name: "Pre-recorded message" }) and a message.
ai_voice, prerecorded A pre-recorded campaign's message. template is the text, with a record's values written as {name} (for
example {due_date}); every placeholder is a required variable of each record. Write it in the script of
language (a few Latin words such as "EMI" are fine) and write values the way they should be spoken ("5th
November", not "05/11"). The text with its values must stay within the platform's limit (500 characters by
default); a record whose text is too long, or a language or gender without a voice, pauses the campaign.
Show child attributes
Show child attributes
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).
Show child attributes
Show child attributes