Create a campaign
import { createClient, createResources } from "@morevoice/sdk";
const mv = createResources({ client: createClient({ baseUrl: "https://api.morevoice.ai/v1", auth: process.env.MOREVOICE_API_KEY }),});
const campaign = await mv.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", }, ], },});console.log(campaign);import osimport uuid
import requests
response = requests.post( "https://api.morevoice.ai/v1/campaigns", headers={"Authorization": f"Bearer {os.environ['MOREVOICE_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())}, json={ "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", }, ], }, },)response.raise_for_status()print(response.json())curl -X POST https://api.morevoice.ai/v1/campaigns \ -H "Authorization: Bearer $MOREVOICE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "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" } ] }}'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.
Try it in the API playground with a test-mode key.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”The API version to use for this request. Defaults to the version the API key is pinned to.
Example
2026-11-01A unique key (for example a UUID) that makes this request safe to retry: for 24 hours, a retry with the same key and parameters returns the first response instead of acting twice.
Example
5f0c1e8a-7b2d-4c3e-9f1a-2b6d8e4c0a17Request Bodyrequired
Section titled “Request Bodyrequired”A new campaign (state draft). Unset fields take the defaults the dashboard uses.
object
object
object
Null: the organisation’s default (on for marketing). A marketing campaign can’t turn it off through the API.
Overrides the assistant’s first message. {{variables}} come from the contacts’ variables, name and phone.
Required on create: marketing, service or survey. It decides the compliance checks.
object
object
object
object
object
object
object
Never dial on Jewish holidays. Like respect_shabbat, it can only add to the organisation’s setting.
Never dial on Shabbat. The organisation’s compliance settings enforce Shabbat for every campaign by default; this flag can add the restriction, never remove it.
IANA time zone of the windows and of contacts without their own, e.g. Asia/Jerusalem.
A weekly calling window in the campaign’s time zone.
object
Weekdays the window applies to.
Closes at, local time (HH:MM, 24-hour).
Opens at, local time (HH:MM, 24-hour).
Extra instructions for the assistant. {{variables}} come from the contacts’ variables, name and phone.
Responses
Section titled “Responses”Created
An outbound calling campaign.
object
Answering-machine detection.
object
The voicemail message (leave_message).
Answering-machine detection: off, hang up on a machine, or leave message.
The number presented to contacts; null: the connection’s default.
New calls per second; 0: only the connection limits it.
An ISO-8601 timestamp in UTC.
The AI and recording disclosure played at the start of each call.
object
Play the AI / recording disclosure before the first message. null: the organisation’s default (on for marketing).
The disclosure text; empty: the organisation’s.
Outcomes the assistant can record.
Overrides the assistant’s first message ({{variables}} allowed); empty: the assistant’s.
A campaign ID (prefix cmp_).
true in live mode, false in test mode.
Simultaneous calls this campaign may hold.
The key that opts a contact out; null: the organisation’s.
Why the campaign paused itself (for example, the national registry can’t check it).
1–10; higher is served first when campaigns compete for lines.
Marketing needs recorded consent with evidence (§30A) and a national-registry check for Israeli numbers.
Retry policy per call result.
object
object
Minutes before the next attempt.
Retry after this result.
object
Minutes before the next attempt.
Retry after this result.
Network or carrier errors and interrupted calls.
object
Minutes before the next attempt.
Retry after this result.
Total dial attempts per contact, the first one included.
object
Minutes before the next attempt.
Retry after this result.
An answering machine was detected.
object
Minutes before the next attempt.
Retry after this result.
Hang up an unanswered call after this long.
When the campaign dials.
object
Never dial on Jewish holidays. Like respect_shabbat, it can only add to the organisation’s setting.
Never dial on Shabbat. The organisation’s compliance settings enforce Shabbat for every campaign by default; this flag can add the restriction, never remove it.
IANA time zone of the windows and of contacts without their own, e.g. Asia/Jerusalem.
When the campaign may dial. The organisation’s calling hours apply on top: a call happens only inside both.
A weekly calling window in the campaign’s time zone.
object
Weekdays the window applies to.
Closes at, local time (HH:MM, 24-hour).
Opens at, local time (HH:MM, 24-hour).
Extra instructions for this campaign ({{variables}} allowed).
Draft → running ⇄ paused → completed | cancelled (scheduled: waits for schedule.start_at).
Contact counts per status and the calls in progress.
object
Contacts per status.
object
Contacts that will not be dialled again (done, failed, do-not-call, skipped, invalid, cancelled).
Calls in progress right now (this server’s dialer).
object
Contacts in the campaign.
An ISO-8601 timestamp in UTC.
Example
{ "amd": { "message": "", "mode": "off" }, "assistant_id": "asst_3kTzL9Qe2R", "caller_id": "+97235550100", "calls_per_second": 0, "completed_at": null, "connection_id": "conn_8DbH2nXy", "created_at": "2026-11-01T08:00:00.000Z", "disclosure": { "enabled": null, "text": "" }, "dispositions": [ "interested", "not-interested", "callback-requested" ], "first_message": "", "id": "cmp_2Yb7mCq9aPLk", "livemode": true, "max_concurrent": 10, "name": "November renewals", "object": "campaign", "opt_out_dtmf_key": null, "pause_reason": null, "priority": 5, "purpose": "marketing", "retry": { "busy": { "delay_minutes": 15, "enabled": true }, "declined": { "delay_minutes": 240, "enabled": false }, "failed": { "delay_minutes": 10, "enabled": true }, "max_attempts": 3, "no_answer": { "delay_minutes": 60, "enabled": true }, "voicemail": { "delay_minutes": 120, "enabled": true } }, "ring_timeout_seconds": 30, "schedule": { "end_at": null, "respect_holidays": true, "respect_shabbat": true, "start_at": null, "timezone": "Asia/Jerusalem", "windows": [ { "days": [ "sun", "mon", "tue", "wed", "thu" ], "end": "20:00", "start": "09:00" }, { "days": [ "fri" ], "end": "13:00", "start": "09:00" } ] }, "script": "Offer the {{plan}} renewal at the loyalty price.", "started_at": "2026-11-02T07:00:00.000Z", "state": "running", "stats": { "by_status": { "callback": 3, "cancelled": 0, "dialing": 5, "dnc": 9, "done": 120, "failed": 6, "invalid": 1, "pending": 812, "scheduled": 40, "skipped": 4 }, "finished": 140, "live": { "connected": 1, "dialing": 2, "ringing": 2 }, "total": 1000 }, "updated_at": "2026-11-02T07:00:00.000Z"}The request is invalid: a parameter is missing, malformed or unknown, or the version header is unknown.
Every /v1 error.
object
object
A stable, machine-readable code from the error-code catalogue.
Structured context, e.g. required_scope or the compliance verdict.
object
A link to the documentation of this code.
A human-readable explanation. Do not parse it.
The request parameter the error relates to, e.g. to or metadata[order_id].
The X-Request-Id of this request. Quote it when you contact support.
The category of the error.
Example
{ "error": { "code": "parameter_missing", "doc_url": "https://docs.morevoice.ai/api/errors#parameter-missing", "message": "Missing required parameter: to.", "param": "to", "request_id": "req_7Hk2LmN9pQ4rS6tV8wX0yZ", "type": "invalid_request_error" }}Headers
Section titled “Headers”The request’s ID (req_…). Quote it when you contact support.
No valid API key was sent.
Every /v1 error.
object
object
A stable, machine-readable code from the error-code catalogue.
Structured context, e.g. required_scope or the compliance verdict.
object
A link to the documentation of this code.
A human-readable explanation. Do not parse it.
The request parameter the error relates to, e.g. to or metadata[order_id].
The X-Request-Id of this request. Quote it when you contact support.
The category of the error.
Example
{ "error": { "code": "invalid_api_key", "doc_url": "https://docs.morevoice.ai/api/errors#invalid-api-key", "message": "Invalid API key.", "request_id": "req_7Hk2LmN9pQ4rS6tV8wX0yZ", "type": "authentication_error" }}Headers
Section titled “Headers”The request’s ID (req_…). Quote it when you contact support.
The key may not do this (a missing scope, a plan limit, or a compliance block).
Every /v1 error.
object
object
A stable, machine-readable code from the error-code catalogue.
Structured context, e.g. required_scope or the compliance verdict.
object
A link to the documentation of this code.
A human-readable explanation. Do not parse it.
The request parameter the error relates to, e.g. to or metadata[order_id].
The X-Request-Id of this request. Quote it when you contact support.
The category of the error.
Example
{ "error": { "code": "missing_scope", "doc_url": "https://docs.morevoice.ai/api/errors#missing-scope", "message": "This API key lacks the calls:write scope.", "request_id": "req_7Hk2LmN9pQ4rS6tV8wX0yZ", "type": "permission_error" }}Headers
Section titled “Headers”The request’s ID (req_…). Quote it when you contact support.
The request conflicts with the object’s state, or the Idempotency-Key was reused with other parameters.
Every /v1 error.
object
object
A stable, machine-readable code from the error-code catalogue.
Structured context, e.g. required_scope or the compliance verdict.
object
A link to the documentation of this code.
A human-readable explanation. Do not parse it.
The request parameter the error relates to, e.g. to or metadata[order_id].
The X-Request-Id of this request. Quote it when you contact support.
The category of the error.
Example
{ "error": { "code": "idempotency_mismatch", "doc_url": "https://docs.morevoice.ai/api/errors#idempotency-mismatch", "message": "This Idempotency-Key was already used with different parameters.", "request_id": "req_7Hk2LmN9pQ4rS6tV8wX0yZ", "type": "idempotency_error" }}Headers
Section titled “Headers”The request’s ID (req_…). Quote it when you contact support.
Too many requests, or no call capacity right now. Retry after the Retry-After delay.
Every /v1 error.
object
object
A stable, machine-readable code from the error-code catalogue.
Structured context, e.g. required_scope or the compliance verdict.
object
A link to the documentation of this code.
A human-readable explanation. Do not parse it.
The request parameter the error relates to, e.g. to or metadata[order_id].
The X-Request-Id of this request. Quote it when you contact support.
The category of the error.
Example
{ "error": { "code": "rate_limited", "doc_url": "https://docs.morevoice.ai/api/errors#rate-limited", "message": "Too many requests. Retry after 1 second.", "request_id": "req_7Hk2LmN9pQ4rS6tV8wX0yZ", "type": "rate_limit_error" }}Headers
Section titled “Headers”Seconds to wait before retrying.
The request’s ID (req_…). Quote it when you contact support.
Something went wrong on MoreVoice’s side. Retry with the same Idempotency-Key.
Every /v1 error.
object
object
A stable, machine-readable code from the error-code catalogue.
Structured context, e.g. required_scope or the compliance verdict.
object
A link to the documentation of this code.
A human-readable explanation. Do not parse it.
The request parameter the error relates to, e.g. to or metadata[order_id].
The X-Request-Id of this request. Quote it when you contact support.
The category of the error.
Example
{ "error": { "code": "internal_error", "doc_url": "https://docs.morevoice.ai/api/errors#internal-error", "message": "Something went wrong on MoreVoice's side.", "request_id": "req_7Hk2LmN9pQ4rS6tV8wX0yZ", "type": "api_error" }}Headers
Section titled “Headers”The request’s ID (req_…). Quote it when you contact support.