CRMCRM Campaigns

CRM Campaigns

Create, enroll, run, and monitor outbound calling campaigns with the Talkturo CRM API, including pagination, retries, webhooks, and dry runs.

curl -G "https://app.talkturo.com/api/crm/campaigns" \
  --data-urlencode "teamId=team_7f3c2a91" \
  --data-urlencode "status=running" \
  --data-urlencode "includeContactStats=true" \
  --data-urlencode "limit=50" \
  --data-urlencode "offset=0" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p" \
  -H "Cookie: sb-session=eyJhbGciOiJIUzI1NiJ9.example_session_token"
{
  "success": true,
  "campaigns": [
    {
      "id": "cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1",
      "team_id": "team_7f3c2a91",
      "assistant_id": "ast_9c41f8e2-7e93-4f8e-8d6c-2c9bdf8b9a33",
      "name": "Q3 renewal outreach",
      "status": "running",
      "total_contacts": 240,
      "contacts_called": 118,
      "contacts_completed": 96,
      "contacts_answered": 72,
      "created_at": "2026-08-01T14:22:11.000Z",
      "updated_at": "2026-08-13T16:42:08.000Z"
    }
  ],
  "count": 1,
  "limit": 50,
  "offset": 0
}
curl -X POST "https://app.talkturo.com/api/crm/campaigns" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p" \
  -H "Content-Type: application/json" \
  -d '{
    "teamId": "team_7f3c2a91",
    "assistantId": "ast_9c41f8e2-7e93-4f8e-8d6c-2c9bdf8b9a33",
    "fromNumberIds": ["pn_4e81c2d7"],
    "name": "Q3 renewal outreach",
    "description": "Renewal calls for accounts expiring this quarter",
    "scheduledStartAt": "2026-08-13T16:00:00.000Z",
    "callWindowStart": "09:00",
    "callWindowEnd": "17:00",
    "callWindowTimezone": "America/Los_Angeles",
    "maxConcurrentCalls": 8,
    "maxAttemptsPerContact": 3,
    "retryDelayMinutes": 30,
    "enrollment": {
      "mode": "delta",
      "leadStatus": "renewal_due",
      "maxToAdd": 500
    }
  }'
{
  "success": true,
  "campaign": {
    "id": "cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1",
    "team_id": "team_7f3c2a91",
    "assistant_id": "ast_9c41f8e2-7e93-4f8e-8d6c-2c9bdf8b9a33",
    "name": "Q3 renewal outreach",
    "status": "scheduled",
    "total_contacts": 184,
    "created_at": "2026-08-01T14:22:11.000Z"
  },
  "enrollment": {
    "inserted": 184,
    "scanned": 212,
    "excludedNoPhone": 12,
    "excludedDnc": 8,
    "excludedAlreadyDialed": 4,
    "excludedDuplicate": 2,
    "excludedOverCap": 2,
    "updated": 0,
    "groupId": "grp_83d7a1c4"
  }
}
curl "https://app.talkturo.com/api/crm/campaigns/cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p"
{
  "success": true,
  "campaign": {
    "id": "cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1",
    "name": "Q3 renewal outreach",
    "status": "scheduled",
    "from_number_ids": ["pn_4e81c2d7"],
    "contact_count": 184,
    "campaign_contacts": [
      {
        "id": "cc_2c8a91f4",
        "status": "pending",
        "attempts": 0,
        "outcome": null,
        "disposition": null,
        "last_attempt_at": null,
        "completed_at": null,
        "contact": {
          "id": "ct_89d1e6b2",
          "first_name": "Maya",
          "last_name": "Patel",
          "phone": "+14155550184",
          "email": "maya.patel@northstar.example",
          "company_name": "Northstar Labs"
        }
      }
    ]
  }
}
curl -X PUT "https://app.talkturo.com/api/crm/campaigns/cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q3 renewal outreach",
    "maxConcurrentCalls": 10,
    "retryBackoffMode": "exponential",
    "retryBackoffMultiplier": 2,
    "retryBackoffMaxMinutes": 120,
    "voicemailDetectionEnabled": true,
    "voicemailAction": "leave_message"
  }'
{
  "success": true,
  "campaign": {
    "id": "cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1",
    "name": "Q3 renewal outreach",
    "status": "scheduled",
    "max_concurrent_calls": 10,
    "updated_at": "2026-08-13T15:48:02.000Z"
  }
}
curl -X DELETE "https://app.talkturo.com/api/crm/campaigns/cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p"
{
  "success": true,
  "message": "Campaign deleted"
}
curl -G "https://app.talkturo.com/api/crm/campaigns/cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1/contacts" \
  --data-urlencode "status=pending" \
  --data-urlencode "limit=50" \
  --data-urlencode "offset=0" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p"
{
  "success": true,
  "contacts": [
    {
      "id": "cc_2c8a91f4",
      "status": "pending",
      "attempts": 0,
      "outcome": null,
      "disposition": null,
      "last_attempt_at": null,
      "next_attempt_at": null,
      "completed_at": null,
      "priority": 50,
      "contact": {
        "id": "ct_89d1e6b2",
        "first_name": "Maya",
        "last_name": "Patel",
        "phone": "+14155550184",
        "email": "maya.patel@northstar.example",
        "job_title": "VP Sales",
        "do_not_call": false,
        "company_name": "Northstar Labs"
      }
    }
  ],
  "count": 1,
  "limit": 50,
  "offset": 0,
  "statusCounts": {
    "pending": 1,
    "completed": 96
  }
}
curl -X POST "https://app.talkturo.com/api/crm/campaigns/cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1/contacts" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p" \
  -H "Content-Type: application/json" \
  -d '{
    "contactIds": ["ct_89d1e6b2", "ct_4a71c9e0"],
    "priority": 75
  }'
{
  "success": true,
  "added": 2,
  "invalid": [],
  "message": "Contacts added",
  "enrollment": {
    "inserted": 2,
    "scanned": 2,
    "excludedNoPhone": 0,
    "excludedDnc": 0,
    "excludedAlreadyDialed": 0,
    "excludedDuplicate": 0,
    "excludedOverCap": 0,
    "updated": 0,
    "groupId": null
  }
}
curl -X POST "https://app.talkturo.com/api/crm/campaigns/preview-enrollment" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1",
    "notYetDialed": true,
    "leadStatus": "renewal_due",
    "maxToAdd": 500
  }'
{
  "success": true,
  "preview": {
    "inserted": 184,
    "scanned": 212,
    "excludedNoPhone": 12,
    "excludedDnc": 8,
    "excludedAlreadyDialed": 4,
    "excludedDuplicate": 2,
    "excludedOverCap": 2,
    "updated": 0,
    "groupId": "grp_83d7a1c4"
  },
  "groupName": "Q3 renewal outreach"
}
curl "https://app.talkturo.com/api/crm/campaigns/cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1/dashboard?limitPending=25&limitCalling=25&limitCalls=25" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p"
{
  "success": true,
  "campaign": {
    "id": "cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1",
    "name": "Q3 renewal outreach",
    "status": "running"
  },
  "counts": {
    "byStatus": {
      "pending": 42,
      "queued": 8,
      "calling": 6,
      "completed": 96,
      "skipped": 4,
      "failed": 2
    },
    "byOutcome": {
      "answered": 72,
      "voicemail": 31,
      "no_answer": 14,
      "busy": 5,
      "invalid_number": 2,
      "declined": 1,
      "do_not_call": 1,
      "error": 2
    },
    "answered": 72,
    "total": 158
  },
  "queue": {
    "pending": [],
    "calling": []
  },
  "recentCalls": []
}
curl -X POST "https://app.talkturo.com/api/crm/campaigns/cmp_6df44cc0-5e10-4b0d-a3f5-ec6116f8c7d1/run" \
  -H "Authorization: Bearer sk_live_example_7h2k9m4p" \
  -H "Content-Type: application/json" \
  -d '{
    "accountSlug": "northstar",
    "maxCalls": 25,
    "dryRun": false,
    "noAutoComplete": true
  }'
{
  "success": true,
  "started": 25,
  "failed": 0,
  "calls": [],
  "errors": [],
  "message": "Campaign is running; the dialer places calls on its next tick",
  "dryRun": false,
  "picks": [],
  "dialing": "async"
}

