Bandura — API testing IDE

The graph and the code are the same file.

Bandura is a local-first IDE for API testing: no account, no forced cloud, fully offline. Every flow is a plain-YAML .aether file in your own Git repo — a visual graph you can arrange by hand and a code editor you can be exact in, over one source of truth. AI with your own key, never credits.

v1.0.0 in development — 138 end-to-end tests passing · launching soon

Launch-day download link and a founding-user badge. By joining you agree to receive one or two launch emails — no reselling, opt out any time, and your address is deleted on request.

Not downloadable yet — early birds get the launch build first. macOS · Windows · Linux, signed installers at v1.0  ·  See how it works ↓

Bandura desktop app after a run: an eight-node checkout flow rendered as a graph with green passed borders, an orange false branch, and the inspector showing the exact request the create-order node sent, including the captured bearer token Bandura desktop app after a run: an eight-node checkout flow rendered as a graph with green passed borders, an orange false branch, and the inspector showing the exact request the create-order node sent, including the captured bearer token
A real run of a real flow: login → stock check → order → receipt. Every node shows its state; the inspector shows exactly what the selected node sent — including the token captured at login.

One file, two hands

Not an export. Not a sync. Two renderings of one file.

Postman Flows gives you a graph and hides the code. Bruno gives you code and has no graph. Bandura refuses the choice: the graph view and the code view are the same .aether YAML, edited either way, always in agreement — because there is nothing to keep in agreement. Visual enough for manual QA to model a scenario; exact enough for automation engineers to own every step — one Git-reviewable file for the whole team.

Watch the file become both views: every YAML block that lands in the Code panel pops the same node into the Graph, and each routing line draws its edge. Nothing to sync — there is only one file.
- 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   # every later node can read this
  next: get_product

Plain YAML with embedded JavaScript. Human-readable, diffable, and — because it's just text — something an AI assistant can actually read and reason about.

The same checkout flow as YAML in the code editor, with the inspector still showing the selected node's resolved request The same checkout flow as YAML in the code editor, with the inspector still showing the selected node's resolved request
The Code tab: the whole flow as YAML. Switch to Graph and it's the same nodes — routing lives on each node, so the edges are derived, never stored twice.

Runs like an IDE

Watch it run. Then ask any node what actually happened.

A run lights the graph node by node — passed, failed, branching live. Click any node for its resolved request and response: not the template, the real thing that went over the wire, headers and all. Values captured by one node (capture: accessToken) are visible everywhere they're used.

The node inspector showing the resolved request: POST /orders with the Authorization header carrying the captured bearer token and the JSON body The node inspector showing the resolved request: POST /orders with the Authorization header carrying the captured bearer token and the JSON body
What did this node send? Method, URL, headers — including the Bearer token captured two nodes earlier — and body, fully resolved.
The variables inspector after a run: baseUrl, productId and quantity from the flow, env values from .env, and accessToken, unitPrice, orderId captured during the run The variables inspector after a run: baseUrl, productId and quantity from the flow, env values from .env, and accessToken, unitPrice, orderId captured during the run
The variables inspector after a run: flow defaults, .env values, and everything captured along the way.

And before a run: unresolved references get a on the node and a banner — Bandura asks before running blind, instead of failing three nodes deep with a silent undefined.

Git-native by construction

Sharing a test suite is git clone.

There is no workspace invite, no export, no import — a Bandura project is a folder of plain-text files, so it was already in your repo. Your teammate clones it and runs.

  1. git clone … && open the folder

    Bandura recognizes the project from bandura.json and the .aether files. Nothing to convert.

  2. fill in the two env vars it asks for

    The manifest declares required variable names — never values. Secrets go to a git-ignored .env, or the OS keychain. They never touch the format.

  3. ▶ Run

    Under a minute from clone to a green graph. That's the whole onboarding.

Review API tests like code — because they are

