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

# Campaign lifecycle

> Start, pause, and stop campaigns to control dialing.

Campaigns follow a state machine: `draft → running ↔ paused → completed`.
The `stop` action is **terminal** — a stopped campaign cannot be restarted.

```
  ┌───────┐     start      ┌─────────┐
  │ draft │───────────────▶│ running │
  └───────┘                └────┬────┘
                                │
                   pause ↓      ↑ start
                                │
                           ┌────┴────┐
                           │ paused  │
                           └────┬────┘
                                │
                   stop ↓       │ stop
                                ↓
                          ┌───────────┐
                          │ completed │  (terminal)
                          └───────────┘
```

## Start a campaign

Transitions a campaign from `draft` or `paused` to `running`. The dialer
begins placing calls according to the configured `dial_mode`.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.yotel.in/api/v1/campaigns/{campaign_id}/start \
    -H "Authorization: Bearer yt_live_YOUR_KEY"
  ```

  ```python Python theme={null}
  campaign = client.campaigns.start("campaign_id")
  ```

  ```typescript TypeScript theme={null}
  const campaign = await client.campaigns.start("campaign_id");
  ```
</CodeGroup>

**Scope:** `campaigns:write`  |  **Status:** `200 OK`

Returns the updated `CampaignResponse` with `status: "running"`.

***

## Pause a campaign

Transitions a running campaign to `paused`. The dialer stops placing new
calls but in-progress calls continue until completion.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.yotel.in/api/v1/campaigns/{campaign_id}/pause \
    -H "Authorization: Bearer yt_live_YOUR_KEY"
  ```

  ```python Python theme={null}
  campaign = client.campaigns.pause("campaign_id")
  ```

  ```typescript TypeScript theme={null}
  const campaign = await client.campaigns.pause("campaign_id");
  ```
</CodeGroup>

**Scope:** `campaigns:write`  |  **Status:** `200 OK`

<Note>
  Campaigns can also be auto-paused by the system when the abandon rate
  approaches the 3% TRAI cap. When this happens, a `campaign.paused`
  webhook fires with `source: "abandon_rate_exceeded"`.
</Note>

***

## Stop a campaign

Transitions a running or paused campaign to `completed`. This is
**terminal** — the campaign cannot be restarted. To resume dialing the
same leads, create a new campaign and re-import.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.yotel.in/api/v1/campaigns/{campaign_id}/stop \
    -H "Authorization: Bearer yt_live_YOUR_KEY"
  ```

  ```python Python theme={null}
  campaign = client.campaigns.stop("campaign_id")
  ```

  ```typescript TypeScript theme={null}
  const campaign = await client.campaigns.stop("campaign_id");
  ```
</CodeGroup>

**Scope:** `campaigns:write`  |  **Status:** `200 OK`

***

## Errors

| Status | Condition                                                                                            |
| ------ | ---------------------------------------------------------------------------------------------------- |
| `404`  | Campaign not found or belongs to another tenant                                                      |
| `409`  | Invalid state transition (e.g., starting an already-running campaign, stopping a completed campaign) |
