---
title: Plan a campaign
description: Ask your agent to write down what you intend to run, approve it, build it on Meta, and record what it created.
---

A **Campaign Plan** is what you intend to run, before you buy anything: the channels, the money, the audience and the dates. You ask your agent to write it. A person approves it. Then the agent can build it on Meta and record each object that it creates. This page walks the job from the first prompt to the last record.

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

A Campaign Plan is a planning document of AdCrunch. One Campaign Plan can become many campaigns on Meta, or none. For the campaigns that run on Meta or Google now, ask for [`list_entities`](/mcp/tools/list-entities) and [`get_entity`](/mcp/tools/get-entity).

:::

## Before you start

- **Scopes.** The token of your client must hold `campaign_plan:read` to read Campaign Plans and `campaign_plan:write` to write and approve them. To build on Meta, it must also hold `mutation:write`. [Auth & scopes](/mcp/auth) explains each scope.
- **A connected ad account.** To build a Line Item, your organization must have a connected Meta ad account. Today, AdCrunch builds on Meta only. [What each provider supports](/connect/providers) tells where each other channel stops.

## Write the Campaign Plan

> "Create a Campaign Plan for the Acme spring sale: €5,000 in euros, from 1 March to 31 May 2026. Meta carries the reach."

The agent calls [`campaign_plan_create`](/mcp/tools/campaign-plan-create). Its page tells what the agent must send and what can come later. The new Campaign Plan is a `draft`. You see its name, its slug and its figures.

:::warning[Amounts are in whole units]

Each amount is in whole units of the currency of the Campaign Plan: `40.5` is €40.50, and `4050` is €4,050.00. AdCrunch refuses an amount that has more decimals than the currency has. It does not round it.

:::

## Add the Line Items

> "Add a Line Item to the spring sale Campaign Plan: Meta, for sales, €2,500, in France and Belgium, ages 25 to 44, through our Meta ad account."

The agent calls [`line_item_create`](/mcp/tools/line-item-create) once for each thing that you buy. Its page tells what the agent must send. You see the new Line Item, and two facts that AdCrunch calculates for it:

- **Can AdCrunch build it today?** You can plan ten channels, from Meta and TikTok to LinkedIn and programmatic display. Today, AdCrunch builds a Line Item on Meta only. A Line Item on another channel stays in the Campaign Plan and adds to its money, but the agent cannot build it.
- **Is its budget a total or a daily rate?** A Line Item with no dates of its own uses the dates of the Campaign Plan. When the Line Item has an end date, its budget is a total for the period. When it has no end date, its budget is a rate for each day.

A persona explains the audience to the people who read the Campaign Plan. The countries, the ages and the gender are what execute. A Line Item can name only a persona of the brand of its Campaign Plan.

A new Line Item starts as a `draft`. When you add a Line Item to an approved Campaign Plan, the Campaign Plan goes back to `draft`.

## Read the Campaign Plan back

> "Show me the spring sale Campaign Plan. How much of the envelope is still free?"

The agent calls [`campaign_plan_get`](/mcp/tools/campaign-plan-get). It gets each Line Item in full, with what each Line Item created. To find a Campaign Plan first, the agent calls [`campaign_plan_list`](/mcp/tools/campaign-plan-list), which gives the figures of each Campaign Plan, newest first.

You see three money figures. They answer three different questions:

| Figure | What it tells you |
| --- | --- |
| The envelope | The money that you have. No envelope means no declared limit. It does not mean zero. |
| The allocated sum | The sum of the Line Item budgets. |
| What is left | The envelope less the allocated sum. It can be negative: AdCrunch shows an over-allocation and does not block it. When the Line Items hold daily rates, AdCrunch does not calculate it, because a total less a rate is not a quantity. |

:::info[Some Campaign Plans have no sum]

When some Line Items hold totals and others hold daily rates, no sum of them exists. Then the agent tells you that the figures are "not comparable". It does not add them.

:::

## Change the Campaign Plan

> "Move the end of the spring sale Campaign Plan to 30 June, and raise the envelope to €7,500."

The agent reads the Campaign Plan, then calls [`campaign_plan_update`](/mcp/tools/campaign-plan-update) with the fields that change. For a Line Item, it calls [`line_item_update`](/mcp/tools/line-item-update) or [`line_item_delete`](/mcp/tools/line-item-delete). To remove the whole Campaign Plan and its Line Items, it calls [`campaign_plan_delete`](/mcp/tools/campaign-plan-delete). These guardrails apply:

