> ## Documentation Index
> Fetch the complete documentation index at: https://kb.vinfer.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Campaigns API — Create and Manage Calling Campaigns

> REST API endpoints for creating, listing, monitoring, pausing, and stopping outbound voice calling campaigns powered by VInfer Neuron.

Campaigns are the core organizing unit of VInfer Neuron. A campaign ties together a contact list, a voice script, a language, and a calling schedule into a single managed run. Once launched, Neuron dials each contact automatically, follows the script, records dispositions, and retries based on your configuration. The Campaigns API lets you create and control all of this programmatically — without touching the dashboard.

***

## Create a Campaign

<code>POST /campaigns</code>

Creates a new outbound calling campaign. The campaign starts in `scheduled` status and begins dialing at the configured `start_time` (or immediately if no schedule is set and you later call the start action).

### Request Body

<ParamField body="name" type="string" required>
  A human-readable display name for the campaign. Shown in the dashboard and included in webhook payloads. Maximum 255 characters.
</ParamField>

<ParamField body="script_id" type="string" required>
  The ID of the voice script to use. Scripts are created and managed in the Neuron section of the dashboard under **Scripts**. You can find the script ID on the script detail page.
</ParamField>

<ParamField body="language" type="string" required>
  BCP-47 language code for the campaign. Determines the voice model and speech recognition used during calls. Examples: `hi-IN` (Hindi), `ta-IN` (Tamil), `en-IN` (English — India).
</ParamField>

<ParamField body="contacts" type="array" required>
  Array of contact objects to call. Each contact must include `phone` (E.164 format, e.g. `+919876543210`) and `name` (string). You can also include any custom fields as additional key-value pairs on the contact object — they are passed into the script context at call time.

  <Expandable title="Contact object fields">
    <ParamField body="contacts[].phone" type="string" required>
      The contact's phone number in E.164 format. Must include the country code prefix (e.g., `+91` for India).
    </ParamField>

    <ParamField body="contacts[].name" type="string" required>
      The contact's name. Used within the script for personalization (e.g., "Hello, {name}").
    </ParamField>

    <ParamField body="contacts[].*" type="any">
      Any additional fields you include are treated as custom variables available within the script template. For example, `"loan_amount": "50000"` can be referenced in the script as `{loan_amount}`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="schedule" type="object">
  Optional scheduling configuration. If omitted, the campaign can be started manually from the dashboard or via `PATCH /campaigns/{id}`.

  <Expandable title="Schedule object fields">
    <ParamField body="schedule.start_time" type="string">
      ISO 8601 datetime at which the campaign should begin dialing. Example: `2024-02-01T09:00:00`.
    </ParamField>

    <ParamField body="schedule.end_time" type="string">
      ISO 8601 datetime at which the campaign should stop, even if contacts remain. Calls already in progress when this time is reached are allowed to complete.
    </ParamField>

    <ParamField body="schedule.timezone" type="string">
      IANA timezone name for the `start_time` and `end_time` values. Example: `Asia/Kolkata`. Defaults to UTC if not specified.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="max_attempts" type="integer" default="1">
  Maximum number of call attempts per contact. Accepted values are `1` through `5`. Contacts that are not reachable after all attempts are marked with disposition `not_reachable`.
</ParamField>

<ParamField body="retry_interval_minutes" type="integer" default="240">
  Number of minutes to wait between retry attempts for a contact who was not reachable. Only applies when `max_attempts` is greater than `1`.
</ParamField>

### Example Request

```bash cURL theme={null}
curl https://api.vinfer.ai/v1/campaigns \
  -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "February Loan Renewal Outreach",
    "script_id": "scr_7xK2pL9mN",
    "language": "hi-IN",
    "contacts": [
      {"phone": "+919876543210", "name": "Priya Sharma", "loan_amount": "75000"},
      {"phone": "+918765432109", "name": "Rahul Verma", "loan_amount": "120000"}
    ],
    "schedule": {
      "start_time": "2024-02-01T09:00:00",
      "end_time": "2024-02-01T18:00:00",
      "timezone": "Asia/Kolkata"
    },
    "max_attempts": 3,
    "retry_interval_minutes": 120
  }'
```

### Example Response

```json theme={null}
{
  "id": "cmp_4Rv8sT1wX",
  "name": "February Loan Renewal Outreach",
  "status": "scheduled",
  "script_id": "scr_7xK2pL9mN",
  "language": "hi-IN",
  "total_contacts": 2,
  "max_attempts": 3,
  "retry_interval_minutes": 120,
  "schedule": {
    "start_time": "2024-02-01T09:00:00",
    "end_time": "2024-02-01T18:00:00",
    "timezone": "Asia/Kolkata"
  },
  "created_at": "2024-01-28T14:22:10Z"
}
```