@@ flows/checkout-flow.aether @@
   - id: create_order
     type: request
     config:
       method: POST
-      url: ${{ variables.baseUrl }}/order
+      url: ${{ variables.baseUrl }}/orders
       capture:
+        orderId: response.body.id

An .aether change in a pull request: reviewable line by line, blameable, revertable. Try that with a database-backed collection.

Opening a flow with an unset environment variable: the node carries a warning badge and a banner offers to fill the variable or run anyway Opening a flow with an unset environment variable: the node carries a warning badge and a banner offers to fill the variable or run anyway
The cloner's first run: Bandura points at exactly what's unset and where to fill it — one honest banner instead of a cryptic failure.

Terminal & CI

The same engine runs everywhere the work happens.

The desktop app, the CLI, and the MCP server share one execution engine. A flow that passes on your machine passes identically in CI — it's the same code running the same file.

Available at launch

# Installs a self-contained native binary — no runtime to load
npm install -g @bandura/cli
bandura --version

# ...or run without installing
npx @bandura/cli run

A native binary per platform — macOS (Apple Silicon & Intel), Linux (x64/arm64, glibc & musl), and Windows x64. No account, no backend. Join early access for the launch-day install, or read the CLI reference →

bandura run with the pretty reporter — then echo $? prints 0. Real output, real contract.

Exit code 0 on green, non-zero on any failure — the CI contract. Reporters: pretty, JSON, JUnit XML, GitHub annotations. Run a file, a glob, or a named suite: bandura run --collection smoke runs an ordered collection as one report.

# .github/workflows/api-tests.yml — generated by "Export to CI/CD"
- uses: bandura-io/run@v1
  with:
    flows: "flows/**/*.aether"
  env:
    BASE_URL: ${{ secrets.STAGING_URL }}

The CLI, the official GitHub Action, and in-app CI/CD export are all shipped today. Secrets flow in as environment variables — the same .env contract as local runs.

AI as an instrument

AI that plays with you, not at you.

Bring your own Anthropic key: your cost, your data, no credit meter, nothing metered behind your back. And because flows are plain text, the AI — yours or your editor's — gets full-fidelity context, not a proprietary blob.

The Generate flow with AI modal, with a natural-language description of a password-reset flow filled in The Generate flow with AI modal, with a natural-language description of a password-reset flow filled in
Describe the flow; get a full, schema-valid graph. Generated flows are validated before they ever touch disk.
The Heal modal comparing a flow against an OpenAPI spec: three drifts found — a renamed path, a missing required header, and a changed method — each with a one-click Apply fix The Heal modal comparing a flow against an OpenAPI spec: three drifts found — a renamed path, a missing required header, and a changed method — each with a one-click Apply fix
Self-healing: point a flow at your OpenAPI spec. Renamed paths, changed methods, new required headers — detected deterministically, fixed with one click. Works offline; no AI key needed.
The whole self-healing loop: run → one node 404s → drift detected against the spec → Apply → re-run green. Deterministic, offline, about eight seconds.

Your agent can run the whole loop

The Bandura MCP server exposes your workspace to Claude Code, Claude Desktop, or Cursor as structured tools. An agent lists your flows, runs one, reads the failing node's request and response, edits the YAML — it's just a file in your repo — and re-runs. No GUI round-trip, no screen scraping. And it runs where your files are: a local stdio process, not a vendor cloud relay — the agent's view of your flows, tokens, and responses never transits anyone's servers. (Postman's own State of the API 2025: 51% of developers worry about AI agents' unauthorized access to their APIs; 46% fear credential leakage. Locality is the fix, not a policy promise.)

claude — working in ~/storefront-api
> The checkout flow is failing after the API update — fix it ⏺ bandura-mcp: run_flow(checkout-flow.aether) ✗ get_receipt — 404 Not Found (GET /order/ord_1042) ⏺ bandura-mcp: detect_drift(checkout-flow.aether, specs/openapi.yaml) path-not-found: GET /order is not in the spec — closest match is GET /orders ⏺ Edit(checkout-flow.aether) — /order → /orders ⏺ bandura-mcp: run_flow(checkout-flow.aether) ✓ 7 nodes passed (14ms) Fixed — the orders endpoint moved to /orders; the flow now passes.

