Plan / Apply

Preview every change before it goes live. Commit. Roll back with git.

Terminal
$ ads plan

+ campaign/brand-search                    create
+ campaign/brand-search/core-kw            create
+ campaign/brand-search/core-kw/rsa        create
~ campaign/retarget/budget                 $20 → $35/day
~ campaign/retarget/broad-match/rsa       +3 headlines
- campaign/old-spring-promo                delete

  3 to create · 2 to update · 1 to delete
  Run `ads apply` to execute.

You've been clicking through the platform UI for 40 minutes making a budget change — only to realize you applied it to the wrong campaign.

There's no preview, no audit trail, and no way to review changes before they go live. Mistakes cost money.

Roll back? Copy the settings from memory, hope you got them right.

Meanwhile the platform is drifting away from what you think it is.

How it works

Plan — see everything before it happens

Run `ads plan` to diff your TypeScript campaign definitions against live platform state. Every create, update, and delete is listed before a single API call is made.

Terminal
$ ads plan

+ campaign/brand-search                    create
+ campaign/brand-search/core-kw            create
~ campaign/retarget/budget                 $20 → $35/day
- campaign/old-spring-promo                delete

  2 to create · 1 to update · 1 to delete

Apply — execute in the right order

Mutations execute in dependency order: campaign → ad group → keyword → ad. Deletes go child-first. A failure stops execution immediately to avoid orphaned resources.

Terminal
$ ads apply

  Creating campaign/brand-search...         ✓
  Creating campaign/brand-search/core-kw... ✓
  Updating campaign/retarget/budget...      ✓  $20 → $35
  Deleting campaign/old-spring-promo...     ✓

  Applied 4 changes in 1.8s.

Pull — detect drift

Someone changed a bid on the platform UI. `ads pull` detects the drift between your TypeScript definitions and live state so you can decide whether to re-apply or update your source.

Terminal
$ ads pull

~ campaign/brand-search/budget    $40/day → $55/day  (platform ahead)
~ campaign/retarget/rsa           final_url changed   (platform ahead)

  2 resources drifted. Run `ads plan` to re-apply.

Capabilities

Preview before apply

Full diff of creates, updates, and deletes before any API call is made.

Dependency-ordered execution

Campaigns before ad groups before keywords before ads. Deletes are reversed.

Atomic rollback

Failures stop execution immediately. Revert with git and re-apply.

Drift detection

Pull live state and see what diverged from your source definitions.

Operation history

Every apply is logged to a local SQLite cache with timestamps and diffs.

Dry run mode

`ads plan` never writes. Use it in CI to validate before merging.