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

# Create Campaign

> Create a new outbound calling campaign with CSV contacts

## Create Campaign

Create a new outbound calling campaign by uploading a CSV file with contacts and configuring campaign parameters.

This is a **multipart/form-data** endpoint — send the CSV file and all configuration fields together in a single request.

***

## Request Parameters

<ParamField body="csv_file" type="file" required>
  CSV file with contact data. Required columns: `name`, `phone_number`
</ParamField>

<ParamField body="campaign_name" type="string" required>
  Human-readable name for the campaign (max 255 characters)
</ParamField>

<ParamField body="agent_id" type="string" required>
  UUID of the agent that will handle calls
</ParamField>

<ParamField body="concurrency" type="integer" required>
  Simultaneous calls (≥ 1, ≤ organization max)
</ParamField>

<ParamField body="from_date" type="string" required>
  Campaign start date — `YYYY-MM-DD`
</ParamField>

<ParamField body="to_date" type="string" required>
  Campaign end date — `YYYY-MM-DD` (≥ `from_date`)
</ParamField>

<ParamField body="start_time" type="string" required>
  Daily call window open — UTC `HH:MM` 24-hour format (e.g. `02:30`)
</ParamField>

<ParamField body="end_time" type="string" required>
  Daily call window close — UTC `HH:MM` 24-hour format (e.g. `14:00`)
</ParamField>

<ParamField body="days_of_week" type="string" required>
  Comma-separated weekdays, e.g. `monday,tuesday,friday`
</ParamField>

<ParamField body="perform_dnd_check" type="boolean" default="false">
  Run DND check on contacts before dialing
</ParamField>

<ParamField body="max_retries" type="integer" default="3">
  Max dial attempts per contact (1–10)
</ParamField>

<ParamField body="retry_delay_mins" type="integer" default="30">
  Minutes between retry attempts (0–1440)
</ParamField>

<ParamField body="notification_emails" type="string">
  Comma-separated email addresses for completion notifications (max 5)
</ParamField>

<ParamField body="campaign_webhook_url" type="string">
  HTTP/HTTPS URL to receive campaign status-change events
</ParamField>

<ParamField body="per_call_webhook_url" type="string">
  HTTP/HTTPS URL to receive per-call post-processing events
</ParamField>

***

## Time Window Reference

All times must be in **24-hour HH:MM format in UTC only**.

| Allowed UTC range | Equivalent IST range |
| ----------------- | -------------------- |
| `02:30` – `14:29` | `08:00` – `19:59`    |

> TRAI compliance window is 08:00–19:59 IST. Submit the UTC equivalent.\
> To convert: IST − 5:30 = UTC (e.g. 13:00 IST = 07:30 UTC)

***

## Example Request

```bash theme={null}
curl -X POST https://api.vaani.ai/api/campaigns/create \
  -H "X-API-Key: vaani_abc123..." \
  -F "csv_file=@contacts.csv" \
  -F "campaign_name=Summer Promo 2024" \
  -F "agent_id=5e737076-fea2-4157-8343-a8e49e5f0990" \
  -F "concurrency=3" \
  -F "from_date=2026-07-10" \
  -F "to_date=2026-07-31" \
  -F "start_time=07:30" \
  -F "end_time=13:30" \
  -F "days_of_week=monday,tuesday,wednesday,thursday,friday" \
  -F "notification_emails=ops@company.com"
```

***

## Response `201 Created`

```json theme={null}
{
  "id": "57fbcf93-a809-4038-8ea9-d676cf7d7fd4",
  "client_id": "1b9e0250-d265-4a67-bb03-c40c98978c76",
  "agent_id": "5e737076-fea2-4157-8343-a8e49e5f0990",
  "campaign_name": "Summer Promo 2024",
  "excel_blob_url": "https://vaani-dev-storage.s3.ap-south-1.amazonaws.com/campaigns/...",
  "campaign_status": "active",
  "contact_source_type": "csv",
  "days_of_week": "monday,tuesday,wednesday,thursday,friday",
  "time_range_from": "07:30:00Z",
  "time_range_to": "13:30:00Z",
  "max_retries": 3,
  "retry_after_mins": 30,
  "call_concurrency": 3,
  "start_date": "2026-07-10T02:00:00",
  "end_date": "2026-07-31T04:00:00",
  "notification_emails": ["ops@company.com"],
  "webhook_url": null,
  "perform_dnd_check": false,
  "created_at": "2026-07-01T08:59:33.063483",
  "updated_at": "2026-07-01T08:59:33.063487"
}
```

***

## CSV File Requirements

### Required Columns

| Column         | Aliases accepted                                                |
| -------------- | --------------------------------------------------------------- |
| `name`         | `contact_name`, `customer_name`, `full_name`                    |
| `phone_number` | `phone`, `mobile`, `contact`, `contact_number`, `mobile_number` |

### Optional Columns

Any extra columns are treated as **dynamic variables** passed to the agent.
Column names must exactly match (case-sensitive) the variable names configured on the agent.

### File Limits

| Property | Limit                   |
| -------- | ----------------------- |
| Formats  | `.csv`, `.xlsx`, `.xls` |
| Encoding | UTF-8                   |
| Max rows | 10,000 contacts         |
| Min rows | 1 contact               |

### Phone Number Formats Accepted

* `+91XXXXXXXXXX` (E.164 with country code)
* `91XXXXXXXXXX` (country code without `+`)
* `0XXXXXXXXXX` (leading zero, Indian trunk prefix)
* `XXXXXXXXXX` (bare 10-digit number)

***

## Error Responses

<ResponseField name="status_code" type="number">
  HTTP status code
</ResponseField>

<ResponseField name="error" type="string">
  Error name
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable error message
</ResponseField>

<ResponseField name="code" type="string">
  Machine-readable error code
</ResponseField>

### Common Error Codes

| Code                   | Description                                     |
| ---------------------- | ----------------------------------------------- |
| `INVALID_TIME_WINDOW`  | Time outside 02:30-14:29 UTC (TRAI compliance)  |
| `CONCURRENCY_EXCEEDED` | Concurrency exceeds organization maximum        |
| `INVALID_DATE_RANGE`   | from\_date > to\_date                           |
| `NO_DAYS_SELECTED`     | days\_of\_week is empty                         |
| `INVALID_RETRY_CONFIG` | max\_retries or retry\_delay\_mins out of range |
| `TOO_MANY_EMAILS`      | More than 5 notification\_emails                |

### Example Error Response

```json theme={null}
{
  "status_code": 400,
  "error": "Bad Request",
  "message": "concurrency 50 exceeds your organisation's maximum of 10.",
  "code": "CONCURRENCY_EXCEEDED",
  "path": "/api/campaigns/create",
  "timestamp": "2026-07-01T08:51:11.245139Z",
  "request_id": "unknown"
}
```
