Skip to main content
This is the complete file reference for code-managed flows: where files live under .autosana/, and every recognized key in flow files, suite manifests, and hook scripts.

Repository layout

Everything Autosana manages lives under a single .autosana/ folder — at your repository root by default, or under a subdirectory you point Autosana at (see Monorepos). Flows are *.flow.yaml files, a suite is a folder containing a _suite.yaml manifest, and hooks are script files under a hooks/ directory.
A file is only recognized if it ends in .flow.yaml, is named exactly _suite.yaml, or sits directly inside a hooks/ folder with a supported extension. Other files under .autosana/ are ignored.

Flow files

A flow file ends in .flow.yaml. The only required keys are name and instructions, where instructions is either a single multiline prompt or a YAML list of steps. As a multiline prompt:
Or as a list of steps:
The recognized top-level keys are:
Any top-level key that isn’t in the table above is a hard error. A typo like instructoins: fails validation with a “Did you mean ‘instructions’?” suggestion on the Autosana Flows check, so mechanical mistakes are caught before they merge.
Let the path derive your key. If you omit key, the key comes from the file path (.autosana/smoke/checkout.flow.yaml becomes smoke/checkout). Set an explicit key when you want the key to stay stable even if you move or rename the file — see Deleting and renaming.

Referencing variables

Reference environment variables inside instructions with the ${env:VAR_NAME} token. This is reference only — the values stay defined in the dashboard and are resolved just in time when the flow runs. There is no env: block in the YAML; the value never lives in your repo.
Define and manage the actual values in the dashboard — see Variables for the full variable model and Environments for per-environment values.

Referencing hooks

Attach hooks to a flow with setup_hooks and teardown_hooks, each an ordered list of hook slugs:
A slug resolves against every active hook in your organization — not just repo files — so you can also reference hooks authored in the dashboard, including cURL hooks (which can only be created in the dashboard). Find a dashboard hook’s slug on the hook in the Hooks page. See Hooks as files for how a repo file’s slug is derived. Duplicate slugs within one list are rejected. The same slug may appear in both setup_hooks and teardown_hooks — that’s legal. To reference a hook by name inside your instructions at run time, use ${hooks:Hook Name} (by display name); see Hooks.

Labels

Attach labels to a flow or suite with labels, a list of label names:
Names match case-insensitively against your org’s labels; unknown names are auto-created. Omitting labels leaves the flow/suite’s existing labels untouched — an explicit labels: [] clears them. Labeled flows and suites dispatch via run-by-label as usual.

Suites

A suite is a folder containing a _suite.yaml manifest. The suite’s key is its folder path (a smoke/ folder gives the suite key smoke). The only required key is name:
The recognized keys are: References in flows and setup_flow resolve sibling-first: a flow directly in the suite’s own folder wins, otherwise the reference is matched against every flow in the repo. Flows in a subfolder are not default members — list them explicitly (or give the subfolder its own _suite.yaml). Flow keys and suite keys must each be unique across the whole repo. An unknown reference, or the same flow listed twice, is a validation error.
The _suite.yaml file must live inside a folder — it cannot sit at the .autosana/ root, because a suite is a folder. Membership is defined by the suite (its flows list or its folder), never declared inside the flow files themselves.
YAML parses bare no, yes, on, and off as booleans (the “Norway problem”). Because setup_flow and name must be strings, setup_flow: no fails validation — quote the value if you really mean the string "no".
For how variables and setup flows propagate across a suite’s flows, see Suites.

Hooks as files

Hooks live as script files inside a hooks/ folder — either .autosana/hooks/ or <suite>/hooks/. The file extension determines the hook type, and the filename becomes the hook’s slug. The slug is derived from the filename with its final extension removed: lowercased, with runs of non-alphanumeric characters collapsed to -. So Seed DB.sh becomes slug seed-db, and reset.env.json becomes reset-env. This slug is what you reference in setup_hooks / teardown_hooks. The display name is the humanized filename (reset-test-env.sh shows as “Reset Test Env”).
Hook slugs are unique across your whole organization — the folder a hook lives in has no scoping effect. Two files that slugify the same (seed-db.py and seed_db.sh), or a slug that collides with a different repository’s hook, fail the sync with a rename error. A slug that matches an existing dashboard-authored hook is not an error — that hook is adopted (its run history preserved), the same way flows adopt by name; see Migrating existing flows. Rename the file if that isn’t what you intend.
The file content is the hook script, stored verbatim. Empty or whitespace-only files are rejected. A .json launch-args hook must parse as valid JSON, and a filename with no letters or digits (so it produces an empty slug) is rejected.
Script hooks (.py, .js, .ts, .sh) read environment variables nativelyos.environ.get(...) in Python, process.env in JavaScript/TypeScript, $VAR in Bash. Launch-args (.json) hooks — and dashboard-authored cURL hooks — use the ${env:KEY} token instead, since they aren’t executed scripts. cURL hooks have no file form; reference an existing dashboard cURL hook by slug, or use a .sh hook that runs curl. See Hooks for the full hook model.

Monorepos

By default Autosana looks for .autosana/ at your repository root. If your definitions live in a subdirectory — common in a monorepo — point Autosana at that folder with the repo’s Root directory setting.
  1. Go to Settings > Integrations
  2. On the repo with Code-Managed Testing enabled, set Root directory to the folder that contains .autosana/ (for example, services/mobile for services/mobile/.autosana/)
  3. Leave it blank to use the repository root
Flow and suite keys stay relative to .autosana/, so moving your definitions into a subdirectory doesn’t change any keys — a flow at services/mobile/.autosana/login.flow.yaml still has the key login. The GitHub links on each row point at the full path in your repo.
Saving a new Root directory doesn’t re-sync on its own, and an unrelated push won’t either. To re-sync from the new location, push a change under <root-directory>/.autosana/ on your default branch, or toggle Code-Managed Testing off and on. The nightly resync also picks it up within a day.

Next Steps