> ## Documentation Index
> Fetch the complete documentation index at: https://www.adjar.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# adjar apply

`adjar apply` is the command that makes things real. It re-runs the diff computed by [`adjar plan`](/docs/cli/plan), presents you with a final confirmation prompt, and then executes each change against the ad platform's API in a safe, ordered sequence. When the API assigns new IDs to created resources, Adjar writes them back into your local TOML files automatically — keeping config and live account permanently in sync. Because every apply is a discrete, committable snapshot, rollback is as simple as `git revert`.

<Warning>
  `adjar apply` modifies your live ad account. Always review the output of `adjar plan` before running apply.
</Warning>

## Syntax

```bash theme={null}
adjar apply --config <file>
```

## Flags

<ParamField query="--config <file>" type="string" required>
  Path to the root TOML config file (e.g., `config/google.toml`). Adjar resolves all referenced subdirectory files relative to this root.
</ParamField>

<ParamField query="--credentials <path>" type="string">
  Path to the platform credentials JSON file (e.g. `google.json`). Alternatively set `ADJAR_CREDENTIALS`. See [Authentication](/docs/cli/overview#authentication).
</ParamField>

<ParamField query="--yes" type="flag">
  Skip the interactive confirmation prompt and apply immediately. Use with care in automated scripts and CI pipelines — always ensure the plan output has been reviewed before passing this flag.
</ParamField>

<ParamField query="-f, --plan-file <path>" type="string">
  Execute a previously-reviewed plan file verbatim instead of computing a fresh diff. The plan file is rejected if your config has changed since it was generated.
</ParamField>

## The apply process

`adjar apply` follows a structured sequence to ensure changes are executed safely and your config stays accurate:

<Steps>
  <Step title="Re-compute the plan">
    Adjar fetches the current live account state and diffs it against your local config, exactly as `adjar plan` does. This ensures the plan reflects reality at the moment of apply, not at the moment you last ran plan. The identical plan output is printed.
  </Step>

  <Step title="Confirm">
    Adjar prompts `Do you want to apply these changes? (yes/no):` before making any API writes. Type `yes` to proceed. Pass `--yes` to skip this prompt in automated workflows.
  </Step>

  <Step title="Validate update and archive steps (Google Ads)">
    On Google Ads, before committing anything, Adjar validates each update/archive step server-side — confirming the targeted resources still exist and can be changed. If a validation fails, apply stops before any writes happen. (OpenAI Ads has no equivalent dry-run, so applies go straight to execution.)
  </Step>

  <Step title="Execute the steps">
    Adjar applies the steps in dependency order — parents before children (campaigns before ad groups, ad groups before their keywords and ads), with archives last, leaf-first. Each step is printed with a `→` marker as it runs. If a step fails, Adjar halts and reports the error without rolling back already-completed steps.
  </Step>

  <Step title="Report completion">
    Adjar prints an `# Apply complete` summary with counts of what was created, updated, and archived. For every resource created during apply, Google Ads returns an assigned ID, which Adjar writes back into the relevant TOML files so your local config matches the live account exactly.
  </Step>
</Steps>

## Example

`adjar apply` first prints the same plan that `adjar plan` produces (the fetch progress, headline, summary, and grouped changes), then prompts for confirmation. After you answer `yes`, it validates and applies the steps. The example below is **from a Google Ads account**; OpenAI Ads applies the same way over its own resource types:

```
Do you want to apply these changes? (yes/no): yes
Validating 3 update/archive step(s) against Google before committing…
  ✓ [1/3] archive keyword "database version control" [PHRASE]
  ✓ [2/3] archive keyword "database change management" [PHRASE]
  ✓ [3/3] archive keyword "database ci/cd" [PHRASE]
Applying 14 step(s)…
  → [1/14] create campaign_negative "ispirer" [BROAD neg]
  → [2/14] create keyword "database change management" [EXACT]
  → [3/14] create keyword "database ci/cd" [EXACT]
  → [4/14] create keyword "database version control" [EXACT]
  → [5/14] create ad_group "GORM keywords"
  → [6/14] create keyword "gorm" [EXACT]
  → [7/14] create keyword "gorm migration" [EXACT]
  → [8/14] create keyword "gorm automigrate" [EXACT]
  → [9/14] create keyword "gorm auto migrate" [EXACT]
  → [10/14] create keyword "gorm migrate" [EXACT]
  → [11/14] create ad "GORM Schema Migration"
  → [12/14] archive keyword "database version control" [PHRASE]
  → [13/14] archive keyword "database change management" [PHRASE]
  → [14/14] archive keyword "database ci/cd" [PHRASE]

# Apply complete
  created: 1 ad_group, 8 keywords, 1 campaign_negative, 1 ad
  updated: —
  archived: 3 keywords
```

The full workflow, from review to commit:

```bash theme={null}
# Review first
adjar plan --config config/google.toml

# Then apply (prints the plan, then prompts for confirmation)
adjar apply --config config/google.toml

# Commit the result (Adjar writes IDs back into config)
git add config/
git commit -m "feat: expand DB Change Mgmt campaign with GORM keywords"
```

## After apply: commit your config

After a successful apply, your TOML files will have been updated with any newly assigned IDs. Commit the entire config directory to keep your repository in sync:

```bash theme={null}
git add config/
git commit -m "feat: pause high-CPA keywords in trail running campaign"
```

Skipping this commit means your next `adjar plan` will detect the ID fields as local changes, which will cause noise in future diffs.

## Rollback

Because Adjar encourages committing config after every apply, rollback is a standard Git operation. To undo the last apply:

```bash theme={null}
git revert HEAD
adjar apply --config config/google.toml
```

This reverts the config to the previous commit and applies the inverse diff to your live account.

## Apply is idempotent

Running `adjar apply` when your local config is already in sync with the live account is a safe no-op:

```
adjar apply --config config/google.toml

Fetching live Google Ads state for customer 7272244390 — 10 queries…
  ✓ campaign negatives (180)
  ✓ keywords (247)
  ✓ ad groups (17)
  ...
# google  ·  account 7272244390 (Bytebase Ads)

Plan: no changes.

Nothing to apply.
```

This makes it safe to include `adjar apply` in automated pipelines without guarding against accidental double-runs.

## Next steps

* Use [`adjar plan`](/docs/cli/plan) before every apply to review changes.
* Re-run [`adjar import`](/docs/cli/import) to reset local config to the live account state if your config and live account diverge unexpectedly.
