Plan a campaign
Write down what you intend to run — channels, budgets, targeting, dates — as a structured Campaign Plan your agent can sum, approve, execute and record against.
On this page
The read tools tell an agent what is running. The campaign_plan_* and line_item_* tools let it write down what you intend to run — before anything is bought — in a form that adds up, that a human can approve, and that the mutation tools can then build from.
This is the document that usually lives in a spreadsheet: €120,000 across four channels and six markets, ten weeks, with an argument for the split. Here it is data, so nothing has to be retyped into an ad account by hand.
Warning
A Campaign Plan is not a provider campaign
It is AdCrunch’s own planning document, and one Campaign Plan may become
several provider campaigns, or none at all. For campaigns that already exist
on Meta or Google, use list_entities and
get_entity.
Three ideas
- A Campaign Plan is what your organization intends to run: an envelope, a currency, a window, optionally a brand, plus the
rationalefor the split and howmeasurementwill judge it. It belongs to your organization, is authored incrementally, and is approved by a person. - A Line Item is one row of that intent — a channel, an objective, an audience, an amount, a window. It holds only what stays constant across everything it spawns, which is why it carries no optimization goal and no campaign-tree shape.
- An execution record is one row per provider object a Line Item created. It is written by the agent that did the creating, and it is what later answers “which of these campaigns came from row 3?”
The workflow
Create the Campaign Plan
campaign_plan_createneeds a name, a one-line description and a currency. Everything else — the envelope, the window, the brand — can arrive later, because every amount written afterwards is read through that currency.Add the Line Items
One
line_item_createper intent: channel, objective, and whatever ofbudget,countries,age_min/age_max,genderand dates you have decided. A line with no dates inherits the Campaign Plan’s.Read it back
campaign_plan_getreturns the Line Items in full — there is noline_item_get— along with the money figures and four facts derived per line:provider,executable, the effective window, andunit. Read these back rather than assuming them.Approve, or validate one line
campaign_plan_approveis the human act: it approves the Campaign Plan and validates every draft line on it. When only one row is ready, useline_item_validateso your approval does not reach somebody else’s half-written row.Execute with the mutation tools
Creating the campaigns and ad sets is the ordinary write path —
meta_create_campaign,meta_create_adset— against theadvertiser_idon the line, and it needs themutation:writescope.Record what you created
After each create, call
line_item_record_executionwith the native id. Nothing does this for you: one line may create any number of objects and you chose the shape, so only you know which came from where.
Three money figures, not one
campaign_plan_get returns an allocation block. The numbers in it answer different questions and are allowed to disagree.
| Figure | What it is |
|---|---|
totalBudget |
The envelope — what you have. null means no declared constraint, never zero. |
allocated |
The sum of the Line Item budgets. |
unallocated |
The envelope minus the allocated sum — what is still unplaced. |
comparable |
Whether that sum means anything at all. |
Warning
Amounts are integer minor units
Send 4050 for €40.50, never 40.50. A fractional amount is refused rather
than rounded — rounding would silently turn €40.50 into 40 cents. The currency
lives on the Campaign Plan; a Line Item carries an amount only.
Note
A mixed-unit plan has no sum
The unit is derived: a line with an effective end date holds a total for
that period, one without holds a daily rate. Mix the two and comparable
comes back false with unallocated: null — an envelope minus a rate is not
a quantity. Say so rather than printing a total that looks right and is not.
Statuses you’ll see
| On | Value | Meaning |
|---|---|---|
| Campaign Plan | draft |
Being authored. Editable, and not approved by anyone. |
| Campaign Plan | approved |
A person signed off on the content at a specific revision. |
| Line Item | draft |
Not cleared to run. |
| Line Item | validated |
Cleared to run — by its own validation, or by the approval that cascaded over it. |
Tip
Editing reverts, and only locally
Edit a Line Item and that line returns to draft. Edit the Campaign Plan’s
own fields, or add a line, and the Campaign Plan returns to draft. What has
already been created on a provider is untouched — reverting a line changes
your plan, never your delivery.
Before you execute
Approval is a gate on the plan, not a lock on the ad account: the Meta tools know nothing about your Campaign Plan and will happily create from a row nobody validated. Check these yourself, from the campaign_plan_get response, before you create anything:
- The line is
validated. This is the gate; walking through it is your job. executableistrue. A channel nobody has connected yet still plans, sums and approves — it simply cannot be built.- The
advertiser_idis set, owned by your organization, and on the line’sprovider. - The account currency equals the Campaign Plan’s. AdCrunch never converts — Meta reads
daily_budgetin the account’s currency, so a EUR plan built into a USD account creates the same number in dollars. A converted budget is a different plan. - The window resolves, after inheritance, and starts before it ends.
- Send the budget in the unit the line says.
totalis a lifetime budget;dailyis a rate.
Warning
A line that ran but was never recorded looks unrun
It is already spending while the plan says nothing came of it. Record each object as you create it, and report “3 objects created” rather than “complete” — how many objects a line should produce was never declared, so completeness is not knowable.
Scopes
Authoring needs campaign_plan:read and campaign_plan:write; recording an execution is a write on the plan, so it needs campaign_plan:write too. Actually creating campaigns needs mutation:write, granted separately.
That separation is the point: an agent can plan an entire quarter — restructure it, re-budget it, approve nothing — without being able to move a cent. See Auth & scopes.
Channels and providers
Ten channels can be planned: meta, tiktok, snapchat, google_search, google_pmax, google_display, youtube, programmatic_display, linkedin and x. Your media plan already spans them, and a planning surface that covered one would be a planning surface you kept a spreadsheet beside.
Execution is a different question, and a narrower one: executable is true for Meta today. It is derived per request from what AdCrunch can write to, never stored — as more providers come online, the same rows become executable with nothing to migrate.