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

# File Organization

Your Adjar config can live in a single TOML file or be split across many — the loader merges everything into one logical account before any `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:

```
google.toml                   ← root: platform + [account] only
google/
  assets.toml                 ← [[assets]] library
  conversions.toml            ← [[conversions]]
  campaigns/
    brand.toml                ← one [[campaigns]] each
    db-access-control.toml
    competitor-terms.toml
```

```toml theme={null}
# google.toml
platform = "google"
imports = [
  "google/assets.toml",
  "google/conversions.toml",
  "google/campaigns/*.toml",
]

[account]
id = "4821937650"
```

Why this shape:

* **Diffs stay small and scoped.** `apply` writes 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.toml` and 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 hit `campaigns/`.

<Note>
  The example above is a Google Ads layout. **OpenAI Ads** has no asset or conversion sections, so its split is simpler — an `openai.toml` root (`platform` + `[account]`) importing `openai/campaigns/*.toml`. The mechanics below are identical.
</Note>

## How `imports` composes files

The `imports` array in a file lists the fragments to merge into it. See the [account root reference](/docs/config/google/account) 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.

<Note>
  Imported fragments may contain **only** the platform's top-level array sections — for Google Ads that's `[[assets]]`, `[[conversions]]`, and `[[campaigns]]`; for OpenAI Ads it's `[[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.
</Note>

## Two rules that keep write-back predictable

Because `apply` rewrites your config to record server-issued IDs, two behaviors are worth knowing:

1. **New blocks land in the root file.** When you add a campaign (or asset, or conversion) with no `id` and run `apply`, the loader has no recorded "slot" for it, so its written-back form goes to `google.toml` rather than into `campaigns/`. After the first apply, move the block into its own file — subsequent applies then keep it there.

2. **Configs are machine-edited, so comments don't survive.** Every `apply` re-serializes the files it touches. Inline TOML comments are dropped on write-back. Keep explanatory notes in commit messages, a README, or your agent's `SKILL.md` — not inside the TOML.

## Related Pages

* Account Root — the `platform`, `imports`, and `[account]` fields in the root file, for [Google Ads](/docs/config/google/account) and [OpenAI Ads](/docs/config/openai/account)
* [Introduction](/docs/introduction) — why plain-text config in git is the foundation for AI-assisted ad management
* [The core workflow](/docs/cli/overview#the-core-workflow) — how `import`, `plan`, `apply`, and `report` turn config edits into live changes
