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

# Create Campaign

> Create a new campaign with scheduling, retry logic, and do-not-call rules

# Create Campaign

Create a new campaign with scheduling, retry policy, cooldowns, and do-not-call rules. Campaigns are created in `draft` status — call [Update Campaign Status](/api-reference/endpoints/update-campaign-status) with `"status": "active"` to start dispatching calls.

## Endpoint

```
POST /api/v1/campaigns
```

## Request headers

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication. Format: `Bearer talq_your_environment_token_here`
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be set to `application/json`
</ParamField>

## Request body

### Identification

<ParamField body="name" type="string" required>
  Campaign name. Max 255 characters.
</ParamField>

<ParamField body="description" type="string" required={false}>
  Free-form description of the campaign.
</ParamField>

<ParamField body="campaign_type" type="string" required>
  Campaign category. Options: `sales`, `follow_up`, `reminder`, `custom`.
</ParamField>

<ParamField body="agent_id" type="string" required>
  UUID of the agent assigned to the campaign. The agent must exist in your environment.
</ParamField>

### Schedule

<ParamField body="start_date" type="string" required>
  Date the campaign becomes eligible to dispatch calls. Format: `YYYY-MM-DD`.
</ParamField>

<ParamField body="end_date" type="string" required={false}>
  Optional end date. Must be after `start_date`. Format: `YYYY-MM-DD`.
</ParamField>

<ParamField body="days_of_week" type="array" required>
  Array of weekday numbers when calls can be placed. `1` = Monday, `7` = Sunday. At least one value required.
</ParamField>

<ParamField body="call_time_ranges" type="array" required>
  Time windows (per day) during which calls can be dispatched. Array of objects with `start` and `end` in `HH:MM` format (24h). At least one window required. Each window's `end` must be after its `start`.

  Example: `[{"start": "09:00", "end": "12:00"}, {"start": "14:00", "end": "17:00"}]`
</ParamField>

<ParamField body="timezone" type="string" required>
  IANA timezone for `call_time_ranges` (e.g., `America/New_York`, `America/Sao_Paulo`, `Europe/London`). Max 50 characters.
</ParamField>

### Retry & Cooldown

<ParamField body="initial_call_delay" type="integer" required={false}>
  Initial delay (in seconds) before the first call attempt. Default: `0`.
</ParamField>

<ParamField body="max_retries" type="integer" required={false}>
  Maximum retry attempts per contact. Range: `0`–`10`. Default: `3`.
</ParamField>

<ParamField body="retry_cooldown_hours" type="integer" required={false}>
  Hours to wait between retry attempts. Range: `1`–`168`. Default: `24`.
</ParamField>

<ParamField body="auto_complete" type="boolean" required={false}>
  When `true`, the campaign automatically transitions to `completed` once all contacts have been processed.
</ParamField>

<ParamField body="retry_on_no_conversion" type="boolean" required={false}>
  When `true`, calls that completed but didn't convert are retried after the cooldown.
</ParamField>

<ParamField body="enable_post_completion_cooldown" type="boolean" required={false}>
  When `true`, applies a cooldown to all contacts after the campaign completes (prevents immediate re-engagement by another campaign).
</ParamField>

<ParamField body="post_completion_cooldown_hours" type="integer" required={false}>
  Hours of cooldown applied to contacts after campaign completion. Range: `1`–`168`. Default: `168`.
</ParamField>

#### Per-status cooldowns

These optional fields override `retry_cooldown_hours` for specific call outcomes. All in range `1`–`168` hours.

<ParamField body="success_cooldown_hours" type="integer" required={false}>
  Cooldown after a successful call.
</ParamField>

<ParamField body="voicemail_cooldown_hours" type="integer" required={false}>
  Cooldown after reaching voicemail.
</ParamField>

<ParamField body="no_answer_cooldown_hours" type="integer" required={false}>
  Cooldown after no-answer.
</ParamField>