Manage outbound CRM campaigns

Use the CRM Campaigns API to create outbound calling campaigns, enroll contacts, control dialing behavior, monitor execution, and retrieve campaign results. The endpoints support both authenticated session cookies and API key authentication.

For session authentication, provide teamId on campaign list and create requests. For API key authentication, send the key using the authentication scheme supported by your Talkturo account.

Endpoint summary

MethodPathPurpose
GET/api/crm/campaignsList campaigns
POST/api/crm/campaignsCreate a campaign
GET/api/crm/campaigns/[id]Retrieve a campaign
PUT/api/crm/campaigns/[id]Update a campaign
DELETE/api/crm/campaigns/[id]Delete a campaign
GET/api/crm/campaigns/[id]/contactsList campaign contacts
POST/api/crm/campaigns/[id]/contactsAdd contacts to a campaign
GET/api/crm/campaigns/[id]/dashboardRetrieve campaign execution data
POST/api/crm/campaigns/[id]/runStart a campaign run or perform a dry run
POST/api/crm/campaigns/preview-enrollmentPreview audience enrollment
GET/api/crm/outbound-assistantsList outbound assistants
GET/api/crm/callsList CRM call logs
GET/api/crm/intelligenceRetrieve AI insights

Campaign object

Campaign responses include the following fields.

