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

# Pause campaign

> Halt spend across every media buy and package on a campaign

`POST /api/v2/buyer/campaigns/:id/pause`

Halts spend across all media buys and packages on the campaign. The pause is
sent to every `ACTIVE` media buy on the campaign. The campaign transitions to
`PAUSED` only when **every** one of those media buys confirms the pause. If any
media buy does not pause, the call returns an error, the campaign keeps its
current status, and the response tells you which buys may still be delivering.

A pause never waits for seller approval. See
[pause media buy](/v2/buyer/campaigns/tasks/pause-media-buy) for what a
confirmed pause means for a single buy.

<Note>
  To resume a paused campaign, use [reactivate](/v2/buyer/campaigns/tasks/reactivate-campaign) — `execute` does not resume a `PAUSED` campaign.
</Note>

## Request

```bash theme={null}
curl -X POST https://api.apostra.com/api/v2/buyer/campaigns/cmp_987654321/pause \
  -H "Authorization: Bearer $SCOPE3_API_KEY"
```

No request body.

## Parameters

| Field | Type | Required | Notes |
| - | - | - | - |
| `id` | string | Yes | Campaign ID (path parameter). |

## Response

```json theme={null}
{
  "campaignId": "cmp_987654321",
  "campaignName": "Q2 2026 Tech Launch",
  "previousStatus": "ACTIVE",
  "newStatus": "PAUSED",
  "totalMediaBuys": 2,
  "successCount": 2,
  "failureCount": 0,
  "mediaBuyResults": [
    { "mediaBuyId": "mb_abc123", "name": "Q2 2026 Tech Launch - Example Media", "previousStatus": "ACTIVE", "success": true },
    { "mediaBuyId": "mb_def456", "name": "Q2 2026 Tech Launch - Display", "previousStatus": "ACTIVE", "success": true }
  ]
}
```

* `campaignId` — the campaign that was paused.
* `campaignName` — the campaign's display name.
* `previousStatus` / `newStatus` — campaign status before and after the call.
* `totalMediaBuys` — number of media buys the cascade attempted.
* `successCount` / `failureCount` — how many media buys paused, and how many did not. A `200` response always has `failureCount: 0`.
* `mediaBuyResults` — per-media-buy outcome. Each entry includes `mediaBuyId`, `name`, `previousStatus`, and `success`.

## When some media buys do not pause

If the seller of any media buy refuses, fails, or does not confirm the pause,
the call returns `503 SERVICE_UNAVAILABLE`:

* The media buys that confirmed the pause are `PAUSED` and stay paused.
* The media buys that did not are still `ACTIVE` and **may still be
  delivering**.
* The campaign is **not** marked `PAUSED`. It keeps its current status
  (`ACTIVE` while any of its media buys are still delivering).
* Apostra's operations team is alerted.

The error's `details` carry the same counts and per-buy results as a success
response, plus the campaign status it kept:

```json theme={null}
{
  "data": null,
  "error": {
    "code": "SERVICE_UNAVAILABLE",
    "message": "Campaign cmp_987654321 was not fully paused: 1 of 2 media buys paused, and 1 did not confirm the pause and may still be delivering.",
    "details": {
      "reason": "campaign_pause_partial",
      "campaignId": "cmp_987654321",
      "campaignStatus": "ACTIVE",
      "totalMediaBuys": 2,
      "successCount": 1,
      "failureCount": 1,
      "mediaBuyResults": [
        { "mediaBuyId": "mb_abc123", "name": "Q2 2026 Tech Launch - Example Media", "previousStatus": "ACTIVE", "success": true },
        { "mediaBuyId": "mb_def456", "name": "Q2 2026 Tech Launch - Display", "previousStatus": "ACTIVE", "success": false, "error": "The seller's ad server rejected the update." }
      ]
    }
  }
}
```

`reason` is `campaign_pause_partial` when some buys paused and
`campaign_pause_failed` when none did. Each failed entry in `mediaBuyResults`
has an `error` string with the seller's reason when one was given.

### When a seller is still applying the pause

Some sellers accept a pause and apply it later. Those buys are not paused yet,
so the call still returns `503` and the campaign stays `ACTIVE`, but no retry
is needed for them:

* Their entries in `mediaBuyResults` have `success: false` and a
  `pauseRequestedAt` timestamp.
* `details.pauseRequestedCount` counts them, and `details.pauseRequestedAt` is
  when the campaign pause was first requested.
* When they are the only buys outstanding, `reason` is
  `campaign_pause_requested`. The campaign becomes `PAUSED` on its own once
  every media buy confirms; Apostra's operations team is alerted if a seller
  has not confirmed after two hours.

If any buy was refused or failed as well, `reason` is
`campaign_pause_partial`, and those buys still need a retry or a call to their
seller.

Retrying the campaign pause is safe: it only sends the pause to media buys that
are still `ACTIVE`. To stop one buy, use
[pause media buy](/v2/buyer/campaigns/tasks/pause-media-buy). If a buy keeps
failing to pause, contact its seller to stop delivery directly.

## Errors

| Code | When |
| - | - |
| `VALIDATION_ERROR` | Campaign is not in a pausable status. |
| `NOT_FOUND` | Campaign ID does not exist for the authenticated account. |
| `SERVICE_UNAVAILABLE` | One or more media buys did not confirm the pause. The campaign keeps its status; see [When some media buys do not pause](#when-some-media-buys-do-not-pause). |

See [Errors](/v2/reference/errors) for the full error shape and recovery semantics.

## Related

<CardGroup cols={2}>
  <Card title="Reactivate campaign" href="/v2/buyer/campaigns/tasks/reactivate-campaign" icon="play">
    Resume a PAUSED campaign back to ACTIVE
  </Card>

  <Card title="Execute campaign" href="/v2/buyer/campaigns/tasks/execute-campaign" icon="rocket">
    Launch a DRAFT or COMPLETED campaign
  </Card>

  <Card title="Media buy status" href="/v2/buyer/campaigns/tasks/get-media-buy-status" icon="signal-stream">
    Poll live ADCP status
  </Card>

  <Card title="Campaign overview" href="/v2/object-guides/campaign" icon="rocket">
    The campaign object and lifecycle
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.