Skip to content

The .bid file

A .bid file is plain text that describes what your Google Ads account should look like. It’s the source of truth bidsmith reads when you run plan and apply.

The file format is HCL — the same configuration language Terraform uses. If you’ve never seen HCL before, it’ll look familiar within an hour: blocks with curly braces, attributes inside them, and references between blocks.

Anatomy

Every .bid file is built from two kinds of blocks:

provider "google_ads" {
customer_id = "1234567890"
}
resource "google_ads_campaign_budget" "summer" {
name = "Summer 2026"
amount_micros = 50000000
delivery_method = "STANDARD"
}

The provider block says which account these files manage. You declare it exactly once per project. See provider "google_ads" for the attributes it accepts.

resource blocks declare the things bidsmith manages — campaigns, ad groups, keywords, budgets, conversion actions, and so on. Each resource block has:

  • A type (the first quoted string after resource, e.g. google_ads_campaign_budget). The type determines which fields are valid; see the resource reference for every type bidsmith understands.
  • A local name (the second quoted string — summer in the example above). It’s how you refer to this resource elsewhere in your .bid files. Pick something short and descriptive. Google doesn’t see this name; it’s a bidsmith-local identifier.
  • Attributes (key-value pairs inside the block — name, amount_micros, etc.).
  • Sometimes nested blocks for sub-configuration (manual_cpc { … }, network_settings { … }).

The lifecycle block

Every resource can carry a lifecycle block. It isn’t a Google Ads field — it tells bidsmith what it’s allowed to do with the resource:

resource "google_ads_campaign" "gh_video_fr" {
name = "GH_YouTube_FR Instream 11.08.2026"
advertising_channel_type = "VIDEO"
campaign_budget = google_ads_campaign_budget.video_fr.id
lifecycle {
create = false
}
}

create = false means adopt this, never create it. bidsmith will match the block to a campaign that already exists in the account and take over managing it; if it can’t find one, the plan stops and says so instead of quietly trying to create it.

That matters most for Video campaigns, which the Google Ads API refuses to create at all — see Adopt a campaign you built in the Google Ads UI.

lifecycle isn’t accepted on keyword or targeting resources: Google creates those freely, so there’d be nothing for it to protect.

Project layout

The simplest project is one file:

my-bidsmith-project/
└── main.bid

Once you have more than ~5 campaigns, split it up. Common patterns:

my-bidsmith-project/
├── account.bid # provider + conversion actions + shared sets
├── summer-2026.bid # one campaign per file
├── black-friday-2026.bid
└── always-on-brand.bid

or by market:

my-bidsmith-project/
├── account.bid
├── us.bid
├── pl.bid
└── de.bid

bidsmith reads every .bid file in the directory (recursively) and treats them as one project. The file split is purely for your ergonomics; bidsmith doesn’t care.

Comments

HCL accepts three comment styles:

# This is a comment.
// So is this.
/*
And multi-line comments look like this.
*/

Most of the file should be self-documenting, so keep comments for the things the code genuinely can’t say — why a budget is the number it is, who signed off, what an odd-looking setting is working around. Those survive bidsmith fmt untouched, so a note you leave beside a value stays beside it. See Leave a note explaining a number.

Formatting

bidsmith ships an opinionated formatter. Run it before committing to keep the project tidy:

Terminal window
bidsmith fmt .

In CI, use bidsmith fmt --check . to fail the build if anything isn’t canonical.

What’s not in a .bid file

Things you might expect to be in a .bid file that aren’t:

  • Performance data (impressions, clicks, conversions). Use Google Ads’ reporting; bidsmith manages configuration only.
  • Account credentials. Those live in environment variables. See Authentication.
  • Time-bound state. bidsmith doesn’t track “this campaign was launched on March 5” — Git history does, since your .bid files are versioned.

Next