plan or apply runs, so the split is purely about how you want to read, diff, and edit. This page covers when to split, how the imports directive composes files, and the two rules that keep write-back predictable.
Single file or split?
Both are fully supported.| Single file | Split (recommended) | |
|---|---|---|
| Best for | Small or experimental accounts, one editor | Real accounts, team or AI-agent editing |
| Diffs | Every change touches one big file | Each change touches one small file |
| Setup | Nothing — just google.toml | A root file plus an imports list |
adjar import bootstraps to a single file (or stdout) by default, so starting single and splitting later is the natural path — there’s no migration, just move blocks into new files and add an imports entry.
Recommended layout: split by section, one file per campaign
For anything beyond a handful of campaigns:- Diffs stay small and scoped.
applywrites server-issued IDs back into the file that declared each element, so editing one campaign touches one file in git — not a 2,000-line monolith. - Clean boundaries for AI agents. An agent told to tune the competitor campaign edits
competitor-terms.tomland can’t accidentally clobber another. One file = one unit of work. - Match files to change rate.
[account], assets, and conversions change rarely; campaigns churn constantly. Keeping the stable sections in their own files means most diffs only hitcampaigns/.
How imports composes files
The imports array in a file lists the fragments to merge into it. See the account root reference for the field itself; the resolution rules are:
- Glob-aware.
"google/campaigns/*.toml"picks up every campaign file in the directory — adding a new campaign is just creating a new file. - Relative to the importing file’s own directory, not the repo root or your working directory.
- Nesting is allowed. An imported file may itself declare
imports, resolved relative to its location. Cycles are detected and rejected. - Deterministic merge order. Within each section, files merge in sorted order, so the result is reproducible.
Imported fragments may contain only top-level array sections —
[[assets]], [[conversions]], [[campaigns]]. The singletons platform and [account] must stay in the root file, or the loader errors. This is what makes a fragment unambiguously a fragment.Two rules that keep write-back predictable
Becauseapply rewrites your config to record server-issued IDs, two behaviors are worth knowing:
-
New blocks land in the root file. When you add a campaign (or asset, or conversion) with no
idand runapply, the loader has no recorded “slot” for it, so its written-back form goes togoogle.tomlrather than intocampaigns/. After the first apply, move the block into its own file — subsequent applies then keep it there. -
Configs are machine-edited, so comments don’t survive. Every
applyre-serializes the files it touches. Inline TOML comments are dropped on write-back. Keep explanatory notes in commit messages, a README, or your agent’sSKILL.md— not inside the TOML.
Related Pages
- Account Root — the
platform,imports, and[account]fields in the root file - Introduction — why plain-text config in git is the foundation for AI-assisted ad management
- The core workflow — how
import,plan,apply, andreportturn config edits into live changes