idstring
Required

Unique campaign identifier.

team_idstring
Required

Team that owns the campaign.

assistant_idstring
Required

Outbound assistant assigned to the campaign.

namestring
Required

Campaign name.

descriptionstring

Campaign description.

from_numberstring

Primary outbound phone number.

statusstring
Required

Campaign status, such as draft, scheduled, running, paused, completed, or cancelled.

scheduled_start_atstring

Scheduled campaign start time.

started_atstring

Time when campaign execution started.

completed_atstring

Time when campaign execution completed.

call_window_startstring

Start of the permitted calling window.

call_window_endstring

End of the permitted calling window.

call_window_timezonestring

Timezone used to interpret the calling window.

max_concurrent_callsinteger

Maximum number of concurrent calls.

max_attempts_per_contactinteger

Maximum number of attempts for each contact.

retry_delay_minutesinteger

Default delay between retry attempts.

total_contactsinteger

Total contacts enrolled in the campaign.

contacts_calledinteger

Contacts for which dialing has started.

contacts_completedinteger

Contacts whose campaign processing is complete.

contacts_answeredinteger

Contacts that answered a call.

settingsobject

Campaign-specific settings.

created_atstring
Required

Campaign creation timestamp.

updated_atstring
Required

Time of the most recent campaign update.

deleted_atstring

Soft-deletion timestamp.

deleted_bystring

Identifier of the user or process that deleted the campaign.

assistantobject

Assigned assistant summary containing id and name.

List campaigns

Retrieve campaigns with pagination, status filters, contact filters, and optional contact statistics.

Query parameters

query
teamIdstring
Required

Team identifier. Required for session-authenticated requests.

query
statusstring

Return campaigns with the specified status.

Allowed values:draftscheduledrunningpausedcompletedcancelled
query
assistantIdstring

Return campaigns assigned to the specified assistant.

query
deletedstring

Control whether deleted campaigns are excluded, included, or returned exclusively.

Allowed values:excludeincludeonly
query
contactFilterstring

Filter campaigns by contact outcome or retry state.

Allowed values:voicemailawaiting_retryansweredno_answerbusyerror
query
includeContactStatsstring

Include contact statistics in campaign results.

Allowed values:1true
query
limitinteger

Maximum number of campaigns to return. Defaults to 50.

query
offsetinteger

Number of campaigns to skip. Defaults to 0.

Response fields

successboolean
Required

Returns true when the request succeeds.

campaignsarray
Required

Campaign objects matching the query.

countinteger
Required

Number of campaigns returned by the query.

limitinteger
Required

Effective result limit.

offsetinteger
Required

