> ## 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.

# Campaign Config Reference

Each campaign in Adjar lives in a TOML file under your `google/campaigns/` directory (or wherever your [account root](/docs/config/google/account) points via `imports`). A single file can contain multiple `[[campaigns]]` entries. Adjar reads these files to understand your current campaign setup and writes changes back in the same format — making your entire campaign structure readable and editable by both humans and AI agents.

## Full Example

```toml theme={null}
[[campaigns]]
name = "DB Access Control | SEARCH | 2026-Q2"
status = "ENABLED"
channel_type = "SEARCH"
bid_strategy = "TARGET_SPEND"
max_cpc_ceiling_usd = 10
daily_budget_usd = 200
sitelinks = [ "sl-pricing", "sl-data-masking" ]

[campaigns.targeting]
include_geos = [ "US" ]
include_languages = [ "en" ]
include_devices = [ "DESKTOP" ]

[[campaigns.negative_keywords]]
text = "cybersecurity"
match_type = "BROAD"

[[campaigns.ad_groups]]
name = "JIT DB Access"
status = "ENABLED"
```

***

## `[[campaigns]]` Fields

<ParamField path="name" type="string" required>
  The display name of the campaign as it appears in Google Ads. Names must be unique within the account.

  A clear naming convention helps AI agents identify campaigns without ambiguity. A common pattern is:

  ```
  <Topic> | <Channel> | <Period>
  ```

  ```toml theme={null}
  name = "DB Access Control | SEARCH | 2026-Q2"
  ```
</ParamField>

