Import an existing campaign
The first tutorial walked through launching a new campaign. This one covers the other common starting point: you already have campaigns in Google Ads and you want to bring them under bidsmith management without rewriting them by hand.
The tool for this is bidsmith refresh.
It reads the live account and writes fmt-canonical .bid files
that describe exactly what’s there. From that point on, every change
goes through the normal plan/apply loop.
End to end: about 20 minutes for a small account.
Before you begin
The same setup as the first tutorial:
bidsmith --versionbidsmith plan --whoamiBoth should succeed. You should be cd-ed into your bidsmith-config
Git repository.
Step 1 — Make a branch
Adoption is a real change to the repo, so it goes through the normal PR flow:
git checkout -b adopt-existing-campaignsStep 2 — Pull live state into .bid files
Use the split-output mode so account-scoped things (conversion
actions, shared sets, call assets) land in account.bid and
campaigns land in campaigns.bid:
bidsmith refresh -d .After this you’ll have two new files in your repo:
account.bid— theproviderblock, conversion actions, shared sets, call assets, customer assets.campaigns.bid— campaigns, budgets, ad groups, ads, criteria.
Step 3 — Inspect what got generated
Open account.bid and campaigns.bid in your editor. Walk through
the resources and confirm they look right.
A few things to check:
- Names — bidsmith uses the Google Ads
namefield as the bidsmith local name (slugified). Make sure they’re meaningful; rename now if anything looks confusing. - Removed resources — by default
refreshdrops anything whosestatusisREMOVED. If you want them in your files for historical reasons, re-run with--include-removed. - Budgets — confirm
amount_microsmatches what the UI shows. Remember: 1 EUR = 1,000,000 micros. - Ad copy — RSAs should have your real headlines and descriptions. If something is missing, it might be a Google-side asset bidsmith doesn’t yet model — check the resource reference for what’s supported.
Step 4 — Validate locally
bidsmith validate .Should report OK. If not, something in the generated output
disagrees with the schema; the error message tells you which file
and line.
Step 5 — Run plan
This is the moment of truth:
bidsmith plan .Expected output:
Plan: 0 to create, 0 to update, 0 to destroy.No changes. Live state matches .bid files.If you see 0 to create, 0 to update, bidsmith is now in sync
with your live account. The files match reality. You haven’t
changed anything in Google Ads.
If you see some ~ update rows, that’s fine — it means a few
fields didn’t round-trip perfectly (this happens with some
server-computed defaults). Read the diff:
- If the change is innocuous (a default Google fills in that you
don’t care about), edit your
.bidfile to match what the live account shows, and re-runplanuntil it’s empty. - If the change is something you don’t want bidsmith to assert
(e.g. a
statusthat you’d rather leave to Google to manage), remove that attribute from the.bidfile.
Step 6 — Commit and open a PR
git add account.bid campaigns.bidgit commit -m "Adopt existing campaigns into bidsmith"git push -u origin adopt-existing-campaignsOpen a pull request on GitHub. The PR description should explain that this is the initial adoption — nothing in Google Ads is changing, just the repo is gaining a baseline.
Have a teammate review the PR. The diff is going to be large (every existing campaign is “new” from Git’s perspective), but the intent is small: “describe what’s already there.”
Merge when approved.
Step 7 — Verify on main
After merge, pull main and run plan once more to confirm
nothing changed in transit:
git checkout maingit pullbidsmith plan .Should still report 0 to create, 0 to update. You’re done.
What changed
Your Google Ads account is exactly the same as it was 20 minutes ago. What’s different is the repo: it now contains a faithful description of every campaign in the account.
From here, every future change — bid adjustments, new keywords,
paused campaigns, new RSAs — follows the normal flow:
edit the .bid file, open a PR, get review, merge, apply.
What if I’m worried about applying the first time?
A reasonable concern. To be extra cautious on your first real apply after adoption:
- Make a small, deliberate change (e.g. raise one budget by €1).
bidsmith plan .should show exactly one~ updaterow.- If anything else shows up, stop and investigate — you found drift that adoption didn’t capture, and you don’t want to apply blindly.
- If only the deliberate change shows up,
bidsmith apply .and verify in the UI.
This dry-run pattern is worth doing on the first apply of any new adoption.
What’s missing today
Two things on the roadmap make adoption smoother in the future:
- Reconcile-in-place mode for
refresh— re-running it against an existing repo will update fields without overwriting unrelated blocks. Gated on bidsmith’s label-tracking work. bidsmith import <address> <resource_name>— adopt a single resource into a specific bidsmith address (not the whole account). Also gated on labels.
Until those land, bootstrap mode is the canonical path. It works fine for first-time adoption.
Next
- Plan and apply — what the loop will look like from here on.
- Drift — what to do when someone edits the UI directly after adoption.
bidsmith refresh— the command reference, including the flags this tutorial skipped.