# Resume a paused campaign

Source: https://docs.usetone.ai/reference/campaigns/resume

> Picks up where it stopped, on the version of the agent it launched with.

`POST /v1/campaigns/{id}/resume`
Picks up where it stopped, on the version of the agent it launched with. Top the wallet up first if it paused for low balance, or it will pause again.

Requires the `write` scope.

## Parameters

| Name | In | | Meaning |
|---|---|---|---|
| `id` | path | required | The campaign's id. |

## Response

| Field | Type | | Meaning |
|---|---|---|---|
| `agent` | object | required | The agent as it was at launch. `id` goes null if the agent is later deleted; `name` keeps saying what ran. |
| `agent.id` | string | null | required | The agent's id, or null if it has since been deleted. |
| `agent.name` | string | null | required | The agent's name at launch. Kept even after the agent is deleted, so the record still says what ran. |
| `archivedAt` | string | null | required | When it was filed out of the list. Archived campaigns are hidden from `GET /v1/campaigns` unless `archived=true`; the detail route always serves them. |
| `autoPauseBelowPaise` | integer | required | Pause below this wallet balance. 0 means the floor is off. |
| `completedAt` | string | null | required | When the last recipient settled. RFC 3339, UTC. Null until the campaign finishes. |
| `createdAt` | string | required | RFC 3339, UTC. |
| `environment` | string | required | `live` or `test` — inherited from the credential that created it. |
| `id` | string | required | The campaign's unique id. |
| `launchedAt` | string | null | required | When the campaign was launched. RFC 3339, UTC. Null while it is still a draft. |
| `name` | string | required | Your label for the campaign. |
| `number` | object | required | The from-number as it was at launch. Same snapshot rule as `agent`. |
| `number.e164` | string | null | required | The number dialled from, in E.164. Kept after release, so the record still says which line called. |
| `number.id` | string | null | required | The number's id, or null if it has since been released. |
| `pacing` | object | required | How fast this campaign dials. |
| `pacing.callsPerMinute` | integer | required | How fast the campaign dials, in calls per minute. |
| `pacing.maxConcurrent` | integer | required | Above your concurrency quota this does not queue — the overflow settles as failed. See `GET /v1/limits`. |
| `pausedReason` | string | null | required | Why it stopped dialling. Null while healthy. Open set — handle an unrecognised value rather than throwing. Today: `operator`, `low_balance`, `target_unavailable`, `carrier_errors`. |
| `preflight` | object | null | required | The cached pre-flight funnel, or null if it has not been computed yet. Launch recomputes rather than trusting it. |
| `progress` | object | required | Counters cached on the campaign row, written alongside the recipient rows they summarise. If they ever disagree with the recipients, the recipients are right. |
| `progress.connected` | integer | required | Recipients who answered. Never exceeds `dialed`. |
| `progress.dialed` | integer | required | Recipients dialled at least once. Retries do not double-count. |
| `progress.excluded` | integer | required | Recipients the pre-dial gate removed — suppression list, missing consent, outside the calling window. Never dialled, never billed. |
| `progress.spentPaise` | integer | required | What this campaign has cost so far, in paise. |
| `progress.total` | integer | required | Recipients uploaded, before exclusions. |
| `purpose` | string | null | required | The sender classification this campaign ran under, snapshotted at launch. It decides which calling window applied, so it is evidence — not a live read of the agent. |
| `retries` | object | required | How this campaign retries recipients it did not reach. The retry tail has to fit inside the calling window, or the campaign is refused at launch. |
| `retries.attempts` | integer | required | How many times a recipient is redialled before giving up. |
| `retries.backoff` | string | required | Retry spacing. Open set — handle an unrecognised value rather than throwing. Today: `linear`, `exponential`. |
| `retries.intervalMinutes` | integer | required | Minutes before the first retry. |
| `retries.on` | string[] | required | Which dispositions are retried. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`. |
| `schedule` | object | required | When this campaign is allowed to dial. Narrower than the legal window, never wider — the compliance gate still runs on every call. |
| `schedule.endsAt` | string | null | required | Stop dialling at this instant even if recipients remain. RFC 3339, UTC. |
| `schedule.startsAt` | string | null | required | Do not dial before this instant. RFC 3339, UTC. |
| `schedule.weekdays` | integer | required | 7-bit mask, Monday = bit 0. |
| `schedule.windowEndMinute` | integer | required | Minutes from midnight IST. |
| `schedule.windowStartMinute` | integer | required | Minutes from midnight IST. Dialling never happens outside the window. |
| `status` | string | required | Lifecycle position. `paused` is resumable; `stopped` is terminal and abandons the remaining recipients. Open set — handle an unrecognised value rather than throwing. Today: `draft`, `scheduled`, `running`, `paused`, `completed`, `stopped`, `failed`. |
| `updatedAt` | string | required | When the campaign was last changed. RFC 3339, UTC. |

### Example response

```json
{
  "data": {
    "agent": {
      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
      "name": "Order confirmation"
    },
    "archivedAt": null,
    "autoPauseBelowPaise": 50000,
    "completedAt": null,
    "createdAt": "2026-08-25T09:14:22Z",
    "environment": "live",
    "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
    "launchedAt": "2026-09-01T04:00:00Z",
    "name": "COD confirmations — September",
    "number": {
      "e164": "+918045678901",
      "id": "4c8b1e77-3d2a-4f5b-9e6c-8a7b6c5d4e3f"
    },
    "pacing": {
      "callsPerMinute": 10,
      "maxConcurrent": 4
    },
    "pausedReason": "operator",
    "preflight": {
      "callable": 0,
      "checks": [
        {
          "outcome": "pass",
          "reason": "Outside the 09:00-21:00 IST window for promotional calls.",
          "type": "time_window"
        }
      ],
      "computedAt": "2026-09-01T03:58:12Z",
      "estimatedCostPaise": {
        "high": 480000,
        "low": 120000
      },
      "excluded": "invalid_number",
      "excludedE164s": {},
      "total": 0,
      "walletBalancePaise": 500000
    },
    "progress": {
      "connected": 244,
      "dialed": 320,
      "excluded": 31,
      "spentPaise": 146400,
      "total": 500
    },
    "purpose": "transactional",
    "retries": {
      "attempts": 1,
      "backoff": "linear",
      "intervalMinutes": 60,
      "on": [
        "no_answer",
        "busy"
      ]
    },
    "schedule": {
      "endsAt": "2026-09-07T14:00:00Z",
      "startsAt": "2026-09-01T04:00:00Z",
      "weekdays": 31,
      "windowEndMinute": 1260,
      "windowStartMinute": 540
    },
    "status": "running",
    "updatedAt": "2026-08-25T09:14:22Z"
  }
}
```
