Skip to content
AdCrunch
Esc
↑↓navigate↵open⌘Jpreview
On this page

campaign_plan_update

Edit a Campaign Plan. A real change returns an approved Campaign Plan to draft.

Ask the agent to change the fields of a Campaign Plan: its name, its brand, its envelope, its dates, its rationale or its measurement. The agent sends only what changes.

“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 with the revision of the Campaign Plan that it read. You see the Campaign Plan as it is now. When the Campaign Plan was approved, a real change returns it to draft. When another change came first, AdCrunch refuses the write, and the agent reads the Campaign Plan again. The currency cannot change after a Line Item has a budget. To change a Line Item, the agent calls line_item_update.

Plan a campaign walks the whole job.

Reference

Update a Campaign Plan. Omit a field to leave it alone; send null to clear it. Pass base_revision from campaign_plan_get. Any real change returns an approved plan to draft — an approval refers to particular content and cannot outlive it; a write that changes nothing leaves the approval standing. The currency is refused once any Line Item carries a budget, because re-denominating a costed plan would silently reinterpret every number in it. A Campaign Plan is AdCrunch’s own planning document — it is not a campaign on Meta or Google. For those, use list_entities and get_entity.

Input

Argument Type Required Description
base_revision integer yes The revision you last read via campaign_plan_get. Guards against writing over a change somebody else made since.
brand_name string or null no Re-point the plan at another brand by slug; null unlinks it. Refused while a Line Item still names a persona of the current brand.
campaign_plan_name string yes The Campaign Plan slug — its stable per-organization handle.
currency string, 3 characters no ISO 4217. Refused once any Line Item carries a budget — nothing is ever converted.
description string no
end_date string or null no null makes the plan always-on, which also flips every inheriting line from a total to a daily rate.
measurement string or null no
name string no
rationale string or null no
slug string no A new slug handle — a deliberate rename.
start_date string or null no
total_budget number, at least 0 or null no null means “no declared constraint”, not zero.

Output

A successful call returns this object in structuredContent.