The rest of the workbench

Small things that make it feel like an IDE, because it is one.

Command palette

⌘⇧P for every command, ⌘P-style search across commands and files. VS Code-style keyboard shortcuts throughout — hands stay on the keys.

Eight node types

request assertion condition loop parallel script ai-action subflow — branch, iterate, fan out, compute, compose flows from flows.

Real terminal, built in

A full terminal in the bottom panel, opened in your workspace — run git, curl, or the bandura CLI without leaving the window.

Run history

Every execution persisted locally (SQLite) — durations, per-node results, what changed between runs. Local means local: history never leaves your machine.

Flow Map

A workspace-level view of how flows connect through subflows — watch a parent run light up its children live.

Plays well with other editors

Edit an open file in VS Code or pull from Git and Bandura notices — clean files reload silently, dirty ones get an honest reload-or-keep choice. It's your file, not the app's.

Data-driven runs

Attach a CSV or JSON dataset (or inline rows) and the flow runs once per row, the row in scope as data. Each row is an independent test case — a capture in one never leaks into the next — with a per-row pass/fail tally at the end.

Start from a template

New from template drops in a ready-to-run flow — smoke test, auth chain, CRUD, pagination, poll-until, data-driven. Each one runs against a public sandbox on the first try, so you learn the format by running it, not reading about it.

Compared, honestly

Where Bandura stands — as of July 2026.

Bandura Postman Bruno Insomnia Apidog
Plain-text, Git-native format ✓ YAML in your repo ✗ cloud workspace ✓ .bru files partial — Git sync partial — Git sync
Visual multi-step flow graph Flows — no code view scenario steps
Code-level editing of every step ✓ same file as the graph not in Flows
Works offline, no account required ✗ account + sync local Vault, but Kong account gates most features 4-user free cloud tier
AI pricing model BYO key — no credits credit economy BYO LLM bundled quota
Self-healing against OpenAPI drift ✓ deterministic, offline spec-driven regen
Retry & poll-until on any step ✓ declarative in YAML ✗ script loops only ✗ script loops only ✗ script loops only per-step on-error only
MCP server for AI agents ✓ shipped, local — no cloud relay
Headless CLI for CI ✓ shipped, incl. GitHub Action Newman/CLI
Protocols beyond REST REST, GraphQL, gRPC, WebSocket GraphQL, gRPC ✓ broad ✓ broad
What it costs Free; $59 once per seat for commercial use — 12 months of updates, and the build you have keeps working $9 / $19 / $29 / $49 per user/mo $6 / $11 per user/mo $12 / $45 per user/mo $9 / $18 / $27 per user/mo

When Postman is still the right call: if you need protocols Bandura doesn't speak yet (SSE, MQTT, SOAP), a hosted team workspace with real-time collaboration, or a large built-in monitoring/mock cloud, the incumbents are further along. Bandura's bet is the opposite one — a local-first, Git-native, plain-text tool that does the API-testing job exceptionally and stays out of your cloud. If that trade is yours to make, keep reading.

Import is one click for Postman collections and environments, OpenAPI/Swagger specs, Insomnia exports, Bruno requests, and curl commands — shipped today. Competitor details from our July 2026 review of public pricing and docs; corrections welcome at [email protected].

The Import flows modal with a pasted Postman collection auto-detected, ready to convert into .aether files The Import flows modal with a pasted Postman collection auto-detected, ready to convert into .aether files
Paste a Postman collection (or an OpenAPI spec, or a curl command) — format auto-detected, one .aether file per request, variables carried over.

Where it fits

Six jobs Bandura is built for.

Migrating