***

## List Campaigns

<code>GET /campaigns</code>

Returns a paginated list of campaigns in your workspace, ordered by creation date descending.

### Query Parameters

<ParamField query="status" type="string">
  Filter by campaign status. One of: `scheduled`, `running`, `paused`, `completed`, `stopped`.
</ParamField>

<ParamField query="from" type="string">
  ISO 8601 date — return campaigns created on or after this date. Example: `2024-01-01`.
</ParamField>

<ParamField query="to" type="string">
  ISO 8601 date — return campaigns created on or before this date.
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Number of results per page. Maximum `100`.
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Number of results to skip. Use with `limit` to paginate through results.
</ParamField>

### Example Request

```bash theme={null}
curl "https://api.vinfer.ai/v1/campaigns?status=running&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

***

## Get Campaign Details

<code>GET /campaigns/\{id}</code>

Returns full details for a single campaign, including real-time progress counters and a breakdown of call dispositions.

### Response Fields

<ResponseField name="id" type="string">
  Unique identifier for the campaign.
</ResponseField>

<ResponseField name="name" type="string">
  Campaign display name.
</ResponseField>

<ResponseField name="status" type="string">
  Current campaign status: `scheduled`, `running`, `paused`, `completed`, or `stopped`.
</ResponseField>

<ResponseField name="total_contacts" type="integer">
  Total number of contacts in the campaign (including contacts removed via the contacts endpoint).
</ResponseField>

<ResponseField name="calls_made" type="integer">
  Number of call attempts made so far (including retries).
</ResponseField>

<ResponseField name="calls_connected" type="integer">
  Number of calls where the contact answered and the conversation began.
</ResponseField>

<ResponseField name="disposition_summary" type="object">
  A breakdown of outcome counts by disposition label.

  <Expandable title="Disposition summary fields">
    <ResponseField name="disposition_summary.interested" type="integer">
      Contacts who expressed interest during the call.
    </ResponseField>

    <ResponseField name="disposition_summary.not_interested" type="integer">
      Contacts who declined or were not interested.
    </ResponseField>

    <ResponseField name="disposition_summary.callback" type="integer">
      Contacts who asked to be called back at a later time.
    </ResponseField>

    <ResponseField name="disposition_summary.not_reachable" type="integer">
      Contacts who did not answer after all configured attempts.
    </ResponseField>

    <ResponseField name="disposition_summary.dnd" type="integer">
      Contacts who requested to be added to the do-not-disturb list.
    </ResponseField>

    <ResponseField name="disposition_summary.escalated" type="integer">
      Calls that were escalated to a human agent.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 timestamp of when the campaign was created.
</ResponseField>

***

## Update Campaign Status

<code>PATCH /campaigns/\{id}</code>

Pauses, resumes, or stops a campaign that is currently running or paused. Pass an `action` field in the request body.

### Request Body

<ParamField body="action" type="string" required>
  The action to perform. One of:

  * `pause` — suspends dialing; calls already in progress are allowed to finish.
  * `resume` — resumes a paused campaign.
  * `stop` — permanently stops the campaign; cannot be restarted.
</ParamField>

### Example Request

```bash theme={null}
curl https://api.vinfer.ai/v1/campaigns/cmp_4Rv8sT1wX \
  -X PATCH \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action": "pause"}'
```

<Warning>
  The `stop` action is irreversible. A stopped campaign cannot be resumed. If you need to temporarily halt a campaign, use `pause` instead.
</Warning>

***

## Remove Contacts from a Campaign

<code>DELETE /campaigns/\{id}/contacts</code>

Removes specific contacts from an active or scheduled campaign. Use this to apply DNC (Do Not Call) suppression after a campaign has already been created, or to remove contacts who have since converted through another channel.

### Request Body

<ParamField body="phones" type="array" required>
  Array of phone numbers in E.164 format to remove from the campaign. Contacts who have already been called are not affected — only pending contacts are removed.
</ParamField>

### Example Request

```bash theme={null}
curl https://api.vinfer.ai/v1/campaigns/cmp_4Rv8sT1wX/contacts \
  -X DELETE \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phones": ["+919876543210", "+918765432109"]}'
```

### Example Response

```json theme={null}
{
  "removed": 2,
  "not_found": 0,
  "already_called": 0
}
```

<Note>
  Contacts that were already called before this request are counted in `already_called` and are not removed from the campaign record — their call data is preserved for reporting.
</Note>