<ParamField path="status" type="string" required>
  Controls whether the campaign is actively serving ads.

  | Value       | Behaviour                                      |
  | ----------- | ---------------------------------------------- |
  | `"ENABLED"` | Campaign is live and eligible to serve         |
  | `"PAUSED"`  | Campaign is suspended but retains all settings |

  ```toml theme={null}
  status = "ENABLED"
  ```

  `ENABLED` and `PAUSED` are the only values you set in config. To remove a campaign, delete its block from TOML — the next `apply` archives the live campaign. (Internally Adjar writes Google's `REMOVED` state during that archive; it is never something you author.)
</ParamField>

<ParamField path="channel_type" type="string" required>
  The Google Ads channel this campaign runs on.

  | Value      | Description                             |
  | ---------- | --------------------------------------- |
  | `"SEARCH"` | Text ads on Google Search results pages |

  ```toml theme={null}
  channel_type = "SEARCH"
  ```

  Additional channel types (e.g. `DISPLAY`, `PERFORMANCE_MAX`) will be documented as Adjar adds support for them.
</ParamField>

<ParamField path="bid_strategy" type="string" required>
  The automated bidding strategy Google uses to set bids for this campaign.

  | Value                         | Description                                                           |
  | ----------------------------- | --------------------------------------------------------------------- |
  | `"MANUAL_CPC"`                | You set bids manually (per ad group / keyword); the simplest baseline |
  | `"TARGET_SPEND"`              | Maximises clicks within the daily budget (Google's "Maximize Clicks") |
  | `"MAXIMIZE_CONVERSIONS"`      | Maximises conversions within the budget                               |
  | `"MAXIMIZE_CONVERSION_VALUE"` | Maximises total conversion value within the budget                    |
  | `"TARGET_CPA"`                | Sets bids to achieve a target cost per acquisition                    |
  | `"TARGET_ROAS"`               | Sets bids to achieve a target return on ad spend                      |

  ```toml theme={null}
  bid_strategy = "TARGET_SPEND"
  ```

  Only the strategy *kind* is modeled here. `TARGET_CPA` / `TARGET_ROAS` targets, and the conversion tracking the conversion-driven strategies require, are configured in the Google Ads UI — switching to one in TOML seeds an empty target that Google may reject until you set it (`apply`'s server-side validation will surface this).
</ParamField>

<ParamField path="max_cpc_ceiling_usd" type="number">
  An optional maximum cost-per-click cap in US dollars applied on top of the automated bid strategy. Google will not bid above this amount for any single click.

  Only valid when `bid_strategy` is `"TARGET_SPEND"`.

  ```toml theme={null}
  max_cpc_ceiling_usd = 10
  ```
</ParamField>

<ParamField path="daily_budget_usd" type="number" required>
  The average daily spend limit for this campaign in US dollars. Google may spend up to twice this amount on a given day, but will not exceed the monthly equivalent (daily × 30.4) over a calendar month.

  ```toml theme={null}
  daily_budget_usd = 200
  ```
</ParamField>

<ParamField path="budget_delivery" type="string" default="STANDARD">
  How the daily budget is paced.

  | Value           | Behaviour                                                                                                    |
  | --------------- | ------------------------------------------------------------------------------------------------------------ |
  | `"STANDARD"`    | Spends the budget evenly throughout the day (recommended)                                                    |
  | `"ACCELERATED"` | Front-loads spend; deprecated by Google for most campaign types and accepted mainly for round-trip on import |

  ```toml theme={null}
  budget_delivery = "STANDARD"
  ```
</ParamField>

<ParamField path="start_date" type="string">
  The date the campaign begins serving, `YYYY-MM-DD`. Omit to let Google use the campaign's existing/created start date.

  ```toml theme={null}
  start_date = "2026-04-01"
  ```
</ParamField>

<ParamField path="end_date" type="string">
  The date the campaign stops serving, `YYYY-MM-DD`. Omit for an open-ended campaign — Adjar leaves the end date unset rather than writing a phantom value.

  ```toml theme={null}
  end_date = "2026-06-30"
  ```
</ParamField>

<ParamField path="sitelinks" type="array of strings">
  A list of sitelink asset IDs to attach at the campaign level. These IDs must be defined in your `assets.toml`.

  Attachment resolves at the **most specific level — Google never merges**. Omitting the field (or setting it empty) inherits the [account-level](/docs/config/google/account) sitelinks; a non-empty list *replaces* the account set for this campaign. To keep an account-wide sitelink showing on a campaign that adds its own, re-list its ID here.

  ```toml theme={null}
  sitelinks = [ "sl-pricing", "sl-data-masking" ]
  ```
</ParamField>

<ParamField path="callouts" type="array of strings">
  Campaign-level callout asset IDs, with the same inherit-or-override semantics as `sitelinks`.

  ```toml theme={null}
  callouts = [ "co-soc2", "co-free-trial" ]
  ```
</ParamField>

<ParamField path="structured_snippets" type="array of strings">
  Campaign-level structured-snippet asset IDs, with the same inherit-or-override semantics as `sitelinks`.

  ```toml theme={null}
  structured_snippets = [ "ss-product-types" ]
  ```
</ParamField>

***

## `[campaigns.network]`

Controls which networks the campaign serves on — Google's `network_settings`. **All fields default to a Google-Search-only campaign**, so omitting the block keeps the campaign off Search partners and the Display Network. This is deliberate: Display spend inside a Search campaign produces no search terms and is easy to miss. The block is always compared against the live campaign, so a Display opt-in flipped on in the UI shows up as drift on the next `plan`.

<ParamField path="network.google_search" type="boolean" default="true">
  Serve on the main Google Search results pages. `search_partners` requires this to be `true`.
</ParamField>

<ParamField path="network.search_partners" type="boolean" default="false">
  Also serve on Google's Search-partner sites.
</ParamField>

<ParamField path="network.display" type="boolean" default="false">
  Also serve on the Display ("Content") Network.

  ```toml theme={null}
  [campaigns.network]
  google_search = true
  search_partners = false
  display = false
  ```
</ParamField>

***

## `[campaigns.targeting]`

The `[campaigns.targeting]` table controls who sees ads from this campaign. All fields are optional — omitting a field leaves that dimension unrestricted.

<ParamField path="targeting.include_geos" type="array of strings">
  List of country codes (ISO 3166-1 alpha-2) to target. Ads will only be eligible to show to users in these locations.

  Adjar maps each code to Google's numeric geo-target constant from a built-in whitelist. Currently supported: `US`, `CA`, `GB`, `DE`, `FR`, `NL`, `AU`, `JP`, `IN`, `SG`. An unrecognised code is rejected — extend the map in the CLI to add a new market.

  ```toml theme={null}
  [campaigns.targeting]
  include_geos = [ "US", "CA", "GB" ]
  ```
</ParamField>

<ParamField path="targeting.include_languages" type="array of strings">
  List of language codes to target. Ads will only show on Google properties using one of these languages.

  As with geos, codes map to Google's numeric language constants from a built-in whitelist. Currently supported: `en`, `de`, `fr`, `es`, `ja`, `zh`. An unrecognised code is rejected.

  ```toml theme={null}
  [campaigns.targeting]
  include_languages = [ "en" ]
  ```
</ParamField>

<ParamField path="targeting.include_devices" type="array of strings">
  List of device types to target. Ads will only be eligible to serve on the specified devices.

  | Value       | Device                       |
  | ----------- | ---------------------------- |
  | `"DESKTOP"` | Desktop and laptop computers |
  | `"MOBILE"`  | Smartphones                  |
  | `"TABLET"`  | Tablet devices               |

  ```toml theme={null}
  [campaigns.targeting]
  include_devices = [ "DESKTOP", "MOBILE" ]
  ```
</ParamField>

***

## `[[campaigns.negative_keywords]]`

Campaign-level negative keywords prevent ads in this campaign from showing on searches that match. They apply to every ad group within the campaign.

<ParamField path="negative_keywords.text" type="string" required>
  The keyword text to exclude. Do not include match type syntax characters (e.g. quotes or brackets) — use the `match_type` field instead.

  ```toml theme={null}
  [[campaigns.negative_keywords]]
  text = "cybersecurity"
  ```
</ParamField>

<ParamField path="negative_keywords.match_type" type="string" required>
  How broadly the negative keyword blocks traffic.

  | Value      | Blocks                                       |
  | ---------- | -------------------------------------------- |
  | `"BROAD"`  | Any search containing all words in any order |
  | `"PHRASE"` | Searches containing the exact phrase         |
  | `"EXACT"`  | Searches that match the keyword exactly      |

  ```toml theme={null}
  [[campaigns.negative_keywords]]
  text = "cybersecurity"
  match_type = "BROAD"
  ```

  See the [Keywords reference](/docs/config/google/keywords) for a full explanation of match type behaviour, including ad-group-level negatives.
</ParamField>

***

## `[[campaigns.ad_groups]]`

Ad groups sit inside a campaign and contain keywords and ads. Each `[[campaigns.ad_groups]]` entry must appear after the `[[campaigns]]` entry it belongs to.

<ParamField path="ad_groups.name" type="string" required>
  The display name of the ad group as it appears in Google Ads. Names must be unique within the parent campaign.

  A clear name reflects the keyword theme the ad group targets, making it easy for both humans and AI agents to identify which ad group to edit.

  ```toml theme={null}
  [[campaigns.ad_groups]]
  name = "JIT DB Access"
  ```
</ParamField>

<ParamField path="ad_groups.status" type="string" required>
  Controls whether the ad group is eligible to serve ads.

  | Value       | Behaviour                                           |
  | ----------- | --------------------------------------------------- |
  | `"ENABLED"` | Ad group is active and its keywords can trigger ads |
  | `"PAUSED"`  | Ad group is suspended but retains all settings      |

  ```toml theme={null}
  [[campaigns.ad_groups]]
  name = "JIT DB Access"
  status = "ENABLED"
  ```

  As with campaigns, `ENABLED` and `PAUSED` are the only values you set; remove the ad-group block to archive it.
</ParamField>

<ParamField path="ad_groups.cpc_bid_usd" type="number">
  The ad group's default maximum cost-per-click bid in US dollars. Used when the campaign's `bid_strategy` is `"MANUAL_CPC"`; automated strategies set bids at the campaign level and ignore this.

  ```toml theme={null}
  [[campaigns.ad_groups]]
  name = "JIT DB Access"
  cpc_bid_usd = 2.50
  ```
</ParamField>

An ad group holds its keywords and ads as nested arrays — `[[campaigns.ad_groups.keywords]]` and `[[campaigns.ad_groups.ads]]`. See [Keywords](/docs/config/google/keywords) and [Creatives](/docs/config/google/creatives) for those fields.

***

## Related Pages

* [Account Root](/docs/config/google/account) — how campaigns are imported via `google.toml`
* [Keywords](/docs/config/google/keywords) — keyword entries, match types, and negatives at the ad group level
* [Creatives](/docs/config/google/creatives) — ads, headlines, and descriptions nested inside ad groups
* [Assets](/docs/config/google/assets) — the sitelinks, callouts, and structured snippets that campaign attachments reference
* [Conversions](/docs/config/google/conversions) — the conversion actions that conversion-based `bid_strategy` values feed