Effective result offset.

Create a campaign

Create a campaign with an assistant, one or more outbound numbers, calling rules, and optional audience enrollment.

Body parameters

body
teamIdstring
Required

Team that owns the campaign.

body
assistantIdstring
Required

Outbound assistant that handles campaign calls.

body
fromNumberIdsarray
Required

One or more outbound phone number identifiers.

body
descriptionstring

Campaign description.

body
scheduledStartAtstring

Scheduled start timestamp.

body
scheduledEndAtstring

Scheduled end timestamp.

body
daysOfWeekarray

Days on which the campaign may place calls.

body
dayWindowsarray

Calling windows configured for individual days.

body
callWindowStartstring

Daily calling window start time.

body
callWindowEndstring

Daily calling window end time.

body
callWindowTimezonestring

Timezone for the calling window.

body
maxConcurrentCallsinteger

Maximum concurrent calls.

body
maxAttemptsPerContactinteger

Maximum attempts per contact.

body
retryDelayMinutesinteger

Default delay between retry attempts.

body
settingsobject

Additional campaign settings.

body
noAutoCompleteboolean

Prevent automatic campaign completion.

body
webhookEnabledboolean

Enable campaign webhooks.

body
webhookUrlstring

Destination URL for campaign webhooks.

body
webhookSecretstring

Secret used to sign webhook deliveries.

body
webhookEventsarray

Events that trigger webhook deliveries.

body
liveSyncboolean

Enable live synchronization for the campaign.

body
enrollmentobject

Audience enrollment rules applied while creating the campaign.

body
enrollment.modestring

Enrollment strategy. Use none to create the campaign without enrolling contacts.

Allowed values:all_eligibledeltanone
body
enrollment.notYetDialedboolean

Limit enrollment to contacts that have not yet been dialed.

body
enrollment.addedAfterstring

Limit enrollment to contacts added after this timestamp.

body
enrollment.importBatchIdsarray

Limit enrollment to contacts from the specified import batches.

body
enrollment.searchstring

Search filter applied to the enrollment audience.

body
enrollment.leadStatusstring

Limit enrollment to contacts with the specified lead status.

body
enrollment.maxToAddinteger

Maximum number of contacts to enroll.

Response fields

successboolean
Required

Returns true when the campaign is created.

campaignobject
Required

Created campaign object.

enrollmentobject
Required

Enrollment results, including inserted, excluded, updated, and group identifier counts.

Get a campaign

Retrieve a campaign and its first 100 campaign contacts.

Path parameters

path
idstring
Required

Campaign identifier.

Response fields

successboolean
Required

Returns true when the campaign is found.

campaignobject
Required

Campaign object with campaign_contacts, contact_count, and from_number_ids.

campaign_contactsarray

First 100 contacts enrolled in the campaign.

contact_countinteger

Total number of contacts enrolled in the campaign.

from_number_idsarray

Outbound phone numbers assigned to the campaign.

Update a campaign

Update one or more campaign fields with PUT. All update fields are optional.

The API returns 409 when you try to change campaign configuration while the campaign is running. The response does not return webhook_secret.

Path parameters

path
idstring
Required

Campaign identifier.

Body parameters

body
namestring

Updated campaign name.

body
descriptionstring

Updated campaign description.

body
fromNumberstring

Primary outbound phone number.

body
fromNumberIdsarray

Outbound phone numbers assigned to the campaign.

body
statusstring

Campaign status.

Allowed values:draftscheduledrunningpausedcompletedcancelled
body
scheduledStartAtstring

Scheduled start timestamp.

body
scheduledEndAtstring

Scheduled end timestamp.

body
daysOfWeekarray

Days on which the campaign may place calls.

body
dayWindowsarray

Calling windows configured for individual days.

body
callWindowStartstring

Calling window start time.

body
callWindowEndstring

Calling window end time.

body
callWindowTimezonestring

Calling window timezone.

body
maxConcurrentCallsinteger

Maximum concurrent calls. The maximum allowed value is 20.

body
maxAttemptsPerContactinteger

Maximum attempts per contact.

body
retryDelayMinutesinteger

