Git-native by construction

Git-native API testing: tests you can review in a pull request.

A Bandura flow is one plain-YAML .aether file in your repository, not a record in a vendor's database that you occasionally export. So the things you already do to code work on your tests unchanged: branch them, diff them, blame them, revert them, require a review before they merge. The graph canvas and the code editor are two renderings of that same file, so there is no "source of truth" question to settle.

v1.0.0-rc.8 is out now on Windows and Linux. v1.0.0 final, and signed macOS builds, in August 2026.

Download for Windows or Linux
or

One email when the signed macOS build and 1.0.0 ship, no reselling, opt out any time.

Windows · Linux · macOS when notarized  ·  What a flow file looks like ↓  ·  Clone → run ↓

The format is the file

One flow, one file, no hidden state.

Routing lives on each node, in next, then and else fields, so there is no separate edges table to keep in step. The graph is derived from what you can read.

version: "1.0"
name: Checkout happy path
variables:
  baseUrl: https://api.example.com
nodes:
  - id: login
    type: request
    config:
      method: POST
      url: ${{ variables.baseUrl }}/auth/login
      body: |
        { "email": "${{ env.DEMO_EMAIL }}", "password": "${{ env.DEMO_PASSWORD }}" }
      capture:
        accessToken: response.body.token
    next: get_cart

Values captured from one response are named and reused by later nodes. Secrets are env.* references, never literals, which is what makes the file safe to commit. The .aether file →

The Code tab: the create_order node of a checkout flow as .aether YAML in the Monaco editor, showing its method, url, headers, body, capture and next fields, with the node inspector's Result tab docked to the right on the request that ran The Code tab: the create_order node of a checkout flow as .aether YAML in the Monaco editor, showing its method, url, headers, body, capture and next fields, with the node inspector's Result tab docked to the right on the request that ran
This is the file Git sees. Nothing is serialized on save, so the bytes in the editor are the bytes in the commit.

Code review, for tests

A tightened assertion is one changed line.

   config:
-    check: "response.status === 200"
+    check: "response.status === 200 && response.body.items.length > 0"

That is the entire diff for "also check the cart isn't empty". A reviewer sees the intent, not a re-serialized document. The same review that gates a change to the API can gate the change to the test that guards it.

Source Control, in the app

Stage, unstage, and commit without leaving the editor. Every change opens as a side-by-side diff with .aether syntax highlighting, and staged rows diff HEAD against the index, so you review exactly what you are about to commit rather than what happens to be in the working tree.

Each file carries its own history rail: who changed it, when, and in which commit, renames followed. Discard is confirm-gated; an untracked file goes to the system Trash rather than vanishing. A single block can be reverted from the diff gutter.

Reviewing flow changes →

No new verbs to learn

The commands you already type work on the tests.

Nothing below is a Bandura feature. It is git, operating on a text file that happens to be an API test suite. That is the entire argument of this page, stated as a transcript instead of an adjective.

zsh · ~/storefront-api
$ git log --oneline -- flows/checkout.aether a1f3c0e tighten the cart assertion: items must be non-empty 9d21b74 poll the fulfilment job until it reports ready 4c8e102 import the checkout collection from Postman $ git diff main...HEAD -- flows/ - check: "response.status === 200" + check: "response.status === 200 && response.body.items.length > 0" $ grep -rl 'api.example.com' flows/ | wc -l 14 $ git revert a1f3c0e # the assertion is back to what it was

git bisect, git blame, git cherry-pick, a CODEOWNERS rule on flows/: all of it applies, because none of it knows or cares that the file is a test. A pre-commit hook has one Bandura-shaped option worth knowing: bandura validate checks every flow against the schema without executing anything and exits 3 on the first bad file, which is fast enough and network-free enough to sit in a hook. The one thing to keep out of the repo is .env; flows reference secrets as env.* and never contain them.

Onboarding

There is no import step, because there was no export.

Handing a suite to a teammate is handing them the repository. That is not a convenience feature; it is what follows from the tests being files.

git clone [email protected]:acme/storefront-api.git
cd storefront-api
cp .env.example .env   # fill in the secrets: they were never committed
# open the folder in Bandura, pick an environment, press Run