Field Type Always present Description
campaignPlan object yes The Campaign Plan as it is now, with its Line Items in full.
campaignPlan.allocation object yes The money of the Campaign Plan. AdCrunch calculates it on each read and does not store it.
campaignPlan.allocation.allocated number or null yes The sum of the Line Item budgets, in whole units of the currency. null when the Line Items with a budget do not share a unit.
campaignPlan.allocation.comparable boolean yes false when the Line Items with a budget mix totals and daily rates. Then no sum exists: say “not comparable”, and do not add the budgets.
campaignPlan.allocation.unallocated number or null yes The envelope less the allocated sum. It can be negative. null when the envelope is not set, when the Line Items do not share a unit, or when the unit is daily.
campaignPlan.allocation.unit one of total, daily or null yes The unit that the Line Items with a budget share. null when no Line Item has a budget, or when the Line Items do not share a unit.
campaignPlan.brandId string or null yes The Brand that the Campaign Plan is for, brd_…, or null.
campaignPlan.createdAt number yes Milliseconds since the Unix epoch, UTC.
campaignPlan.createdBy string yes The user who created the Campaign Plan, usr_….
campaignPlan.currency string yes ISO 4217. Each amount of the Campaign Plan and of its Line Items is in whole units of this currency. It cannot change after a Line Item has a budget.
campaignPlan.description string yes One sentence that tells the Campaign Plan apart in a list.
campaignPlan.endDate string or null yes The last day of the Campaign Plan, or null. With no end date, the Campaign Plan is always on, and the budget of a Line Item with no end date of its own is a daily rate.
campaignPlan.id string yes The id of the Campaign Plan, cpl_….
campaignPlan.lineItems array of object yes Each Line Item of the Campaign Plan, in full.
campaignPlan.lineItems[].advertiserId string or null yes The ad account that the Line Item runs through, acc_…, or null.
campaignPlan.lineItems[].ageMax number or null yes The highest age, or null for no upper bound.
campaignPlan.lineItems[].ageMin number or null yes The lowest age, or null for no lower bound.
campaignPlan.lineItems[].budget number or null yes The amount in whole units of the currency of the Campaign Plan, or null when it is not set. unit tells how to read it.
campaignPlan.lineItems[].campaignPlanId string yes The id of the Campaign Plan that holds the Line Item, cpl_….
campaignPlan.lineItems[].channel one of meta, tiktok, snapchat, google_search, google_pmax, google_display, youtube, programmatic_display, linkedin, x yes What the Line Item buys, in planning words. A channel is not a provider.
campaignPlan.lineItems[].countries array of string yes ISO 3166-1 alpha-2 codes. An empty list means that the geography is not decided.
campaignPlan.lineItems[].createdAt number yes Milliseconds since the Unix epoch, UTC.
campaignPlan.lineItems[].createdBy string yes The user who added the Line Item, usr_….
campaignPlan.lineItems[].effectiveEndDate string or null yes The end that applies: the end date of the Line Item, else the end date of the Campaign Plan. null when neither has one.
campaignPlan.lineItems[].effectiveStartDate string or null yes The start that applies: the start date of the Line Item, else the start date of the Campaign Plan. null when neither has one.
campaignPlan.lineItems[].endDate string or null yes The end date of the Line Item itself, or null when the Line Item uses the end date of the Campaign Plan.
campaignPlan.lineItems[].executable boolean yes true when AdCrunch can create objects for this channel today. It is not a promise that a create succeeds.
campaignPlan.lineItems[].executions array of object yes The provider objects that the Line Item created, as line_item_record_execution recorded them. The list does not tell whether the Line Item is complete.
campaignPlan.lineItems[].executions[].advertiserId string yes The ad account that holds the object, acc_….
campaignPlan.lineItems[].executions[].createdAt number yes When AdCrunch recorded the object, in milliseconds since the Unix epoch, UTC.
campaignPlan.lineItems[].executions[].entityId string yes The id of the object on the provider, with no prefix. get_entity and list_entities use the same id.
campaignPlan.lineItems[].executions[].entityType string yes The word of the provider for the level of the object, such as campaign, adset or ad.
campaignPlan.lineItems[].executions[].id string yes The id of the record, exe_….
campaignPlan.lineItems[].executions[].mutationWorkflowId string or null yes The workflowId of the change that created the object, or null when the record names none.
campaignPlan.lineItems[].executions[].provider one of meta, gads, tiktok, x, openai, snapchat, dv360 yes The provider of the object.
campaignPlan.lineItems[].gender one of all, men, women or null yes The gender of the audience, or null when it is not decided. null executes as all.
campaignPlan.lineItems[].id string yes The id of the Line Item, lni_….
campaignPlan.lineItems[].objective one of awareness, engagement, leads, sales, traffic, app_promotion yes What the Line Item is for.
campaignPlan.lineItems[].personaId string or null yes The Persona that explains the audience, psn_…, or null. The countries, the ages and the gender are what execute.
campaignPlan.lineItems[].provider one of meta, gads, tiktok, x, openai, snapchat, dv360 or null yes The provider that sells the channel, or null when AdCrunch has no integration for it.
campaignPlan.lineItems[].revision number yes The revision of the Line Item. It increments when the Line Item changes. Send it as base_revision to line_item_update, line_item_delete or line_item_validate.
campaignPlan.lineItems[].startDate string or null yes The start date of the Line Item itself, or null when the Line Item uses the start date of the Campaign Plan.
campaignPlan.lineItems[].status one of draft, validated yes validated when a person cleared the Line Item to run, by line_item_validate or by the approval of the Campaign Plan. A real change to the Line Item returns it to draft.
campaignPlan.lineItems[].unit one of total, daily yes How to read budget. total when the Line Item has an effective end date: the budget is for the whole period. daily when it has none: the budget is for each day.
campaignPlan.lineItems[].updatedAt number or null yes When the Line Item last changed, or null when it never changed.
campaignPlan.measurement string or null yes How the result is judged, or null.
campaignPlan.name string yes The display name.
campaignPlan.rationale string or null yes The argument for the split of the money, or null. A reviewer approves it.
campaignPlan.revision number yes The revision of the Campaign Plan. It increments when the Campaign Plan changes. Send it as base_revision to campaign_plan_update, campaign_plan_delete or campaign_plan_approve. A Line Item has a revision of its own.
campaignPlan.slug string yes The slug of the Campaign Plan. Each tool takes it as campaign_plan_name.
campaignPlan.startDate string or null yes The first day of the Campaign Plan, or null.
campaignPlan.status one of draft, approved yes approved when a person approved the content at this revision. A real change to the Campaign Plan, or a Line Item that is added or deleted, returns it to draft.
campaignPlan.totalBudget number or null yes The envelope: the money that you have, in whole units of currency. null means no declared limit, not zero.
campaignPlan.updatedAt number or null yes When the Campaign Plan last changed, or null when it never changed.