Leave Postman without losing your collections

One-click import turns collections into plain files in your repo. No seat pricing surprise can follow you into your own Git history.

CI

API regression tests in your pipeline

bandura run over a folder of flows: exit codes, JUnit output, GitHub annotations. Replace the brittle Newman setup with files your team can review.

Sharing

Onboard a teammate with a clone

Ship runnable API examples with your repo. The manifest asks for the env vars it needs; a minute later they're watching the graph go green.

Agents

Let your AI agent fix the failing test

Via MCP, an agent runs a flow, reads the failing node's real request and response, edits the YAML, and re-runs. The whole loop, no GUI.

Debugging

Untangle a multi-step auth chain

Login, capture the token, chain authorized calls — then click any node to see the exact resolved request it sent. No more copy-pasting bearer tokens.

Maintenance

Keep tests honest against a moving API

Teams report 60–80% of testing time going to maintaining brittle tests, not writing them. Point a flow at the current OpenAPI spec; apply the drift fixes — deterministically, offline; re-run.

In the open

What's shipped, what's next, what's later.

No dates, no vaporware: everything on this page marked shipped is in the app today, and everything that isn't says so.

Shipped

  • Desktop IDE — graph + code editor over .aether, 10 node types
  • Execution engine with per-node request/response inspection & history
  • Retry & poll-until on any step — declarative in the YAML, not script loops
  • Data-driven runs — one flow, once per CSV/JSON row, each row independent
  • GraphQL requests — same request node, same engine in desktop, CLI, and MCP
  • gRPC nodes — unary & server-streaming, via .proto or server reflection
  • WebSocket nodes — connect, send, collect messages, close
  • Import: Postman collections & environments, OpenAPI/Swagger, Insomnia, Bruno, curl
  • Natural-language flow generation (BYO key)
  • Self-healing vs OpenAPI drift — deterministic, offline
  • Headless CLI — pretty/JSON/JUnit/GitHub reporters
  • Collections — an ordered suite as one report, from the CLI (bandura run --collection) and a workspace sidebar view
  • Flow template gallery — one-click starter flows that run on the first try
  • MCP server: list, read, run, drift-check, import
  • Clone → run onboarding: manifest recognition + env prompt
  • GitHub Action + in-app CI/CD export
  • User docs — the help center is live now

Next

  • Signed installers for macOS / Windows / Linux — v1.0 launch
  • More protocols — SSE, MQTT, SOAP — order set by early-user demand

Later

  • Scheduled monitors & remote execution
  • Web app
  • Team workspaces (hosted collaboration)
  • Mock server generator
  • HAR importer

Pricing

Free to download. $59 once, if it earns you money.

The download is the whole app — not a trial, not a community edition, not a version with the good parts removed. Personal projects, learning and open source are free indefinitely. Using it at work? Thirty days to evaluate it properly, then buy a seat: one payment, twelve months of new releases, and the version you have keeps working after that. Nothing is ever switched off; the commitments below are the part we put in writing.

  1. Local functionality is free, forever. Saving, editing, and running local flows will never move behind a paywall — licence or no licence.
  2. Git collaboration is free by construction. Sharing via a repo is just Git. We will never charge for your own version control.
  3. No AI credit economy. Bring your own key — free and unmetered at our layer. Hosted AI, when it comes, is a flat per-seat inclusion.
  4. No forced account, even after you buy. Your key is verified offline against a public key inside the app. There is no server to log into, and no server that can be switched off to disable software you paid for.
  5. No "lifetime" promises. A licence covers twelve months of new releases, stated up front, and the build you have goes on working after that. That window is the only boundary — whatever we ship inside it is yours, major versions included. Vendors who promised "everything, forever" for one payment have all had to take it back. We would rather commit to less and keep it.
  6. Nothing is ever switched off. The 30 days are how long we stay quiet, not how long the app works. Day 31 is exactly as capable as day 1 — no read-only mode, nothing that runs out, no feature that a licence unlocks. The end of an update window works the same way: the copy you have carries on unchanged.

