Skip to content

bidsmith apply

apply is the mutator. It runs the same diff as plan, shows it to you, prompts for confirmation, and only then sends the changes to Google Ads.

It’s idempotent: applying twice in a row does nothing the second time. It’s atomic: either every operation commits, or none of them do (modulo Google’s own consistency guarantees).

Synopsis

Terminal window
bidsmith apply [PATH] [--auto-approve] [--refresh-state] [--verbose]

Arguments

ArgumentDefaultDescription
PATH.File or directory containing .bid files.

Flags

FlagDescription
--auto-approveSkip the interactive yes prompt. Required when stdin is not a TTY (CI, cron, scripts).
--refresh-stateIgnore any cached live state and refetch from the API before computing the diff. The cache is dropped as the mutate is sent regardless — including when the run is interrupted or the response is lost. See Cut Google Ads API quota usage.
--verbosePrint the outgoing API request envelope and the raw response.

Environment variables

Same as bidsmith plan. See Authentication for the full list.

Exit codes

CodeMeaning
0Apply completed (whether or not anything changed).
1Local validation failed, authentication failed, Google rejected an operation, the user declined the prompt, or any other error.

Examples

Interactive apply

Terminal window
bidsmith apply .

Prints the plan, prompts:

Do you want to perform these actions?
Type 'yes' to confirm.
>

Type yes and press Enter to commit. Anything else aborts (the account is not touched).

Apply from a script or CI

Terminal window
bidsmith apply --auto-approve .

Skips the prompt. Required for non-interactive runs — apply refuses to read yes from a non-TTY stdin, so omitting --auto-approve in CI is a hard error rather than a silent auto-confirm.

Debug an apply that’s misbehaving

Terminal window
bidsmith apply . --verbose

Same as plan --verbose plus the real mutate.

What the prompt does

The prompt is bidsmith’s last line of defense between you and a bad change. It blocks until you type the literal three letters yes followed by Enter. Anything else aborts with no changes.

This is intentional: a wrong key (y, Yes, accidental Enter) should not auto-commit. The prompt is meant to make you re-read the plan before agreeing.

Removing keywords

When you delete a negative_keyword (or keyword) block from a resource that still exists, apply now removes that keyword from Google Ads — it shows up as a - destroy row in the plan and is approved by the same yes prompt as every other change. This makes cleanup safe: trim a few negatives, or move a whole ad-group negative list into a shared set, and the old entries are actually removed instead of silently lingering.

The removal is scoped to what you already manage. If your file lists negative keywords for an ad group, that negative list is treated as the complete set — but positive keywords you manage elsewhere (or in the Google Ads UI) are left untouched, and vice versa.

Removing a whole campaign

Deleting a campaign, ad group, or ad block from a .bid file removes it from Google Ads. bidsmith tags everything it creates or adopts with a bidsmith:address=… label, so it can tell a campaign it manages from one somebody made in the Google Ads UI — the labeled one is destroyed when nothing declares it, and the unlabeled one is never touched.

When a change is too big for one request

Everything in an apply goes to Google as a single atomic request, and Google puts a deadline on how long it will spend on one. A first apply that creates a whole account — several campaigns, their ad groups, and a thousand-odd keywords and ads — can run past it:

apply: Google did not finish this batch in time — 1300 operation(s) went
out as one atomic request, so nothing was written and nothing needs
undoing. …

Nothing was written: that is what atomic means, and it is why there is nothing to clean up before trying again. Re-running sometimes gets through. What reliably works is applying one file at a time — a run pointed at a single file only touches that file’s resources, so a per-campaign layout gives you natural batches:

Terminal window
for f in campaigns/*.bid; do bidsmith apply --auto-approve "$f"; done

Then go back to bidsmith apply . for everyday changes, which is also what makes removals work.

See also