Failure codes

A failed call has isError set, and structuredContent.error holds one of these codes. Errors describes the shape of a failed call.

  • not_found
  • invalid_slug
  • invalid_currency
  • invalid_amount
  • invalid_window
  • persona_not_in_brand
  • currency_frozen
  • revision_mismatch
  • slug_conflict
  • forbidden
  • invalid_request
  • internal_error

Scope

The token must hold campaign_plan:write. Auth & scopes lists each scope.

Annotations

A client reads these hints. A hint that the tool does not declare has the default value of the MCP specification.

  • Writes. The tool can change data.
  • Destructive. The tool can make a change that you cannot undo. A client can ask you to confirm before it calls the tool.
  • Not idempotent. A second call with the same arguments can change more.
  • Closed world. The tool reads and writes the data of AdCrunch only.

Example

The arguments:

{
  "base_revision": 3,
  "campaign_plan_name": "spring-sale",
  "end_date": "2026-06-30",
  "total_budget": 7500
}

The result, in structuredContent:

{
  "campaignPlan": {
    "allocation": {
      "allocated": 2500,
      "comparable": true,
      "unallocated": 5000,
      "unit": "total"
    },
    "brandId": "brd_6a9c33",
    "createdAt": 1768435200000,
    "createdBy": "usr_5d2b71",
    "currency": "EUR",
    "description": "The spring sale of Acme, on Meta, in France and Belgium.",
    "endDate": "2026-06-30",
    "id": "cpl_4e1a08",
    "lineItems": [
      {
        "advertiserId": "acc_1203456789012345",
        "ageMax": 44,
        "ageMin": 25,
        "budget": 2500,
        "campaignPlanId": "cpl_4e1a08",
        "channel": "meta",
        "countries": [
          "FR",
          "BE"
        ],
        "createdAt": 1768435200000,
        "createdBy": "usr_5d2b71",
        "effectiveEndDate": "2026-06-30",
        "effectiveStartDate": "2026-03-01",
        "endDate": null,
        "executable": true,
        "executions": [
          {
            "advertiserId": "acc_1203456789012345",
            "createdAt": 1772409600000,
            "entityId": "120210000000000",
            "entityType": "campaign",
            "id": "exe_7a4c12",
            "mutationWorkflowId": "b3d1f0c4-6a2e-4a1f-9f77-2c0d1e5a8b94",
            "provider": "meta"
          }
        ],
        "gender": "all",
        "id": "lni_2d9e77",
        "objective": "sales",
        "personaId": "psn_8c4a20",
        "provider": "meta",
        "revision": 2,
        "startDate": null,
        "status": "validated",
        "unit": "total",
        "updatedAt": 1769040000000
      }
    ],
    "measurement": "Revenue in the window, against the spring of 2025.",
    "name": "Spring Sale 2026",
    "rationale": "Meta carries the reach. One Line Item keeps the budget in one place.",
    "revision": 4,
    "slug": "spring-sale",
    "startDate": "2026-03-01",
    "status": "draft",
    "totalBudget": 7500,
    "updatedAt": 1769644800000
  }
}

Was this page helpful?