Default retry delay.

body
settingsobject

Additional campaign settings.

body
voicemailDropMessagestring

Message to leave when voicemail handling is enabled.

body
voicemailDetectionEnabledboolean

Enable voicemail detection.

body
voicemailActionstring

Action to take when voicemail is detected.

Allowed values:leave_messagehangup
body
unavailableActionstring

Action to take when the contact is unavailable.

Allowed values:retryfail
body
retryDelayMinutesNoAnswerinteger

Retry delay for unanswered calls.

body
maxCallDurationMinutesinteger

Maximum call duration in minutes.

body
retryDelayMinutesBusyinteger

Retry delay for busy calls.

body
retryDelayMinutesErrorinteger

Retry delay for call errors.

body
retryOnErrorboolean

Retry calls that end with an error.

body
useContactTimezoneForCallWindowboolean

Use each contact's timezone for call-window evaluation.

body
retryBackoffModestring

Retry backoff strategy.

Allowed values:fixedexponential
body
retryBackoffMultipliernumber

Multiplier used by exponential retry backoff.

body
retryBackoffMaxMinutesinteger

Maximum exponential backoff delay.

body
maxAttemptsNoAnswerinteger

Maximum attempts for unanswered calls.

body
maxAttemptsBusyinteger

Maximum attempts for busy calls.

body
maxAttemptsErrorinteger

Maximum attempts for calls that return errors.

body
noAutoCompleteboolean

Prevent automatic campaign completion.

body
liveSyncboolean

Enable live synchronization.

body
webhookEnabledboolean

Enable webhook deliveries.

body
webhookUrlstring

Webhook destination URL.

body
webhookSecretstring

Secret used to sign webhook deliveries.

body
webhookEventsarray

Events that trigger webhook deliveries.

Response fields

successboolean
Required

Returns true when the update succeeds.

campaignobject
Required

Updated campaign object.

Delete a campaign

Delete a campaign by ID. Deletion is available only when the campaign status is draft or cancelled.

Path parameters

path
idstring
Required

Campaign identifier.

Response fields

successboolean
Required

Returns true when the campaign is deleted.

messagestring
Required

Deletion result message.

Manage campaign contacts

Use the contacts endpoints to inspect enrollment and add existing or new contacts.

List campaign contacts

Path parameters

path
idstring
Required

Campaign identifier.

Query parameters

query
statusstring

Filter campaign contacts by status.

query
limitinteger

Maximum number of contacts to return. Defaults to 50.

query
offsetinteger

Number of contacts to skip. Defaults to 0.

Response fields

successboolean
Required

Returns true when the request succeeds.

contactsarray
Required

Campaign contact records.

countinteger
Required

Number of contacts returned.

limitinteger
Required

Effective result limit.

offsetinteger
Required

Effective result offset.

statusCountsobject
Required

Counts grouped by campaign contact status.

Add contacts to a campaign

Add existing contacts, create one inline contact, or enroll an audience.

Path parameters

path
idstring
Required

Campaign identifier.

Body parameters

body
contactIdsarray

Identifiers of existing contacts to add.

body
contactobject

Inline contact to create and enroll.

body
contact.first_namestring

Inline contact first name.

body
contact.last_namestring

Inline contact last name.

body
contact.phonestring

Inline contact phone number.

body
contact.emailstring

Inline contact email address.

body
contact.job_titlestring

Inline contact job title.

body
contact.company_namestring

Inline contact company name.

body
audienceobject

Audience enrollment rules.

body
audience.modestring

Audience enrollment mode.

Allowed values:all_eligibledelta
body
audience.notYetDialedboolean

Limit audience enrollment to contacts that have not been dialed.

body
audience.addedAfterstring

Limit enrollment to contacts added after this timestamp.

body
audience.importBatchIdsarray

Limit enrollment to specified import batches.

body
audience.searchstring

Search filter applied to the audience.

body
audience.leadStatusstring

Limit enrollment to the specified lead status.

body
audience.maxToAddinteger

Maximum number of contacts to add.

body
priorityinteger

Contact priority from 0 to 99.

Response fields

