$ git status → nothing hidden

Everything is a file.

API Craft is a desktop API IDE where specs, requests, environments, workflows and docs are plain files in your git repo. Edit them in the app, from the craftr CLI, or in vim. Same files, three interfaces. No account. No cloud sync. No lock-in.

Downloads: coming soon

Public builds open shortly. Free tier, no signup. Windows coming.

find-by-status.jsonplain JSON. Edit it in the app or in vim
{  "version": 1,  "name": "Find available pets",  "operation": { "resource": "Pet", "name": "findByStatus" },  "params": {    "query": { "status": "available" }  }}

A real project. Click a file: what you see is what's on disk, and what the GUI edits.

why

The difference isn't a feature. It's the model.

PostmanBrunoAPI Craft
Where your work livesTheir serversYour repoYour repo
AccountRequired to keep anythingNoneNone
FormatProprietary; export to leave.bru filesJSON, YAML, Markdown, OpenAPI
What's modeledA folder of requestsA folder of requestsResources and operations, from the spec
The OpenAPI specImported onceImported onceThe source of truth
A request isOne mutable objectOne fileN instances per operation
Working with someonePer seat, per monthgitgit

Bruno got the file layer right, and got it right first. API Craft goes one layer up.

The full argument →

instances

A request is a file, not a slot you overwrite.

Everywhere else a request is a single mutable object, so to try something you overwrite the thing you're trying it on. Here an operation comes from the spec and each request instance is a file under it. Keep as many as you want: shared with the team, personal, or scratch.

The get operation in the resource tree holding three request instances, one public and two private, with a private debug-404 request selected and its 404 response
Three files under one operation: one committed, two gitignored. Switching to a private one to reproduce a 404 costs nothing: the shared request is untouched.

environments

Environments inherit. Secrets never leave your machine.

Variables are declared once in a schema: typed, required or optional, secret or not. Values live in committed JSON per environment; secrets live next to them in gitignored dotenv files. The extends chain resolves recursively, with cycle detection.

Environment list with stage badges, the inheritance chain, and per-variable source files
Every value shows where it came from: inherited, overridden, or read from a gitignored secrets file.

workflows

API tests as state machines. In JSON, in your repo.

A workflow is a sequence of typed blocks (request, assert, condition, loop) with declarative assertions for the common cases and TypeScript when you need real logic. Author it in the app; run the same file headless with craftr workflow run in CI.

Workflow run panel: selected workflows, environment bindings, and a pass/fail tree per block
Run one workflow or all of them. Same result tree in the app and in CI output.

cli

The GUI authors. The CLI runs anywhere.

$ craftr req run Pet/find-by-status \
    --api petstore-api --env dev --full | jq '.response.status'
200
$ craftr workflow run pet-lifecycle --env petstore-api=staging
{ "status": "passed", "total": 1, "passed": 1, "failed": 0 }

JSON output, always. Colored on a TTY, raw when piped, so jq works with no extra flags.

# .github/workflows/api-tests.yml
steps:
  - uses: actions/checkout@v4
  - run: npm install -g @apicrafthq/cli
  - run: craftr workflow run pet-lifecycle --env petstore-api=staging
    env:
      API_CRAFT_VAR_APIKEY: ${{ secrets.PETSTORE_KEY }}

The repo is the collection. CI needs checkout, one install, one command.

agents

Your agent already knows how to use it.

Every project is JSON, YAML and Markdown on disk, and the CLI prints JSON for everything the app can do. So Claude Code, Cursor, or any coding agent works with the tools it already has: read the API model, write a request instance, run it, read the result, fix itself. No plugin, no integration, no API key.

> add a request for sold pets and check it works

  Bash   craftr schema read -a petstore-api
         → Pet: get, create, delete, update…
  Write  apis/petstore-api/resources/Pet/
           requests/find-sold.json
  Bash   craftr req run Pet/find-sold
           --env dev
         → {"status": 200, "body": [ … ]}

Added find-sold. Returns 200 with 4 pets.

pricing

Free to live in. Paid when it becomes structural.

Free

$0

1 API per project, unlimited projects. 2 environments, 3 workflows. Full CLI, full GUI. No account, no wall.

Team soon

Shared secrets, run dashboards, docs hosting. Leave an email to hear about it.

Full comparison and FAQ →

git clone and you have the whole API setup.