- **An edit cannot overwrite an edit.** The Campaign Plan has a revision, and each Line Item has a revision of its own. `campaign_plan_update`, `campaign_plan_delete` and `campaign_plan_approve` send the revision of the Campaign Plan that the agent read. `line_item_update`, `line_item_delete` and `line_item_validate` send the revision of the Line Item that the agent read. When the Campaign Plan or the Line Item changed after the agent read it, AdCrunch refuses the write with `revision_mismatch`. The agent reads again, checks that the two changes agree, and tries again.
- **A change cancels the approval of what it changes.** A real change to an approved Campaign Plan returns it to `draft`. So does a Line Item that is added or deleted. A real change to a validated Line Item returns that Line Item to `draft`, and the approval of the Campaign Plan stays. A write that changes nothing cancels nothing.
- **The currency freezes at the first budget.** When a Line Item has a budget, AdCrunch refuses a change of currency. AdCrunch never converts an amount.
- **Nothing live changes.** An edit or a delete changes the Campaign Plan only. A campaign that a Line Item created stays on Meta as it is.

## Approve

> "Approve the spring sale Campaign Plan."

The agent calls [`campaign_plan_approve`](/mcp/tools/campaign-plan-approve) with the revision that it read. The approval is of that content. It also validates each draft Line Item of the Campaign Plan, and you see how many Line Items it validated.

When only one Line Item is ready, ask for that Line Item alone:

> "The Meta Line Item of the spring sale Campaign Plan is ready. Validate only that Line Item."

The agent calls [`line_item_validate`](/mcp/tools/line-item-validate). Your approval then does not reach a Line Item that another person still writes.

:::info[An approval spends nothing]

An approval creates nothing on Meta, and it spends nothing. It does not block on an incomplete or over-allocated Campaign Plan: the person who approves decides. An approval changes the revision of the Campaign Plan and of each Line Item that it validates, so the agent reads the Campaign Plan again before its next write.

:::

## Build it on Meta

> "Build the Meta Line Item of the spring sale Campaign Plan."

The agent reads the Campaign Plan, and then builds the Line Item with the Meta tools, such as [`meta_create_campaign`](/mcp/tools/meta-create-campaign) and [`meta_create_adset`](/mcp/tools/meta-create-adset). Each create arrives paused, so nothing spends until you activate it. AdCrunch queues each create, and the agent follows it with [`get_mutation_status`](/mcp/tools/get-mutation-status). When the change completes, that tool gives the id of the new object.

The Meta tools do not read your Campaign Plan. So the agent checks that the Line Item is ready before it builds. A Line Item is ready when each of these is true:

- The Line Item is `validated`.
- AdCrunch can build its channel today.
- The Line Item names an ad account that your organization connected, on the provider of its channel.
- AdCrunch knows the currency of that ad account. When the currency is unknown, AdCrunch refuses the Line Item: reconnect the provider to refresh the currency.
- The currency of the ad account is the currency of the Campaign Plan. AdCrunch never converts: a €2,500 budget sent to a USD account becomes $2,500.
- The Line Item has a start date, an end date, or both, of its own or from the Campaign Plan. When it has both, the start is on or before the end.

The budget then goes to Meta in the unit of the Line Item: a total as a lifetime budget, a daily rate as a daily budget.

## Record what the agent created

When a create completes, the agent calls [`line_item_record_execution`](/mcp/tools/line-item-record-execution) with the id that `get_mutation_status` gave for the new object. Then the Line Item shows what it created, and you can see which campaigns came from which Line Item.

:::warning[Nothing records this for you]

One Line Item can create many objects, and only the agent knows which object came from which Line Item. A Line Item that created a campaign but has no record looks unbuilt while it can already spend. Ask the agent to record each object after each create.

:::

A second record of the same object adds nothing. Nobody declares how many objects a Line Item must create, so the agent reports "3 objects created", and never "complete".

To stop what a Line Item created, ask the agent to pause or archive it with [`meta_set_status`](/mcp/tools/meta-set-status). A delete of the Line Item or of the Campaign Plan does not stop it.

## When a call fails

A failed call carries a code and a sentence. The sentence tells the agent what to do next: for example, to read the Campaign Plan again after `revision_mismatch`. [Errors](/mcp/errors) describes the shape of a failed call. Each tool page lists the codes of its tool.