Download

$0

  • The complete desktop IDE, unlimited flows
  • All importers, CLI, MCP server
  • AI features with your own key
  • No account, no telemetry, works offline

Free indefinitely for personal work, learning and open source — not a trial, and nothing expires. See the downloads →

Licence — for commercial use

$59 once, per seat · 30 days to decide

  • Every release we build in the next 12 months
  • That version then runs unchanged for good — renewing is optional
  • New releases and betas before they're public
  • Your bug reports answered first
  • Verified offline; keeps working if we don't

Buying unlocks nothing, because nothing is locked. The licence terms give you 30 days to evaluate Bandura at work, and after that a dismissible note — once a day at most — is all that ever mentions it. Running a build from outside your 12 months without renewing brings back that same note, and nothing else.

Licences open at launch

Hosted — later

post-1.0

  • Web access, remote & scheduled runs
  • Hosted AI (flat, no credits)
  • Team workspaces, shared history

Subscription, because it genuinely runs on servers we pay for. Nothing that runs on your own machine will ever move here.

Buying opens at the v1.0 launch. Until then the app isn't downloadable and there's nothing to pay for — join the early-access list below for the launch-day link and a founding-user badge.

Why "Bandura"

Named after an instrument you play with both hands.

The bandura is a Ukrainian string instrument — a lute's fretted neck and a zither's open strings fused over one soundboard. One instrument, two ways of playing, every string tied to the same resonant board. That's the product in one image: the graph and the code are two hands on the same strings, and the .aether file is the soundboard underneath.

Questions, answered straight

FAQ

Can I download Bandura today?

Not yet — the desktop app is in active development toward its v1.0.0 launch, with 138 end-to-end tests passing against the current build. The /download page lists exactly what ships and on which platforms: macOS (Apple Silicon and Intel), Windows, and Linux, each built natively on its own machine. Joining the early-access list gets you the launch-day download link first and a founding-user badge.

Is Bandura free?

The download is the complete app — nothing locked, timed, or degraded — and it is free indefinitely for personal projects, learning, and open-source work. Using it at your job is what a licence is for: 30 days to evaluate it, then $59 once, per seat, covering every release we build in the following 12 months. It is not a subscription, and after those 12 months the version you have keeps working. Unlimited flows, all importers, the CLI, the MCP server, and AI features with your own key are in the free download either way.

What happens after the 30 days if I don't buy a licence?

The app carries on exactly as before. Nothing is disabled, degraded, or made read-only — not at day 31, not ever. What changes is that it starts showing a dismissible note, at most once a day, asking you to buy a seat if you're using it commercially. That is the entire enforcement mechanism. We would rather ask honestly than build a tool that holds your own work hostage, and the end-to-end test suite pins that down: one of the tests exists purely to prove an unlicensed, past-30-days install still runs flows.

Is the licence a subscription?

No. One payment of $59 per seat — nothing auto-renews, and no card is kept on file. What the payment covers is every release we build in the 12 months after you buy: every bug fix and every feature that lands in that window is yours. Builds we make after your window need a renewal, and renewing is optional and costs less than the first purchase; we'll publish the exact renewal price well before anyone's first 12 months are up. The window is the only boundary: if version 2.0 lands while yours is open, you get it — there is no separate upgrade fee to work out. We call this perpetual rather than 'lifetime' because there is a real boundary and we would rather tell you where it is.

What happens when the 12 months of updates run out?

The version you have keeps working, unchanged, forever. It does not expire, go read-only, phone home, or lose a feature — the boundary is on new builds, never on the software you already run. If you do install a release built after your window without renewing, the only thing that happens is the same dismissible note, at most once a day, comes back. Nothing else changes. Renewing is optional, and the app never asks for a card. Verification stays offline throughout: your key is checked on your own machine against a public key built into the app, with no server involved, so it keeps working even if we disappear.

