client.campaigns
Outbound calling campaigns. These methods are on client.campaigns, where client is a MoreVoice client (see the Python SDK). On AsyncMoreVoice the same methods are awaited. Each one returns the response object and raises an exception when the API answers with an error.
cancel()
Section titled “cancel()”Cancel a campaign. Stops the campaign for good: unanswered calls are hung up and the contacts not yet dialled are cancelled.
def cancel(self, id: str, body: _m.CampaignActionParamsInput | Mapping[str, Any] | Unset = UNSET, *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.Campaignclient.campaigns.cancel() · await async_client.campaigns.cancel() · POST /campaigns/{id}/cancel · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Returns
Section titled “Returns”Campaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
livemode |
boolean |
true in live mode, false in test mode. |
name |
string |
— |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at). |
purpose |
"marketing" | "service" | "survey" |
marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers. |
assistant_id |
string | null |
asst_… ID. |
connection_id |
string | null |
The SIP connection it dials through; null: the default one. |
caller_id |
string | null |
The number presented to contacts; null: the connection’s default. |
priority |
integer |
1–10; higher is served first when campaigns compete for lines. |
max_concurrent |
integer |
Simultaneous calls this campaign may hold. |
calls_per_second |
integer |
New calls per second; 0: only the connection limits it. |
schedule |
CampaignSchedule |
When the campaign dials. |
ring_timeout_seconds |
integer |
Hang up an unanswered call after this long. |
retry |
CampaignRetry |
Retry policy per call result. |
amd |
CampaignAmd |
Answering-machine detection. |
disclosure |
CampaignDisclosure |
The AI and recording disclosure played at the start of each call. |
first_message |
string |
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s. |
script |
string |
Extra instructions for this campaign ({{variables}} allowed). |
dispositions |
string[] |
Outcomes the assistant can record. |
opt_out_dtmf_key |
string | null |
The key that opts a contact out; null: the organisation’s. |
pause_reason |
string | null |
Why the campaign paused itself (for example, the national registry can’t check it). |
stats |
CampaignStats |
Contact counts per status and the calls in progress. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign = client.campaigns.cancel("cmp_7Hk2Lm9Qp", {})print(campaign)contacts.create()
Section titled “contacts.create()”Add contacts to a campaign. Adds up to 1,000 contacts and answers what was added and what was left out, like a dashboard import of the same list: numbers are normalised and de-duplicated, do-not-call numbers are kept as dnc (never dialled), and in a marketing campaign a contact without consent evidence is added but skipped by the dialer (§30A).
def create(self, id: str, body: _m.ContactBatchParamsInput | Mapping[str, Any], *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.ContactBatchResultclient.campaigns.contacts.create() · await async_client.campaigns.contacts.create() · POST /campaigns/{id}/contacts · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
contacts |
ContactInputInput[] |
yes | Up to 1000 contacts. |
default_country |
string |
no | Country of numbers written without a country code (ISO 3166-1 alpha-2, default IL). |
drop_dnc |
boolean |
no | Leave numbers on the do-not-call list out entirely (default false: they are kept with status dnc, for the record, and never dialled). |
Returns
Section titled “Returns”ContactBatchResult:
| Field | Type | Description |
|---|---|---|
object |
"contact_batch_result" |
Always contact_batch_result. |
campaign_id |
string |
A campaign ID (prefix cmp_). |
livemode |
boolean |
true in live mode, false in test mode. |
received |
integer |
Non-empty contacts / rows received. |
imported |
integer |
Contacts added to the campaign for dialling. |
rejected |
integer |
Contacts not added for dialling (invalid, duplicate, do-not-call). |
rejected_reasons |
ContactRejectedReasons |
Rejected contacts per reason. |
without_consent |
integer |
Marketing: contacts added without a consent record. The dialer skips them (§30A) unless consent is recorded first. |
consent_recorded |
integer |
Consent records created from the evidence sent. |
errors |
object[] |
Rejected contacts (the first 100). |
warnings |
object[] |
Contacts added with a problem, e.g. consent claimed without complete evidence (the first 100). |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
contact_batch_result = client.campaigns.contacts.create("cmp_7Hk2Lm9Qp", { "contacts": [ { "consent": { "channel": "web", "granted_at": "2026-09-20T14:02:00+03:00", "source": "website_form_2026", }, "name": "Dana Levi", "phone": "+972501234567", "variables": { "plan": "Gold", }, }, { "name": "Yossi Cohen", "phone": "052-765-4321", "variables": { "plan": "Silver", }, }, ], "default_country": "IL",})print(contact_batch_result)contacts.import_()
Section titled “contacts.import_()”Import a contact list in the background. Imports a CSV or XLSX list in the background through the dashboard’s import path and answers 202 with the import; poll GET /v1/imports/{id} until it succeeds or fails. Send the file as multipart/form-data (a file part plus the options as text fields, mapping as a JSON string), or as JSON: CSV text, a base64 file, or an https URL to download. An Idempotency-Key is required, so a retried upload never imports twice.
def import_(self, id: str, body: _m.ContactImportParamsInput | _m.CampaignsContactsImportFilesBody | Mapping[str, Any] | Unset = UNSET, *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.ContactImportclient.campaigns.contacts.import_() · await async_client.campaigns.contacts.import_() · POST /campaigns/{id}/contacts/import · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
consent_channel |
"web" | "phone" | "sms" | "email" | "whatsapp" | "app" | "written" | "in_person" | … |
no | How every consenting row consented, when the file has no channel column. |
consent_source |
string |
no | Where every consenting row consented, when the file has no source column. |
csv |
string |
no | The list as CSV text (UTF-8; comma, semicolon, tab or pipe separated). |
default_country |
string |
no | Country of numbers written without a country code (ISO 3166-1 alpha-2, default IL). |
drop_dnc |
boolean |
no | Leave do-not-call numbers out entirely (default false: kept with status dnc, never dialled). |
file |
object |
no | A CSV or XLSX file. |
has_header |
boolean |
no | The first row holds column names (default: detected). |
mapping |
ImportMappingInput |
no | Which column holds what: contact field → header name (or 0-based index). Any other key names a {{variable}}. Omit the mapping to detect the columns like the dashboard does. |
url |
string |
no | An https URL to download the CSV / XLSX from (public addresses only, ≤ 10 MB). |
Returns
Section titled “Returns”ContactImport:
| Field | Type | Description |
|---|---|---|
id |
string |
A import ID (prefix imp_). |
object |
"import" |
Always import. |
livemode |
boolean |
true in live mode, false in test mode. |
campaign_id |
string |
A campaign ID (prefix cmp_). |
status |
"pending" | "processing" | "succeeded" | "failed" |
pending → processing → succeeded | failed. Poll GET /v1/imports/{id}. |
source |
"csv" | "xlsx" | "url" |
— |
filename |
string | null |
— |
received |
integer |
Non-empty contacts / rows received. |
imported |
integer |
Contacts added to the campaign for dialling. |
rejected |
integer |
Contacts not added for dialling (invalid, duplicate, do-not-call). |
rejected_reasons |
ContactRejectedReasons |
Rejected contacts per reason. |
without_consent |
integer |
Marketing: contacts added without a consent record. The dialer skips them (§30A) unless consent is recorded first. |
consent_recorded |
integer |
Consent records created from the evidence sent. |
errors |
object[] |
Rejected rows (the first 100). |
warnings |
object[] |
Rows added with a problem (the first 100). |
error |
object | null |
Why the import failed (status failed): a stable code and a message to show. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
contact_import = client.campaigns.contacts.import_("cmp_7Hk2Lm9Qp", { "csv": "Mobile,Name,Plan\n0501234567,Dana Levi,Gold\n0527654321,Yossi Cohen,Silver\n", "default_country": "IL", "mapping": { "name": "Name", "phone": "Mobile", "variables": { "plan": "Plan", }, },})print(contact_import)contacts.list()
Section titled “contacts.list()”List a campaign’s contacts. Lists the contacts of a campaign, newest first, with each contact’s status, attempts and outcome. Filter by status (several, comma-separated), by outcome (the recorded disposition) or by phone.
def list(self, id: str, *, limit: int | Unset = 20, starting_after: str | Unset = UNSET, ending_before: str | Unset = UNSET, status: str | Unset = UNSET, outcome: str | Unset = UNSET, phone: str | Unset = UNSET, more_voice_version: str | Unset = UNSET) -> AsyncPage[_m.CampaignContact]client.campaigns.contacts.list() · await async_client.campaigns.contacts.list() · GET /campaigns/{id}/contacts · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
limit |
integer |
no | How many objects to return, 1–100 (default 20). |
starting_after |
string |
no | A cursor (next_cursor) or object ID: return the objects after it (older). |
ending_before |
string |
no | A cursor or object ID: return the objects before it (newer). |
status |
string |
no | Only these statuses, comma-separated (e.g. pending,scheduled). |
outcome |
string |
no | Only contacts with this recorded disposition. |
phone |
string |
no | Only this number. |
Returns
Section titled “Returns”A page of results (CampaignContactList): data, has_more and next_cursor.
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
for contact in client.campaigns.contacts.list("cmp_7Hk2Lm9Qp"): print(contact)contacts.list_attempts()
Section titled “contacts.list_attempts()”List a contact’s dial attempts. Lists the dial attempts made to one contact of the campaign, newest first: when each one started, how it ended, and the call it placed.
def list_attempts(self, id: str, contact_id: str, *, limit: int | Unset = 20, starting_after: str | Unset = UNSET, ending_before: str | Unset = UNSET, more_voice_version: str | Unset = UNSET) -> AsyncPage[_m.CampaignAttempt]client.campaigns.contacts.list_attempts() · await async_client.campaigns.contacts.list_attempts() · GET /campaigns/{id}/contacts/{contact_id}/attempts · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
contact_id |
str |
yes | A contact ID (ctc_…). |
limit |
integer |
no | How many objects to return, 1–100 (default 20). |
starting_after |
string |
no | A cursor (next_cursor) or object ID: return the objects after it (older). |
ending_before |
string |
no | A cursor or object ID: return the objects before it (newer). |
Returns
Section titled “Returns”A page of results (CampaignAttemptList): data, has_more and next_cursor.
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
for contact in client.campaigns.contacts.list_attempts("cmp_7Hk2Lm9Qp", "ctc_7Hk2Lm9Qp"): print(contact)contacts.retrieve()
Section titled “contacts.retrieve()”Retrieve a campaign contact. Returns one contact of a campaign: the number, its variables, its status, how many times it was dialled and the outcome.
def retrieve(self, id: str, contact_id: str, *, more_voice_version: str | Unset = UNSET) -> _m.CampaignContactclient.campaigns.contacts.retrieve() · await async_client.campaigns.contacts.retrieve() · GET /campaigns/{id}/contacts/{contact_id} · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
contact_id |
str |
yes | A contact ID (ctc_…). |
Returns
Section titled “Returns”CampaignContact:
| Field | Type | Description |
|---|---|---|
id |
string |
A contact ID (prefix ctc_). |
object |
"campaign_contact" |
Always campaign_contact. |
livemode |
boolean |
true in live mode, false in test mode. |
campaign_id |
string |
A campaign ID (prefix cmp_). |
phone |
string |
E.164. |
name |
string |
— |
variables |
Record<string, string> |
— |
timezone |
string | null |
— |
consent |
boolean |
The import said the person consented. Marketing calls also need a consent record with evidence (§30A). |
status |
"pending" | "scheduled" | "callback" | "dialing" | "done" | "failed" | "dnc" | "skipped" | … |
pending → dialing → scheduled | callback → … → done | failed; skipped, dnc, invalid and cancelled are never dialled. |
skip_reason |
string | null |
Why it is not dialled: dnc_import, dnc_dial_time, registry, no_consent, no_consent_evidence, no_calling_window, manual, … |
attempts |
integer |
— |
next_attempt_at |
string | null |
When it is due (dialable statuses only). |
last_result |
string | null |
The last attempt’s result (answered, no_answer, busy, voicemail, …). |
outcome |
string | null |
The disposition the assistant recorded. |
outcome_data |
object | null |
— |
last_call_id |
string | null |
call_… ID. |
last_attempt_at |
string | null |
— |
completed_at |
string | null |
— |
row |
integer | null |
The row it came from in its import. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign_contact = client.campaigns.contacts.retrieve("cmp_7Hk2Lm9Qp", "ctc_7Hk2Lm9Qp")print(campaign_contact)contacts.update()
Section titled “contacts.update()”Requeue or skip a campaign contact. status scheduled dials the contact again now (refused for a number on the do-not-call list); skipped takes it out of the campaign. A contact being dialled can’t change.
def update(self, id: str, contact_id: str, body: _m.ContactUpdateParamsInput | Mapping[str, Any], *, more_voice_version: str | Unset = UNSET) -> _m.CampaignContactclient.campaigns.contacts.update() · await async_client.campaigns.contacts.update() · PATCH /campaigns/{id}/contacts/{contact_id} · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
contact_id |
str |
yes | A contact ID (ctc_…). |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
status |
"scheduled" | "skipped" |
yes | scheduled: dial it again now (refused for a do-not-call number); skipped: take it out of the campaign. |
Returns
Section titled “Returns”CampaignContact:
| Field | Type | Description |
|---|---|---|
id |
string |
A contact ID (prefix ctc_). |
object |
"campaign_contact" |
Always campaign_contact. |
livemode |
boolean |
true in live mode, false in test mode. |
campaign_id |
string |
A campaign ID (prefix cmp_). |
phone |
string |
E.164. |
name |
string |
— |
variables |
Record<string, string> |
— |
timezone |
string | null |
— |
consent |
boolean |
The import said the person consented. Marketing calls also need a consent record with evidence (§30A). |
status |
"pending" | "scheduled" | "callback" | "dialing" | "done" | "failed" | "dnc" | "skipped" | … |
pending → dialing → scheduled | callback → … → done | failed; skipped, dnc, invalid and cancelled are never dialled. |
skip_reason |
string | null |
Why it is not dialled: dnc_import, dnc_dial_time, registry, no_consent, no_consent_evidence, no_calling_window, manual, … |
attempts |
integer |
— |
next_attempt_at |
string | null |
When it is due (dialable statuses only). |
last_result |
string | null |
The last attempt’s result (answered, no_answer, busy, voicemail, …). |
outcome |
string | null |
The disposition the assistant recorded. |
outcome_data |
object | null |
— |
last_call_id |
string | null |
call_… ID. |
last_attempt_at |
string | null |
— |
completed_at |
string | null |
— |
row |
integer | null |
The row it came from in its import. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign_contact = client.campaigns.contacts.update("cmp_7Hk2Lm9Qp", "ctc_7Hk2Lm9Qp", { "status": "skipped",})print(campaign_contact)create()
Section titled “create()”Create a campaign. Creates a draft campaign. Add contacts, then start it. The purpose decides the compliance checks: marketing needs consent with evidence (§30A) and, for Israeli numbers, the national do-not-call registry.
def create(self, body: _m.CampaignCreateParamsInput | Mapping[str, Any], *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.Campaignclient.campaigns.create() · await async_client.campaigns.create() · POST /campaigns · API reference
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
yes | — |
purpose |
"marketing" | "service" | "survey" |
yes | Required on create: marketing, service or survey. It decides the compliance checks. |
amd |
object |
no | — |
assistant_id |
string | null |
no | asst_… ID. |
caller_id |
string | null |
no | — |
calls_per_second |
integer |
no | — |
connection_id |
string | null |
no | conn_… ID. |
disclosure |
object |
no | — |
dispositions |
string[] |
no | — |
first_message |
string |
no | Overrides the assistant’s first message. {{variables}} come from the contacts’ variables, name and phone. |
max_concurrent |
integer |
no | — |
opt_out_dtmf_key |
string | null |
no | — |
priority |
integer |
no | — |
retry |
object |
no | — |
ring_timeout_seconds |
integer |
no | — |
schedule |
object |
no | — |
script |
string |
no | Extra instructions for the assistant. {{variables}} come from the contacts’ variables, name and phone. |
Returns
Section titled “Returns”Campaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
livemode |
boolean |
true in live mode, false in test mode. |
name |
string |
— |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at). |
purpose |
"marketing" | "service" | "survey" |
marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers. |
assistant_id |
string | null |
asst_… ID. |
connection_id |
string | null |
The SIP connection it dials through; null: the default one. |
caller_id |
string | null |
The number presented to contacts; null: the connection’s default. |
priority |
integer |
1–10; higher is served first when campaigns compete for lines. |
max_concurrent |
integer |
Simultaneous calls this campaign may hold. |
calls_per_second |
integer |
New calls per second; 0: only the connection limits it. |
schedule |
CampaignSchedule |
When the campaign dials. |
ring_timeout_seconds |
integer |
Hang up an unanswered call after this long. |
retry |
CampaignRetry |
Retry policy per call result. |
amd |
CampaignAmd |
Answering-machine detection. |
disclosure |
CampaignDisclosure |
The AI and recording disclosure played at the start of each call. |
first_message |
string |
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s. |
script |
string |
Extra instructions for this campaign ({{variables}} allowed). |
dispositions |
string[] |
Outcomes the assistant can record. |
opt_out_dtmf_key |
string | null |
The key that opts a contact out; null: the organisation’s. |
pause_reason |
string | null |
Why the campaign paused itself (for example, the national registry can’t check it). |
stats |
CampaignStats |
Contact counts per status and the calls in progress. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign = client.campaigns.create({ "assistant_id": "asst_3kTzL9Qe2R", "name": "November renewals", "purpose": "marketing", "retry": { "busy": { "delay_minutes": 30, }, "max_attempts": 3, "no_answer": { "delay_minutes": 240, }, }, "schedule": { "respect_shabbat": True, "timezone": "Asia/Jerusalem", "windows": [ { "days": [ "sun", "mon", "tue", "wed", "thu", ], "end": "19:00", "start": "09:00", }, ], },})print(campaign)delete()
Section titled “delete()”Delete a campaign. Deletes a campaign that is not running or scheduled, with its contacts and attempts. Calls already made stay in the call log.
def delete(self, id: str, *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.DeletedCampaignclient.campaigns.delete() · await async_client.campaigns.delete() · DELETE /campaigns/{id} · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Returns
Section titled “Returns”DeletedCampaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
deleted |
true |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
deleted_campaign = client.campaigns.delete("cmp_7Hk2Lm9Qp")print(deleted_campaign)export()
Section titled “export()”Export a campaign’s contacts or attempts as CSV. The dashboard’s export, streamed: UTF-8 with a byte-order mark (opens in Excel with Hebrew intact). kind=contacts (default) has one row per contact with its result and variables; kind=attempts one row per dial attempt.
def export(self, id: str, *, kind: _m.CampaignsExportKind | Unset = "contacts", more_voice_version: str | Unset = UNSET) -> strclient.campaigns.export() · await async_client.campaigns.export() · GET /campaigns/{id}/export · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
kind |
"contacts" | "attempts" |
no | contacts (default) or attempts. |
Returns
Section titled “Returns”Nothing, on success.
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
data = client.campaigns.export("cmp_7Hk2Lm9Qp")print(data)list()
Section titled “list()”List campaigns. Lists the campaigns of this mode, newest first, with each campaign’s contact counts. Filter by state or purpose.
def list(self, *, limit: int | Unset = 20, starting_after: str | Unset = UNSET, ending_before: str | Unset = UNSET, state: _m.CampaignsListState | Unset = UNSET, purpose: _m.CampaignsListPurpose | Unset = UNSET, more_voice_version: str | Unset = UNSET) -> AsyncPage[_m.Campaign]client.campaigns.list() · await async_client.campaigns.list() · GET /campaigns · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
limit |
integer |
no | How many objects to return, 1–100 (default 20). |
starting_after |
string |
no | A cursor (next_cursor) or object ID: return the objects after it (older). |
ending_before |
string |
no | A cursor or object ID: return the objects before it (newer). |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
no | Only campaigns in this state. |
purpose |
"marketing" | "service" | "survey" |
no | Only campaigns with this purpose. |
Returns
Section titled “Returns”A page of results (CampaignList): data, has_more and next_cursor.
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
for campaign in client.campaigns.list(): print(campaign)pause()
Section titled “pause()”Pause a campaign. Stops dialling new calls; calls in progress finish. Resume it to continue.
def pause(self, id: str, body: _m.CampaignActionParamsInput | Mapping[str, Any] | Unset = UNSET, *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.Campaignclient.campaigns.pause() · await async_client.campaigns.pause() · POST /campaigns/{id}/pause · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Returns
Section titled “Returns”Campaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
livemode |
boolean |
true in live mode, false in test mode. |
name |
string |
— |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at). |
purpose |
"marketing" | "service" | "survey" |
marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers. |
assistant_id |
string | null |
asst_… ID. |
connection_id |
string | null |
The SIP connection it dials through; null: the default one. |
caller_id |
string | null |
The number presented to contacts; null: the connection’s default. |
priority |
integer |
1–10; higher is served first when campaigns compete for lines. |
max_concurrent |
integer |
Simultaneous calls this campaign may hold. |
calls_per_second |
integer |
New calls per second; 0: only the connection limits it. |
schedule |
CampaignSchedule |
When the campaign dials. |
ring_timeout_seconds |
integer |
Hang up an unanswered call after this long. |
retry |
CampaignRetry |
Retry policy per call result. |
amd |
CampaignAmd |
Answering-machine detection. |
disclosure |
CampaignDisclosure |
The AI and recording disclosure played at the start of each call. |
first_message |
string |
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s. |
script |
string |
Extra instructions for this campaign ({{variables}} allowed). |
dispositions |
string[] |
Outcomes the assistant can record. |
opt_out_dtmf_key |
string | null |
The key that opts a contact out; null: the organisation’s. |
pause_reason |
string | null |
Why the campaign paused itself (for example, the national registry can’t check it). |
stats |
CampaignStats |
Contact counts per status and the calls in progress. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign = client.campaigns.pause("cmp_7Hk2Lm9Qp", {})print(campaign)preflight()
Section titled “preflight()”Check whether a campaign can start. Runs the checks that starting the campaign runs, without starting it: the same checks as the dashboard’s Start button. ok says whether it can start; errors block the start, warnings don’t. window_open and next_window_at say whether the campaign’s calling window (and Shabbat and holidays) lets it dial now, and when it next can.
def preflight(self, id: str, *, more_voice_version: str | Unset = UNSET) -> _m.CampaignPreflightclient.campaigns.preflight() · await async_client.campaigns.preflight() · GET /campaigns/{id}/preflight · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Returns
Section titled “Returns”CampaignPreflight:
| Field | Type | Description |
|---|---|---|
object |
"campaign_preflight" |
Always campaign_preflight. |
campaign_id |
string |
A campaign ID (prefix cmp_). |
ok |
boolean |
No errors: the campaign can start. |
errors |
string[] |
What blocks the start (missing assistant or connection, no contacts, no marketing consent, no registry, …). |
warnings |
string[] |
What the dialer will skip or delay (contacts without consent, outside calling hours now, …). |
dialable |
integer |
Contacts the dialer may call. |
window_open |
boolean |
Calling is allowed right now (calling hours, Shabbat, holidays). |
next_window_at |
string | null |
When calling is next allowed; null if never in the next 3 weeks. |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign_preflight = client.campaigns.preflight("cmp_7Hk2Lm9Qp")print(campaign_preflight)resume()
Section titled “resume()”Resume a paused campaign. Runs the pre-flight checks again and resumes dialling.
def resume(self, id: str, body: _m.CampaignActionParamsInput | Mapping[str, Any] | Unset = UNSET, *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.Campaignclient.campaigns.resume() · await async_client.campaigns.resume() · POST /campaigns/{id}/resume · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Returns
Section titled “Returns”Campaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
livemode |
boolean |
true in live mode, false in test mode. |
name |
string |
— |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at). |
purpose |
"marketing" | "service" | "survey" |
marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers. |
assistant_id |
string | null |
asst_… ID. |
connection_id |
string | null |
The SIP connection it dials through; null: the default one. |
caller_id |
string | null |
The number presented to contacts; null: the connection’s default. |
priority |
integer |
1–10; higher is served first when campaigns compete for lines. |
max_concurrent |
integer |
Simultaneous calls this campaign may hold. |
calls_per_second |
integer |
New calls per second; 0: only the connection limits it. |
schedule |
CampaignSchedule |
When the campaign dials. |
ring_timeout_seconds |
integer |
Hang up an unanswered call after this long. |
retry |
CampaignRetry |
Retry policy per call result. |
amd |
CampaignAmd |
Answering-machine detection. |
disclosure |
CampaignDisclosure |
The AI and recording disclosure played at the start of each call. |
first_message |
string |
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s. |
script |
string |
Extra instructions for this campaign ({{variables}} allowed). |
dispositions |
string[] |
Outcomes the assistant can record. |
opt_out_dtmf_key |
string | null |
The key that opts a contact out; null: the organisation’s. |
pause_reason |
string | null |
Why the campaign paused itself (for example, the national registry can’t check it). |
stats |
CampaignStats |
Contact counts per status and the calls in progress. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign = client.campaigns.resume("cmp_7Hk2Lm9Qp", {})print(campaign)retrieve()
Section titled “retrieve()”Retrieve a campaign. Returns a campaign: its settings, its state and its contact counts. GET /v1/campaigns/{id}/stats has the detailed results.
def retrieve(self, id: str, *, more_voice_version: str | Unset = UNSET) -> _m.Campaignclient.campaigns.retrieve() · await async_client.campaigns.retrieve() · GET /campaigns/{id} · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Returns
Section titled “Returns”Campaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
livemode |
boolean |
true in live mode, false in test mode. |
name |
string |
— |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at). |
purpose |
"marketing" | "service" | "survey" |
marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers. |
assistant_id |
string | null |
asst_… ID. |
connection_id |
string | null |
The SIP connection it dials through; null: the default one. |
caller_id |
string | null |
The number presented to contacts; null: the connection’s default. |
priority |
integer |
1–10; higher is served first when campaigns compete for lines. |
max_concurrent |
integer |
Simultaneous calls this campaign may hold. |
calls_per_second |
integer |
New calls per second; 0: only the connection limits it. |
schedule |
CampaignSchedule |
When the campaign dials. |
ring_timeout_seconds |
integer |
Hang up an unanswered call after this long. |
retry |
CampaignRetry |
Retry policy per call result. |
amd |
CampaignAmd |
Answering-machine detection. |
disclosure |
CampaignDisclosure |
The AI and recording disclosure played at the start of each call. |
first_message |
string |
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s. |
script |
string |
Extra instructions for this campaign ({{variables}} allowed). |
dispositions |
string[] |
Outcomes the assistant can record. |
opt_out_dtmf_key |
string | null |
The key that opts a contact out; null: the organisation’s. |
pause_reason |
string | null |
Why the campaign paused itself (for example, the national registry can’t check it). |
stats |
CampaignStats |
Contact counts per status and the calls in progress. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign = client.campaigns.retrieve("cmp_7Hk2Lm9Qp")print(campaign)start()
Section titled “start()”Start a campaign. Runs the dashboard’s pre-flight checks and starts dialling (or schedules the start). A failed check answers 409 preflight_failed with the list. Once running, every call is still checked against the do-not-call list, consent, the national registry, the calling hours and Shabbat; a marketing campaign the registry can’t check pauses itself (pause_reason).
def start(self, id: str, body: _m.CampaignStartParamsInput | Mapping[str, Any] | Unset = UNSET, *, more_voice_version: str | Unset = UNSET, idempotency_key: str | Unset = UNSET) -> _m.Campaignclient.campaigns.start() · await async_client.campaigns.start() · POST /campaigns/{id}/start · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
start_at |
string | null |
no | Start later: the campaign is scheduled and starts dialling at this time. |
Returns
Section titled “Returns”Campaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
livemode |
boolean |
true in live mode, false in test mode. |
name |
string |
— |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at). |
purpose |
"marketing" | "service" | "survey" |
marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers. |
assistant_id |
string | null |
asst_… ID. |
connection_id |
string | null |
The SIP connection it dials through; null: the default one. |
caller_id |
string | null |
The number presented to contacts; null: the connection’s default. |
priority |
integer |
1–10; higher is served first when campaigns compete for lines. |
max_concurrent |
integer |
Simultaneous calls this campaign may hold. |
calls_per_second |
integer |
New calls per second; 0: only the connection limits it. |
schedule |
CampaignSchedule |
When the campaign dials. |
ring_timeout_seconds |
integer |
Hang up an unanswered call after this long. |
retry |
CampaignRetry |
Retry policy per call result. |
amd |
CampaignAmd |
Answering-machine detection. |
disclosure |
CampaignDisclosure |
The AI and recording disclosure played at the start of each call. |
first_message |
string |
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s. |
script |
string |
Extra instructions for this campaign ({{variables}} allowed). |
dispositions |
string[] |
Outcomes the assistant can record. |
opt_out_dtmf_key |
string | null |
The key that opts a contact out; null: the organisation’s. |
pause_reason |
string | null |
Why the campaign paused itself (for example, the national registry can’t check it). |
stats |
CampaignStats |
Contact counts per status and the calls in progress. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign = client.campaigns.start("cmp_7Hk2Lm9Qp", {})print(campaign)stats()
Section titled “stats()”Retrieve a campaign’s results. Returns the campaign’s results so far: contacts per status, dial attempts per result with talk and ring time, the dispositions recorded, and the contacts compliance checks skipped, by reason.
def stats(self, id: str, *, more_voice_version: str | Unset = UNSET) -> _m.CampaignResultsclient.campaigns.stats() · await async_client.campaigns.stats() · GET /campaigns/{id}/stats · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Returns
Section titled “Returns”CampaignResults:
| Field | Type | Description |
|---|---|---|
object |
"campaign_stats" |
Always campaign_stats. |
campaign_id |
string |
A campaign ID (prefix cmp_). |
livemode |
boolean |
true in live mode, false in test mode. |
contacts |
CampaignStats |
Contact counts per status and the calls in progress. |
attempts |
object |
— |
outcomes |
Record<string, integer> |
Contacts per recorded disposition (interested, not-interested, …). |
skip_reasons |
Record<string, integer> |
Contacts the compliance checks or a user took out, per reason (dnc_import, registry, no_consent, …). |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign_results = client.campaigns.stats("cmp_7Hk2Lm9Qp")print(campaign_results)update()
Section titled “update()”Update a campaign. Changes the fields you send and keeps the rest. A completed or cancelled campaign can’t change; pause a running one before changing its purpose.
def update(self, id: str, body: _m.CampaignUpdateParamsInput | Mapping[str, Any] | Unset = UNSET, *, more_voice_version: str | Unset = UNSET) -> _m.Campaignclient.campaigns.update() · await async_client.campaigns.update() · PATCH /campaigns/{id} · API reference
Parameters
Section titled “Parameters”| Name | Type | Required | Description |
|---|---|---|---|
id |
str |
yes | A campaign ID (cmp_…). |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
amd |
object |
no | — |
assistant_id |
string | null |
no | asst_… ID. |
caller_id |
string | null |
no | — |
calls_per_second |
integer |
no | — |
connection_id |
string | null |
no | conn_… ID. |
disclosure |
object |
no | — |
dispositions |
string[] |
no | — |
first_message |
string |
no | Overrides the assistant’s first message. {{variables}} come from the contacts’ variables, name and phone. |
max_concurrent |
integer |
no | — |
name |
string |
no | — |
opt_out_dtmf_key |
string | null |
no | — |
priority |
integer |
no | — |
purpose |
"marketing" | "service" | "survey" |
no | Required on create: marketing, service or survey. It decides the compliance checks. |
retry |
object |
no | — |
ring_timeout_seconds |
integer |
no | — |
schedule |
object |
no | — |
script |
string |
no | Extra instructions for the assistant. {{variables}} come from the contacts’ variables, name and phone. |
Returns
Section titled “Returns”Campaign:
| Field | Type | Description |
|---|---|---|
id |
string |
A campaign ID (prefix cmp_). |
object |
"campaign" |
Always campaign. |
livemode |
boolean |
true in live mode, false in test mode. |
name |
string |
— |
state |
"draft" | "scheduled" | "running" | "paused" | "completed" | "cancelled" |
draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at). |
purpose |
"marketing" | "service" | "survey" |
marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers. |
assistant_id |
string | null |
asst_… ID. |
connection_id |
string | null |
The SIP connection it dials through; null: the default one. |
caller_id |
string | null |
The number presented to contacts; null: the connection’s default. |
priority |
integer |
1–10; higher is served first when campaigns compete for lines. |
max_concurrent |
integer |
Simultaneous calls this campaign may hold. |
calls_per_second |
integer |
New calls per second; 0: only the connection limits it. |
schedule |
CampaignSchedule |
When the campaign dials. |
ring_timeout_seconds |
integer |
Hang up an unanswered call after this long. |
retry |
CampaignRetry |
Retry policy per call result. |
amd |
CampaignAmd |
Answering-machine detection. |
disclosure |
CampaignDisclosure |
The AI and recording disclosure played at the start of each call. |
first_message |
string |
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s. |
script |
string |
Extra instructions for this campaign ({{variables}} allowed). |
dispositions |
string[] |
Outcomes the assistant can record. |
opt_out_dtmf_key |
string | null |
The key that opts a contact out; null: the organisation’s. |
pause_reason |
string | null |
Why the campaign paused itself (for example, the national registry can’t check it). |
stats |
CampaignStats |
Contact counts per status and the calls in progress. |
created_at |
string |
An ISO-8601 timestamp in UTC. |
updated_at |
string |
An ISO-8601 timestamp in UTC. |
started_at |
string | null |
— |
completed_at |
string | null |
— |
Example
Section titled “Example”from morevoice import MoreVoice
client = MoreVoice() # MOREVOICE_API_KEY from the environment
campaign = client.campaigns.update("cmp_7Hk2Lm9Qp", { "max_concurrent": 20, "schedule": { "end_at": "2026-11-30T18:00:00+02:00", },})print(campaign)