Bandura recognises a project by its bandura.json manifest (name, flow globs, environments, and the variable names a run requires), so opening the folder is the setup. Clone from GitHub… does the same thing from inside the app. Share flows with Git →

What stays on your machine

Run history, variable overrides, the environment you happen to have selected, breakpoints, and your AI key all live outside the workspace: per machine, never committed, never shared. Your repository carries the tests; your laptop carries your state.

No account, no workspace sync, and no telemetry, and the licence is verified offline against a public key compiled into the app rather than a server we run. The app makes exactly two requests of its own, both switchable off: an AI provider if you configure one, and a once-a-day anonymous check for a newer version. Both, in full →

What follows from plain text

Tools you already have start working on your tests.

grep, sed, and everything else

A suite you can search with ordinary tools is a suite you can refactor. The app ships project-wide search and replace (⌘⇧F, confirm-gated), but nothing stops you doing it from the terminal instead.

CI is one command

Because the runner reads files, the pipeline needs no account and no export: bandura run "flows/**/*.aether", an exit code, and a JUnit report. API testing in CI →

Agents can read them

A model can reason about YAML it can read, run, and rewrite, which is why the MCP server and the in-app chat can actually fix a failing flow rather than describe it.

Bring what you already wrote

Postman, Insomnia, Bruno, OpenAPI, HAR captures, and raw curl commands import into flows, with a review step before anything is written to disk. Importing →

Leave whenever you like

The exit is cp -r. Flows are YAML you can read without us; there is no proprietary store to be extracted from, and no plan tier that decides whether you may open your own files.

Ten node types, all declarative

Branch, loop, fan out in parallel, compose flows from flows, assert, script, call gRPC or a WebSocket: every one of them a few readable lines. Node reference →

For teams

An API testing tool for teams that already use Git.

There is no team plan, because the repository is the team feature. What a hosted workspace charges per head for, your Git host already does.

Review is the collaboration

A changed assertion is one changed line in a pull request, so test changes go through the same review that gates the code they guard. A CODEOWNERS rule on flows/ makes that mandatory, and nobody needs an account anywhere to read the diff.

One payment per seat, nothing renewing

One payment per commercial seat, priced at launch, after each person's 30-day evaluation; free for personal use. Keeping the suite in a repository you already own is never a billing line, and there is no per-user monthly fee to re-justify at renewal, because nothing renews.

Onboarding is git clone

A new teammate clones the repo, copies .env.example, and presses Run. The bandura.json manifest names the flows and the variables a run requires, and the pre-run guard lists anything still unset before a request is sent.

The boundaries

What Git-native does not give you.

No hosted workspace

There is no real-time shared collection, no presence indicators, and no server-side team sync. Collaboration is branches, pull requests, and review. For a team already working that way this is the feature. For one that wants non-developers editing collections in a browser, it is not, and a hosted tool is the better answer today.

No cloud runs or schedules

Bandura executes where you are: the app, the CLI, your CI runner. There is no remote execution or scheduled monitoring service; cron and your pipeline cover the common case, and we would rather say so than imply a service we have not built.

Push, pull, branch and merge are not in the app

The Source Control view stages, commits, diffs, shows per-file history, and reverts a hunk. It does not push, pull, fetch, branch, or merge. Those stay with your normal Git tooling, and the app ships a terminal rather than a second, worse implementation of them.

No signed macOS build yet

Windows and Linux installers are on the download page today. The Mac builds exist but are held until they are signed and notarized. The Windows one is unsigned too, so SmartScreen shows a warning you click through. That is the state of it as this ships, not a permanent position.

Questions, answered straight

FAQ

How do I keep API tests in Git?

In Bandura they are already there. One flow is one .aether file: plain YAML, in whatever folder of your repository you put it. There is no database, no workspace record, and no export step, so committing a test is committing a file. Branch it, review it in a pull request, blame it, revert it, grep it, and cherry-pick it exactly like the code it tests.

Does a flow diff readably in a pull request?

Yes, and that is the reason for the format. A changed assertion is one changed line of YAML, so a reviewer reads intent instead of reconstructing it from a serialized blob. Even the graph layout lives in the file as ui.position, which means the arrangement you made on the canvas travels to your teammate's canvas instead of being regenerated differently on each machine.