What do I actually get for the $59?

Permission to use Bandura commercially, every release we build in the following 12 months, and three things that are worth having on their own: new releases and beta builds reach licence holders before they go public, your bug reports and feature requests get answered first by the person who wrote the code, and you can be credited in the release notes if you want to be. Plus the note stops appearing.

Is Bandura a Postman alternative?

Yes — that's the most common migration. Unlike Postman, Bandura needs no account and no cloud sync: your API tests are plain-text .aether files in your own Git repository. One-click import for Postman Collection v2.1 is shipped, so your existing collections come with you.

Is Bandura open source?

Not today. But there is no lock-in by design: the .aether format is plain YAML in your repo, readable and editable by any tool, and the format is documented. Your tests never live in our database — they live in your Git history.

What is an .aether file?

One flow: an ordered, branching set of nodes (request, assertion, condition, loop, parallel, script, AI action, subflow) written as plain YAML with embedded JavaScript expressions. The visual graph and the code editor are two renderings of that one file — routing lives on each node, so there's no separate graph state to drift out of sync.

Does Bandura work offline?

Fully. Editing, running, importing, drift detection, the CLI — all local, no account, no network required. Only the AI generation and chat features call out, using your own Anthropic key.

Can I import Postman collections, OpenAPI specs, or curl commands?

Yes, all shipped: Postman Collection v2.1 (folders flattened, variables and auth carried over), OpenAPI 3.0/3.1 and Swagger 2.0, pasted curl commands, Bruno requests (.bru and OpenCollection YAML), Insomnia v4 (JSON) exports, and Postman environment files (imported as .env values).

What platforms does it run on?

macOS (Apple Silicon and Intel), Windows, and Linux (AppImage and .deb). Every installer is built natively on its own platform, so nothing is cross-compiled. The first releases are unsigned while the Apple and Windows certificates are being obtained, which means macOS asks you to right-click → Open the first time and Windows shows a SmartScreen prompt; both are expected, and we would rather say so than have you discover it. Signing lands shortly after launch.

Does it support GraphQL, gRPC, or WebSocket?

All three are shipped. GraphQL rides the request node (a graphql block with query, variables, operationName), with GraphQL errors failing the node loudly instead of hiding behind an HTTP 200. gRPC is its own node type — unary and server-streaming, via a .proto file or server reflection. WebSocket is a node too — connect, send, collect messages, close. Every one runs identically in the desktop app, the CLI, and the MCP server. SSE and MQTT are the next protocols on the roadmap.

What does the AI cost?

Whatever your Anthropic key costs you — Bandura adds no markup, no credits, no metering. And most of the intelligence doesn't need a key at all: import, drift detection, and self-healing fixes are deterministic and run offline.

How do I run API tests in CI?

The bandura CLI runs any flow or glob headlessly and exits non-zero on failure — the standard CI contract. Reporters: pretty for terminals, JSON, JUnit XML for test history, and GitHub annotations. An official GitHub Action and in-app CI/CD export are shipped too. You can also run a named suite in one shot: bandura run --collection smoke executes an ordered collection defined in bandura.json and reports it as one result.

Can I run one flow against many rows of test data?

Yes — attach a CSV or JSON dataset (or inline rows) to a flow and it runs once per row, with that row in scope as `data` (use it in any URL, header, body, or assertion). Each row is an independent test case: a value captured in one row never leaks into the next, and the run reports a per-row passed/failed tally. It runs the same in the desktop app and the CLI, so it works in CI too.

v1.0.0 in development — launching soon

Be there on launch day.

Early birds get the launch-day download link, a founding-user badge, and the extended trial we promised when the hosted tier ships. Until then: one or two emails, nothing else.

Launch-day download link and a founding-user badge. By joining you agree to receive one or two launch emails — no reselling, opt out any time, and your address is deleted on request.