Campaign Plans

Update a Campaign Plan

Updates a Campaign Plan. Send the base_revision you read. Omit a field to keep it. Send null to clear it.

Any change puts an approved plan back into draft. An approval speaks about content, and it cannot survive a change to that content. A write that changes nothing keeps the approval, and it does not move the revision.

The Line Items keep the state they hold. The revert is local to the Campaign Plan, so a validated line stays validated.

The answer is 409 with error=currency_frozen if a Line Item already has a budget, with error=revision_mismatch if the Campaign Plan changed after you read it, and with error=slug_conflict if the new name gives a slug that already exists.

patch/context/campaign-plans/{slug}

Request

  • Base URL: https://api.adcrunch.dev
  • URL: https://api.adcrunch.dev/context/campaign-plans/{slug}
  • Auth: HTTP bearer

Path parameters

slugstring required

Request body

base_revisioninteger required

The revision last read via GET — guards concurrent edits.

brand_namestring nullable

Re-point the Campaign Plan at another Brand by slug; null unlinks it. Refused with 409 error=persona_not_in_brand while any Line Item still names a Persona of the current Brand.

currencystring

ISO 4217. Refused with 409 error=currency_frozen once any Line Item carries a budget — re-denominating a costed plan would silently reinterpret every number in it.

descriptionstring
end_datestring nullable

null makes the Campaign Plan always-on — which also flips every inheriting line’s amount from a total to a daily rate.

measurementstring nullable
namestring
rationalestring nullable
slugstring

Optional new slug handle (a deliberate rename).

start_datestring nullable
total_budgetnumber nullable

null means "no declared constraint", not zero.

Example request

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

Response

The Campaign Plan as it now stands, with its Line Items. A change takes the approval away and moves the revision; the Line Items keep the state they hold.

brandIdstring nullable required

Nullable and mutable: a plan may precede its brand, cover a portfolio, or be re-pointed. Deleting a Brand leaves its plans standing.

createdAtnumber required

Milliseconds since the Unix epoch, UTC.

createdBystring required
currencystring required

Editable until the first Line Item budget, and frozen thereafter.

descriptionstring required
endDatestring nullable required

A calendar date, YYYY-MM-DD.

idstring required
measurementstring nullable required
namestring required
rationalestring nullable required
revisionnumber required

Increments on every write. Send it back as base_revision to edit; a stale one answers 409.

slugstring required
startDatestring nullable required

A calendar date, YYYY-MM-DD.

status'draft' | 'approved' required

The only two stored states. active, closed and "executed" are derived, never stored.

totalBudgetnumber nullable required
updatedAtnumber nullable required

Milliseconds since the Unix epoch, UTC.

Example response

{
  "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
}

Changes

No recorded changes to this operation across all 1 revision of this API.