<ParamField body="busy_cooldown_hours" type="integer" required={false}>
  Cooldown after busy signal.
</ParamField>

<ParamField body="failed_cooldown_hours" type="integer" required={false}>
  Cooldown after a failed call.
</ParamField>

### Do-Not-Call (DNC)

<ParamField body="do_not_call_enabled" type="boolean" required={false}>
  When `true`, contacts are checked against a DNC list before dispatching. Default: `false`.
</ParamField>

<ParamField body="do_not_call_list_source" type="string" required={false}>
  Source of the DNC list. Options:

  * `environment` — DNC list shared across all campaigns in this environment
  * `global` — platform-wide DNC list
  * `custom` — campaign-specific list provided in `do_not_call_custom_list`
</ParamField>

<ParamField body="do_not_call_custom_list" type="array" required={false}>
  Array of phone numbers (E.164) blocked for this campaign. Used only when `do_not_call_list_source` is `custom`.
</ParamField>

<ParamField body="auto_add_to_dnc_enabled" type="boolean" required={false}>
  When `true`, contacts that match `auto_dnc_trigger_statuses` or `auto_dnc_trigger_errors` are automatically added to the DNC list.
</ParamField>

<ParamField body="auto_dnc_trigger_statuses" type="array" required={false}>
  Call statuses that trigger auto-add to DNC. Example: `["completed", "voicemail"]`.
</ParamField>

<ParamField body="auto_dnc_trigger_errors" type="array" required={false}>
  Call errors that trigger auto-add to DNC. Example: `["invalid_number", "disconnected"]`.
</ParamField>

## Examples

<RequestExample>
  ```bash theme={null}
  # Basic sales campaign — weekdays 09:00–17:00 New York
  curl -X POST "https://app.talkover.ai/api/v1/campaigns" \
    -H "Authorization: Bearer talq_your_environment_token_here" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Sales Campaign Q1",
      "description": "Outbound sales campaign for Q1",
      "campaign_type": "sales",
      "agent_id": "agent-uuid-1",
      "start_date": "2024-01-01",
      "days_of_week": [1, 2, 3, 4, 5],
      "call_time_ranges": [
        {"start": "09:00", "end": "17:00"}
      ],
      "timezone": "America/New_York"
    }'
  ```

  ```javascript theme={null}
  const response = await fetch('https://app.talkover.ai/api/v1/campaigns', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer talq_your_environment_token_here',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name: 'Sales Campaign Q1',
      description: 'Outbound sales campaign for Q1',
      campaign_type: 'sales',
      agent_id: 'agent-uuid-1',
      start_date: '2024-01-01',
      days_of_week: [1, 2, 3, 4, 5],
      call_time_ranges: [
        { start: '09:00', end: '17:00' }
      ],
      timezone: 'America/New_York'
    })
  });

  const result = await response.json();
  ```

  ```python theme={null}
  import requests

  url = "https://app.talkover.ai/api/v1/campaigns"
  headers = {
      "Authorization": "Bearer talq_your_environment_token_here",
      "Content-Type": "application/json"
  }
  data = {
      "name": "Sales Campaign Q1",
      "description": "Outbound sales campaign for Q1",
      "campaign_type": "sales",
      "agent_id": "agent-uuid-1",
      "start_date": "2024-01-01",
      "days_of_week": [1, 2, 3, 4, 5],
      "call_time_ranges": [
          {"start": "09:00", "end": "17:00"}
      ],
      "timezone": "America/New_York"
  }

  response = requests.post(url, headers=headers, json=data)
  result = response.json()
  ```
</RequestExample>

