---
title: "Apply Plan"
method: POST
path: "/plans/{plan_id}/apply"
---

# Apply Plan

`POST /plans/{plan_id}/apply`

Apply the accepted subset of a persisted plan and record outcomes.

The plan body itself is loaded from `plan.payload` — the FE no
longer ships it in the request. The endpoint is single-shot per
plan: a non-ACTIVE plan returns 409, so the caller can't double-apply
even if the FE's button-disable logic misfires.

## Path parameters

- `plan_id` integer, required

## Headers

- `Authorization` string, nullable
- `X-User-Id` string, nullable
- `X-Posthog-Session-Id` string

## Cookies

- `session_id` string, nullable

## Request body

- ApplyPlanRequest — User's per-suggestion verdict. `accepted` drives the apply loop; `rejected`, `follow_up`, and `skipped` are persisted alongside as the audit trail and to distinguish "user said no" (with an optional reason), "user asked a question instead of deciding", and "user didn't act on it". `rejected`/`follow_up` carry the user's note. Applying with an empty `accepted` (only rejections/follow-ups) pushes nothing and cancels the plan — the user gave feedback without taking any change live. `overrides` carries any values the operator edited in the review UI before applying — numeric targets or a duplicate ad's status/rename settings — each addressing a change inside an *accepted* suggestion. They're baked into the payload that's pushed to the ad platform, recorded on `plan_change_applications`, and echoed to the agent.
  - `accepted` string[]
  - `rejected` SuggestionFeedback[]
    - `suggestion_id` string, required
    - `feedback` string, nullable
  - `follow_up` SuggestionFeedback[]
    - `suggestion_id` string, required
    - `feedback` string, nullable
  - `skipped` string[]
  - `overrides` union[]
    - union
      - AddressedMonetaryOverride
        - `suggestion_id` string, required
        - `change_index` integer, required
        - `field` 'daily_budget' | 'lifetime_budget' | 'daily_spend_cap' | 'lifetime_spend_cap' | 'bid_amount', required
        - `to_cents` integer, required
      - AddressedRoasOverride
        - `suggestion_id` string, required
        - `change_index` integer, required
        - `field` 'roas_average_floor', required
        - `to_roas` number, required
      - AddressedDuplicateAdOverride
        - `suggestion_id` string, required
        - `change_index` integer, required
        - `status_option` 'ACTIVE' | 'PAUSED' | 'INHERITED_FROM_SOURCE', required
        - `rename_prefix` string, nullable
        - `rename_suffix` string, nullable
        - `field` 'duplicate_ad', required
      - AddressedDuplicateAdsetOverride
        - `suggestion_id` string, required
        - `change_index` integer, required
        - `status_option` 'ACTIVE' | 'PAUSED' | 'INHERITED_FROM_SOURCE', required
        - `rename_prefix` string, nullable
        - `rename_suffix` string, nullable
        - `field` 'duplicate_adset', required
      - AddressedDuplicateCampaignOverride
        - `suggestion_id` string, required
        - `change_index` integer, required
        - `status_option` 'ACTIVE' | 'PAUSED' | 'INHERITED_FROM_SOURCE', required
        - `rename_prefix` string, nullable
        - `rename_suffix` string, nullable
        - `field` 'duplicate_campaign', required

## Response `200`

Successful Response

- ApplyPlanResponse
  - `outcomes` SuggestionOutcome[], required
    - `suggestion_id` string, required
    - `success` boolean, required
    - `error` string, nullable
    - `per_change` ChangeApplicationOutcome[]
      - `change_index` integer, required
      - `platform_object_id` string, required
      - `field` string, required
      - `integration_id` integer, nullable
      - `outcome` 'applied' | 'failed' | 'aborted' | 'skipped', required — What became of a single `Change` in an accepted suggestion.
      - `error` string, nullable
      - `created_platform_object_id` string, nullable
  - `status` 'active' | 'applied' | 'partially_applied' | 'superseded' | 'canceled', required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/runconverge/apis/fastapi.md) · [All operations](https://skmtc.dev/runconverge/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/runconverge/fastapi/revisions/1452e350bd1d/schema)
