API Reference
Campaigns API
Create, manage, and control outbound calling campaigns.
Campaigns automate outbound communications. You can create campaigns, configure business hours, set rate limits, and control campaign status (start, pause, archive).
Available Endpoints
/v1/campaigns— List all campaigns/v1/campaigns— Create a campaign/v1/campaigns/:id— Get a campaign/v1/campaigns/:id— Update a campaign/v1/campaigns/:id— Archive a campaign/v1/campaigns/:id/start— Start a campaign/v1/campaigns/:id/pause— Pause a campaign/v1/campaigns/:id/enrollments— List enrollments with call outcomes/v1/campaigns/:id/enrollments— Enroll a lead (triggers the first call within seconds)List Campaigns
/v1/campaignsRetrieves a paginated list of campaigns with optional filtering.
Query Parameters
Parameters
| Name | Type | Description |
|---|---|---|
limit | integer | Number of campaigns to return (1-100, default: 20) |
offset | integer | Number of campaigns to skip (default: 0) |
status | string | Filter by status: draft, active, paused, completed, archived |
type | string | Filter by type: outbound, inbound, webhook |
Example Request
curl -X GET "https://www.nutalk.ai/v1/campaigns?status=active&limit=10" \ -H "Authorization: Bearer YOUR_API_KEY"Response
{
"success": true,
"data": [
{
"id": "camp_abc123",
"name": "Q1 Outreach",
"description": "First quarter customer outreach campaign",
"type": "outbound",
"status": "active",
"total_enrollments": 500,
"active_enrollments": 150,
"completed_enrollments": 320,
"goal_reached_count": 45,
"business_hours": {
"timezone": "America/New_York",
"days": {
"monday": { "start": "09:00", "end": "17:00" },
"tuesday": { "start": "09:00", "end": "17:00" }
}
},
"rate_limits": {
"max_concurrent_calls": 10,
"calls_per_minute": 5
},
"created_at": "2024-01-10T08:00:00Z",
"updated_at": "2024-01-25T12:00:00Z"
}
],
"pagination": {
"total": 15,
"limit": 10,
"offset": 0,
"has_more": true
}
}Create Campaign
/v1/campaignsCreates a new campaign in draft status.
Request Body
Parameters
| Name | Type | Description |
|---|---|---|
nameRequired | string | Campaign name (1-200 characters) |
description | string | Campaign description (max 1000 characters) |
type | string | Campaign type: outbound, inbound, or webhook (default: outbound) |
outbound_channel_id | uuid | Channel ID for outbound calls |
business_hours | object | Business hours configuration |
rate_limits | object | Rate limiting configuration |
Example Request
curl -X POST "https://www.nutalk.ai/v1/campaigns" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Summer Sale Campaign", "description": "Outreach for summer promotion", "type": "outbound", "business_hours": { "timezone": "America/Los_Angeles", "days": { "monday": { "start": "10:00", "end": "18:00" }, "tuesday": { "start": "10:00", "end": "18:00" }, "wednesday": { "start": "10:00", "end": "18:00" } } }, "rate_limits": { "max_concurrent_calls": 5, "calls_per_minute": 3 }}'Response
{
"success": true,
"data": {
"id": "camp_def456",
"name": "Summer Sale Campaign",
"description": "Outreach for summer promotion",
"type": "outbound",
"status": "draft",
"business_hours": {
"timezone": "America/Los_Angeles",
"days": {
"monday": { "start": "10:00", "end": "18:00" },
"tuesday": { "start": "10:00", "end": "18:00" },
"wednesday": { "start": "10:00", "end": "18:00" }
}
},
"rate_limits": {
"max_concurrent_calls": 5,
"calls_per_minute": 3
},
"created_at": "2024-01-25T16:30:00Z",
"updated_at": "2024-01-25T16:30:00Z"
}
}Draft Status
New campaigns are created in draft status. Use the /start endpoint to activate them.
Start Campaign
/v1/campaigns/:id/startActivates a campaign. The campaign will begin processing enrollments according to its configuration.
Path Parameters
Parameters
| Name | Type | Description |
|---|---|---|
idRequired | uuid | The campaign's unique identifier |
Example Request
curl -X POST "https://www.nutalk.ai/v1/campaigns/camp_abc123/start" \ -H "Authorization: Bearer YOUR_API_KEY"Response
{
"success": true,
"data": {
"id": "camp_abc123",
"name": "Q1 Outreach",
"status": "active",
"type": "outbound",
"updated_at": "2024-01-25T17:00:00Z"
},
"message": "Campaign started successfully"
}Requirements
Outbound campaigns require a channel to be configured before they can be started. Ensure outbound_channel_id is set.
Pause Campaign
/v1/campaigns/:id/pausePauses an active campaign. No new calls will be initiated while paused.
Path Parameters
Parameters
| Name | Type | Description |
|---|---|---|
idRequired | uuid | The campaign's unique identifier |
Example Request
curl -X POST "https://www.nutalk.ai/v1/campaigns/camp_abc123/pause" \ -H "Authorization: Bearer YOUR_API_KEY"Response
{
"success": true,
"data": {
"id": "camp_abc123",
"name": "Q1 Outreach",
"status": "paused",
"type": "outbound",
"updated_at": "2024-01-25T18:00:00Z"
},
"message": "Campaign paused successfully"
}Campaign Statuses
| Status | Description | Allowed Actions |
|---|---|---|
| draft | Campaign is being configured | start, update, delete |
| active | Campaign is running and processing enrollments | pause, update |
| paused | Campaign is paused, no new calls | start, update, delete |
| completed | All enrollments have been processed | delete (archive) |
| archived | Campaign has been archived | none (read-only) |
Enroll a Contact
/v1/campaigns/:id/enrollmentsAdds one contact to the campaign. The contact is created or matched by phone number, then enrolled according to the campaign's deduplication policy. On an active campaign the first call happens within seconds; with API import enabled on the campaign (Integrations tab), a draft or paused campaign holds the contact until it starts. Supports the Idempotency-Key header.
Request Body
Parameters
| Name | Type | Description |
|---|---|---|
phone_numberRequired | string | Phone number with country code, e.g. +5215512345678 |
name | string | Display name |
email | string | Email address |
lead_data | object | Any extra fields; available to the agent as lead data |
source_metadata | object | Free-form origin details stored with the enrollment |
Example Request
curl -X POST "https://www.nutalk.ai/v1/campaigns/camp_abc123/enrollments" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone_number": "+5215512345678", "name": "Ana López", "lead_data": { "product": "Plan Pro" } }'Response
{
"success": true,
"data": {
"enrollment_id": "enr_123",
"contact_id": "con_456",
"action": "created",
"status": "queued",
"campaign_status": "active"
}
}Held contacts
status: "enrolled" means the campaign is not active yet and the contact waits for the start. Without API import enabled, an inactive campaign answers 409.
Import Contacts (bulk)
/v1/campaigns/:id/contacts/importImports up to 500 contacts in one request. Every row is validated (phone format, duplicates within the request, already enrolled) and the response reports the outcome of each row, so your system knows exactly which contacts were refused and why. The run is recorded in the campaign's import history. Supports the Idempotency-Key header.
Request Body
Parameters
| Name | Type | Description |
|---|---|---|
contactsRequired | array | 1–500 objects with phone_number (required) and optional name, first_name, last_name, email, company, external_id, notes, lead_data and any custom field |
source | string | Origin label (e.g. salesforce). Stored as the enrollment source and as the key of external_id on the contact. Defaults to api |
Example Request
curl -X POST "https://www.nutalk.ai/v1/campaigns/camp_abc123/contacts/import" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "source": "my_crm", "contacts": [ { "phone_number": "+5215512345678", "name": "Ana López", "company": "Acme", "external_id": "crm-1001" }, { "phone_number": "+15550000000", "name": "Bob" }, { "phone_number": "12", "name": "Invalid" } ] }'Response
{
"success": true,
"data": {
"batch_id": "batch_789",
"campaign_status": "active",
"summary": { "total": 3, "enrolled": 2, "held": 0, "updated": 0, "skipped": 0, "rejected": 1 },
"rows": [
{ "index": 0, "phone_number": "+5215512345678", "status": "enrolled", "contact_id": "con_1", "enrollment_id": "enr_1" },
{ "index": 1, "phone_number": "+15550000000", "status": "enrolled", "contact_id": "con_2", "enrollment_id": "enr_2" },
{ "index": 2, "phone_number": "12", "status": "rejected", "reason": "invalid_phone",
"message": "Phone number must have 8 to 15 digits including the country code" }
]
}
}Row statuses
enrolled (queued to dial), held (waits for the campaign to start), updated (deduplication policy update_only), skipped (already enrolled) and rejected with a reason: missing_phone, invalid_phone, duplicate_in_request, campaign_not_accepting.