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
| Method | Path | Purpose |
|---|---|---|
GET | /api/crm/campaigns | List campaigns |
POST | /api/crm/campaigns | Create 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]/contacts | List campaign contacts |
POST | /api/crm/campaigns/[id]/contacts | Add contacts to a campaign |
GET | /api/crm/campaigns/[id]/dashboard | Retrieve campaign execution data |
POST | /api/crm/campaigns/[id]/run | Start a campaign run or perform a dry run |
POST | /api/crm/campaigns/preview-enrollment | Preview audience enrollment |
GET | /api/crm/outbound-assistants | List outbound assistants |
GET | /api/crm/calls | List CRM call logs |
GET | /api/crm/intelligence | Retrieve AI insights |
Campaign object
Campaign responses include the following fields.
Unique campaign identifier.
Team that owns the campaign.
Outbound assistant assigned to the campaign.
Campaign name.
Campaign description.
Primary outbound phone number.
Campaign status, such as draft, scheduled, running, paused, completed, or cancelled.
Scheduled campaign start time.
Time when campaign execution started.
Time when campaign execution completed.
Start of the permitted calling window.
End of the permitted calling window.
Timezone used to interpret the calling window.
Maximum number of concurrent calls.
Maximum number of attempts for each contact.
Default delay between retry attempts.
Total contacts enrolled in the campaign.
Contacts for which dialing has started.
Contacts whose campaign processing is complete.
Contacts that answered a call.
Campaign-specific settings.
Campaign creation timestamp.
Time of the most recent campaign update.
Soft-deletion timestamp.
Identifier of the user or process that deleted the campaign.
Assigned assistant summary containing id and name.
List campaigns
Retrieve campaigns with pagination, status filters, contact filters, and optional contact statistics.
Query parameters
Team identifier. Required for session-authenticated requests.
Return campaigns with the specified status.
draftscheduledrunningpausedcompletedcancelledReturn campaigns assigned to the specified assistant.
Control whether deleted campaigns are excluded, included, or returned exclusively.
excludeincludeonlyFilter campaigns by contact outcome or retry state.
voicemailawaiting_retryansweredno_answerbusyerrorMaximum number of campaigns to return. Defaults to 50.
Number of campaigns to skip. Defaults to 0.
Response fields
Returns true when the request succeeds.
Campaign objects matching the query.
Number of campaigns returned by the query.
Effective result limit.
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
Team that owns the campaign.
Outbound assistant that handles campaign calls.
One or more outbound phone number identifiers.
Campaign name.
Campaign description.
Scheduled start timestamp.
Scheduled end timestamp.
Days on which the campaign may place calls.
Calling windows configured for individual days.
Daily calling window start time.
Daily calling window end time.
Timezone for the calling window.
Maximum concurrent calls.
Maximum attempts per contact.
Default delay between retry attempts.
Additional campaign settings.
Prevent automatic campaign completion.
Enable campaign webhooks.
Destination URL for campaign webhooks.
Secret used to sign webhook deliveries.
Events that trigger webhook deliveries.
Enable live synchronization for the campaign.
Audience enrollment rules applied while creating the campaign.
Enrollment strategy. Use none to create the campaign without enrolling contacts.
all_eligibledeltanoneLimit enrollment to contacts that have not yet been dialed.
Limit enrollment to contacts added after this timestamp.
Limit enrollment to contacts from the specified import batches.
Search filter applied to the enrollment audience.
Limit enrollment to contacts with the specified lead status.
Maximum number of contacts to enroll.
Response fields
Returns true when the campaign is created.
Created campaign object.
Enrollment results, including inserted, excluded, updated, and group identifier counts.
Get a campaign
Retrieve a campaign and its first 100 campaign contacts.
Path parameters
Campaign identifier.
Response fields
Returns true when the campaign is found.
Campaign object with campaign_contacts, contact_count, and from_number_ids.
First 100 contacts enrolled in the campaign.
Total number of contacts enrolled in the campaign.
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
Campaign identifier.
Body parameters
Updated campaign name.
Updated campaign description.
Primary outbound phone number.
Outbound phone numbers assigned to the campaign.
Scheduled start timestamp.
Scheduled end timestamp.
Days on which the campaign may place calls.
Calling windows configured for individual days.
Calling window start time.
Calling window end time.
Calling window timezone.
Maximum concurrent calls. The maximum allowed value is 20.
Maximum attempts per contact.
Default retry delay.
Additional campaign settings.
Message to leave when voicemail handling is enabled.
Enable voicemail detection.
Action to take when voicemail is detected.
leave_messagehangupRetry delay for unanswered calls.
Maximum call duration in minutes.
Retry delay for busy calls.
Retry delay for call errors.
Retry calls that end with an error.
Use each contact's timezone for call-window evaluation.
Multiplier used by exponential retry backoff.
Maximum exponential backoff delay.
Maximum attempts for unanswered calls.
Maximum attempts for busy calls.
Maximum attempts for calls that return errors.
Prevent automatic campaign completion.
Enable live synchronization.
Enable webhook deliveries.
Webhook destination URL.
Secret used to sign webhook deliveries.
Events that trigger webhook deliveries.
Response fields
Returns true when the update succeeds.
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
Campaign identifier.
Response fields
Returns true when the campaign is deleted.
Deletion result message.
Manage campaign contacts
Use the contacts endpoints to inspect enrollment and add existing or new contacts.
List campaign contacts
Path parameters
Campaign identifier.
Query parameters
Filter campaign contacts by status.
Maximum number of contacts to return. Defaults to 50.
Number of contacts to skip. Defaults to 0.
Response fields
Returns true when the request succeeds.
Campaign contact records.
Number of contacts returned.
Effective result limit.
Effective result offset.
Counts grouped by campaign contact status.
Add contacts to a campaign
Add existing contacts, create one inline contact, or enroll an audience.
Path parameters
Campaign identifier.
Body parameters
Identifiers of existing contacts to add.
Inline contact to create and enroll.
Inline contact first name.
Inline contact last name.
Inline contact phone number.
Inline contact email address.
Inline contact job title.
Inline contact company name.
Audience enrollment rules.
Limit audience enrollment to contacts that have not been dialed.
Limit enrollment to contacts added after this timestamp.
Limit enrollment to specified import batches.
Search filter applied to the audience.
Limit enrollment to the specified lead status.
Maximum number of contacts to add.
Contact priority from 0 to 99.
Response fields
Returns true when the request succeeds.
Number of contacts added.
Contacts that could not be added.
Result message.
Created contact identifier for an inline contact request.
Created campaign contact identifier for an inline contact request.
Enrollment counts and exclusion details.
Preview audience enrollment
Estimate enrollment results without inserting contacts into a campaign.
Body parameters
Campaign to use for the enrollment preview.
Limit the preview to contacts that have not been dialed.
Limit the preview to contacts added after this timestamp.
Limit the preview to specified import batches.
Search filter applied to the audience.
Limit the preview to the specified lead status.
Maximum number of contacts that would be added.
Response fields
Returns true when the preview succeeds.
Enrollment counts and exclusion details. The preview does not insert contacts.
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
Campaign identifier.
Query parameters
Maximum pending contacts to return. Defaults to 25; accepted range is 1 to 100.
Maximum calling contacts to return. Defaults to 25; accepted range is 1 to 100.
Maximum recent calls to return. Defaults to 25; accepted range is 1 to 100.
Response fields
Returns true when dashboard data is available.
Campaign summary.
Counts grouped by status and outcome, plus answered and total counts.
Pending and currently calling campaign contacts.
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
Campaign identifier.
Body parameters
Account that owns the campaign run.
Maximum number of calls to select for the run.
Snake-case alias for maxCalls.
Return selected contacts without placing calls.
Snake-case alias for dryRun.
Prevent automatic campaign completion.
Snake-case alias for noAutoComplete.
Response fields
Returns true when the run request succeeds.
Number of calls started or selected.
Number of calls that failed to start.
Calls started by the run.
Errors encountered while selecting or starting calls.
Run result message.
Indicates whether the request was a dry run.
Contacts selected for dialing. Dry-run entries include campaign_contact_id, contact_id, toNumber, and fromNumber.
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.