successboolean
Required

Returns true when the request succeeds.

addedinteger
Required

Number of contacts added.

invalidarray

Contacts that could not be added.

messagestring
Required

Result message.

contact_idstring

Created contact identifier for an inline contact request.

campaign_contact_idstring

Created campaign contact identifier for an inline contact request.

enrollmentobject

Enrollment counts and exclusion details.

Preview audience enrollment

Estimate enrollment results without inserting contacts into a campaign.

Body parameters

body
campaignIdstring
Required

Campaign to use for the enrollment preview.

body
notYetDialedboolean

Limit the preview to contacts that have not been dialed.

body
addedAfterstring

Limit the preview to contacts added after this timestamp.

body
importBatchIdsarray

Limit the preview to specified import batches.

body
leadStatusstring

Limit the preview to the specified lead status.

body
maxToAddinteger

Maximum number of contacts that would be added.

Response fields

successboolean
Required

Returns true when the preview succeeds.

previewobject
Required

Enrollment counts and exclusion details. The preview does not insert contacts.

groupNamestring

Name of the audience group used for the preview.

Retrieve campaign dashboard data

Retrieve aggregate counts, pending and calling queues, and recent calls.

Path parameters

path
idstring
Required

Campaign identifier.

Query parameters

query
limitPendinginteger

Maximum pending contacts to return. Defaults to 25; accepted range is 1 to 100.

query
limitCallinginteger

Maximum calling contacts to return. Defaults to 25; accepted range is 1 to 100.

query
limitCallsinteger

Maximum recent calls to return. Defaults to 25; accepted range is 1 to 100.

Response fields

successboolean
Required

Returns true when dashboard data is available.

campaignobject
Required

Campaign summary.

countsobject
Required

Counts grouped by status and outcome, plus answered and total counts.

queueobject
Required

Pending and currently calling campaign contacts.

recentCallsarray
Required

Recent calls associated with the campaign.

Run a campaign

Start an asynchronous campaign run or inspect the contacts that would be selected with a dry run. The external dialer places calls on its next tick; this endpoint does not place calls directly.

Path parameters

path
idstring
Required

Campaign identifier.

Body parameters

body
accountSlugstring
Required

Account that owns the campaign run.

body
maxCallsinteger

Maximum number of calls to select for the run.

body
max_callsinteger

Snake-case alias for maxCalls.

body
dryRunboolean

Return selected contacts without placing calls.

body
dry_runboolean

Snake-case alias for dryRun.

body
noAutoCompleteboolean

Prevent automatic campaign completion.

body
no_auto_completeboolean

Snake-case alias for noAutoComplete.

Response fields

successboolean
Required

Returns true when the run request succeeds.

startedinteger
Required

Number of calls started or selected.

failedinteger
Required

Number of calls that failed to start.

callsarray
Required

Calls started by the run.

errorsarray
Required

Errors encountered while selecting or starting calls.

messagestring
Required

Run result message.

dryRunboolean
Required

Indicates whether the request was a dry run.

picksarray
Required

Contacts selected for dialing. Dry-run entries include campaign_contact_id, contact_id, toNumber, and fromNumber.

dialingstring
Required

Dialing mode. Normal runs return async.

Common workflow

Use the following sequence to create, validate, run, and monitor a campaign.

Create the campaign

Send POST /api/crm/campaigns with an assistant, at least one outbound number, and a campaign name. Use the enrollment object when the campaign should enroll an audience during creation.

Preview enrollment

Send POST /api/crm/campaigns/preview-enrollment with the campaign ID and audience filters. Confirm the preview counts before inserting contacts.

Enroll contacts

Add existing contacts, create an inline contact, or submit an audience through POST /api/crm/campaigns/[id]/contacts. Confirm the added and enrollment values in the response.

Run the campaign

Call POST /api/crm/campaigns/[id]/run with accountSlug. Use dryRun first when you need to inspect the selected contacts. A normal run returns dialing: async; the external dialer places calls on its next tick.

Monitor execution

Poll GET /api/crm/campaigns/[id]/dashboard to read status and outcome counts, queue contents, and recent calls.