---
title: campaign_plan_update
description: 'Edit a campaign plan. Any real change returns an approved plan to draft.'
---

Updates a **Campaign Plan**'s own fields. Its Line Items are edited with [`line_item_update`](/mcp/tools/line-item-update).

:::warning[A Campaign Plan is not a provider campaign]

It is AdCrunch's own planning document — written before anything is bought, and possibly executed into several campaigns, or none. For campaigns that exist on Meta or Google, use [`list_entities`](/mcp/tools/list-entities) and [`get_entity`](/mcp/tools/get-entity).

:::

## Input

Omit a field to leave it alone; send `null` to clear it. The two are deliberately different — "I only moved the end date" must not erase the rationale.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `campaign_plan_name` | `string` | yes | The plan slug. |
| `base_revision` | `integer` | yes | The revision you last read via `campaign_plan_get`. |
| `name`, `description` | `string` | no |  |
| `slug` | `string` | no | A new handle — a deliberate rename. |
| `brand_name` | `string \| null` | no | Re-point the plan; `null` unlinks it. |
| `currency` | `string` | no | Refused once any Line Item carries a budget. |
| `total_budget` | `integer \| null` | no | `null` means "no declared constraint", not zero. |
| `start_date` / `end_date` | `YYYY-MM-DD \| null` | no |  |
| `rationale`, `measurement` | `string \| null` | no |  |

:::warning[Editing cancels an approval]

An approval says somebody agreed to _particular content_. Change that content and the plan returns to `draft`, so the label never outlives what it referred to. A write that changes nothing leaves the approval standing.

:::

:::info[The currency freezes at the first budget]

Re-denominating a costed plan would silently reinterpret every number in it — `40000` going from €400 to $400 without a figure moving on screen. Nothing is ever converted: a converted budget is a different plan.

:::

:::info[Re-pointing the brand can be refused]

If a Line Item still names a persona of the current brand, the change is refused and names those lines. Clear their personas first — they are not cleared for you, because only you know which reading you meant.

:::

Requires the `campaign_plan:write` scope.