Can a reviewer read a flow change without installing Bandura?

Yes. The diff on GitHub, GitLab, or in git diff is the whole change, because the file is the format. The graph is derived from the same YAML rather than stored beside it, so there is no second representation a reviewer would be missing. That also means a reviewer who does have the app is reading exactly what the pipeline will run, not a rendering of it.

What should I commit, and what should I not?

Commit the .aether flows, the bandura.json manifest, any datasets, and a .env.example. Do not commit .env. Secrets are referenced as env.* and read from the environment or a dotenv file, so they never need to be inside a flow. Run history, variable overrides, your selected environment, and your AI key all live outside the workspace, per machine, and are never written into the repo.

Can Bandura do Git work without leaving the app?

The Source Control view stages and unstages files, commits, and shows every change as a syntax-highlighted side-by-side diff. Staged rows diff HEAD against the index, so you review exactly what you are about to commit. Per file it lists the commits that touched it with author and date, renames followed. Discard is confirm-gated, and an untracked file goes to the system Trash rather than being deleted outright. A single change can be reverted from the diff gutter. Push, pull, branching, and merges stay with your normal Git tooling; the built-in terminal is right there.

How does a teammate get my tests?

They clone the repo and press Run. Bandura recognises a project by its bandura.json manifest (name, flow globs, environments, required variable names), so opening the folder is the whole setup, and the pre-run guard names any variable that is still unset before anything is sent. There is no import step because there was never an export.

What about merge conflicts in a flow file?

They behave like conflicts in any other text file, which is the point of plain YAML. Your usual merge tool works, and the Source Control view groups conflicted files separately so they are not mistaken for ordinary changes. Nothing about the format requires a special resolver.

Is Bandura a good API testing tool for teams?

For a team that already collaborates through Git, yes, and deliberately so. Flows are files in the repository, so sharing them is a push, reviewing a change is a pull request, and a CODEOWNERS rule on the flows folder makes review mandatory. There is no team plan and no workspace to administer: each commercial seat is a single one-time payment after that person's 30-day evaluation, priced when checkout opens at launch, and keeping the suite in a repository you already own never becomes a billing line. What Bandura does not offer a team is a hosted shared workspace with live presence, so a team that wants non-developers editing collections in a browser is better served by a hosted tool today.

How does a team share API tests without a sync service?

Through the repository, which is a sync service your team already trusts. The bandura.json manifest makes a folder of flows a project: name, flow globs, environments, and the variable names a run requires. A teammate clones, copies .env.example to .env, and presses Run; the pre-run guard names any variable still unset before a request is sent. Machine-local state (run history, breakpoints, overrides, AI keys) stays out of the workspace, so nothing personal rides along with a push and nobody inherits someone else's debugging session.

Keep reading

Where the files go next.

Run them in CI

One command, deterministic exit codes, JUnit XML, and GitHub annotations on the pull request that changed the flow.

Let an agent read and edit them

A local MCP server gives Claude Code or Cursor the same YAML a reviewer sees: run it, read the failure, change the file.

Postman vs Bruno, sourced

The cloud workspace against the other files-in-your-repo tool, strengths conceded, with Bandura as the third option rather than the headline.

Where every piece of data sits

The repo holds the tests; a table on that page names the file that holds each of the other things: keys, history, preferences, breakpoints.

Migrating from Postman

Collections, environments, and pm.* scripts come across, and land in your repo as files.

Already git-native with Bruno?

Then you agree with this page already. The straight answer to "why pay at all" is there, and Insomnia's Git Sync is compared too.

v1.0.0-rc.8 is out now. v1.0.0 final in August 2026

Put the tests where the code is.

Open the repo you already have and commit the first flow tonight: the diff on that commit is the argument this whole page has been making. The Windows and Linux builds ship with the importers, the Source Control view, and the CLI in them; on a Mac, leave an address and you get the signed build the day it is notarized.

Download for Windows or Linux

One email when the signed macOS build and 1.0.0 ship, no reselling, opt out any time.

Or read what a teammate does with the commit: Share flows with Git covers the clone-to-run side.