<RequestExample>
  ```bash theme={null}
  # Campaign with split call windows + custom DNC + per-status cooldowns
  curl -X POST "https://app.talkover.ai/api/v1/campaigns" \
    -H "Authorization: Bearer talq_your_environment_token_here" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Follow-up Campaign",
      "campaign_type": "follow_up",
      "agent_id": "agent-uuid-2",
      "start_date": "2024-01-15",
      "end_date": "2024-03-31",
      "days_of_week": [1, 2, 3, 4, 5],
      "call_time_ranges": [
        {"start": "10:00", "end": "12:00"},
        {"start": "14:00", "end": "17:00"}
      ],
      "timezone": "America/Sao_Paulo",
      "max_retries": 5,
      "retry_cooldown_hours": 48,
      "success_cooldown_hours": 168,
      "voicemail_cooldown_hours": 24,
      "no_answer_cooldown_hours": 12,
      "busy_cooldown_hours": 6,
      "failed_cooldown_hours": 72,
      "do_not_call_enabled": true,
      "do_not_call_list_source": "custom",
      "do_not_call_custom_list": ["+15551234567", "+15559876543"],
      "auto_add_to_dnc_enabled": true,
      "auto_dnc_trigger_statuses": ["completed"],
      "auto_dnc_trigger_errors": ["invalid_number"]
    }'
  ```
</RequestExample>

## Response

### Success Response (201 Created)

<ResponseExample>
  ```json theme={null}
  {
    "success": true,
    "data": {
      "id": "campaign-uuid-1",
      "name": "Sales Campaign Q1",
      "description": "Outbound sales campaign for Q1",
      "campaign_type": "sales",
      "status": "draft",
      "agent_id": "agent-uuid-1",
      "start_date": "2024-01-01",
      "end_date": null,
      "days_of_week": [1, 2, 3, 4, 5],
      "call_time_ranges": [
        {"start": "09:00", "end": "17:00"}
      ],
      "timezone": "America/New_York",
      "max_retries": 3,
      "retry_cooldown_hours": 24,
      "do_not_call_enabled": false,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  }
  ```
</ResponseExample>

### Response fields

<ResponseField name="success" type="boolean" required>
  Indicates if the campaign was created successfully.
</ResponseField>

<ResponseField name="data" type="object" required>
  The created campaign object. New campaigns start in `status: "draft"`. Use [Update Campaign Status](/api-reference/endpoints/update-campaign-status) to activate.
</ResponseField>

## Error responses

### 422 Validation Error

<ResponseExample>
  ```json theme={null}
  {
    "success": false,
    "message": "The given data was invalid.",
    "errors": {
      "agent_id": ["The selected agent id is invalid."],
      "call_time_ranges": ["The call time ranges field is required."],
      "call_time_ranges.0.end": ["The call time ranges.0.end must be a date after call time ranges.0.start."],
      "days_of_week.0": ["The days of week.0 must be between 1 and 7."]
    }
  }
  ```
</ResponseExample>

### 401 Unauthorized

<ResponseExample>
  ```json theme={null}
  {
    "message": "Missing Bearer Token"
  }
  ```
</ResponseExample>

### 403 Forbidden — Plan Limit Reached

<ResponseExample>
  ```json theme={null}
  {
    "success": false,
    "message": "Your plan does not allow creating more campaigns",
    "code": "CAMPAIGN_LIMIT_REACHED"
  }
  ```
</ResponseExample>

## Notes

* The campaign agent must already exist. Create it via [Create Agent](/api-reference/endpoints/create-agent).
* `call_time_ranges` replaces the older `earliest_call_time`/`latest_call_time` fields. Multiple windows let you skip lunch hours or split between morning and afternoon.
* All `*_cooldown_hours` fields default to `24` if not provided. Use them to fine-tune retry behavior per call outcome.
* Time windows are evaluated in the campaign's `timezone`, not the caller's local time.

## Related endpoints

* [List Campaigns](/api-reference/endpoints/list-campaigns)
* [Get Campaign](/api-reference/endpoints/get-campaign)
* [Update Campaign](/api-reference/endpoints/update-campaign)
* [Update Campaign Status](/api-reference/endpoints/update-campaign-status)
* [Make Campaign Call](/api-reference/endpoints/make-campaign-call)
