Compare

Stampdrill and Postman

Both send HTTP requests and check what comes back. The difference is where the requests are kept, and that one decision settles most of the rest: how a change gets reviewed, what a new colleague clones, what the build server runs, and what you pay for. What Stampdrill adds on top is the rest of the job in the same file: the plan that runs the requests in order, the load test with its thresholds, and the race that fires five at the same instant. There is a list further down of what it does not do, so you can see the shape of it before you spend an afternoon moving.

Where the requests live

In Postman a request belongs to a collection, and the collection belongs to a workspace. In Stampdrill a request is a few lines of text in a .stamp file in your repository, next to the code that answers it.

### Log in
POST {{baseUrl}}/auth/login
Content-Type: application/json

{ "username": "{{username}}", "password": "{{password}}" }

> assert status == 200
> set token = body.accessToken

### List posts
@needs logIn
@auth bearer {{token}}
GET {{baseUrl}}/posts?limit={{limit}}

> assert status == 200
> assert all(body.posts, post => post.title != null)

That file is the whole thing: the request, the login it depends on, the token it carries, and the checks. What follows is not a feature list, it is the working day.

The cost is just as concrete. There is no workspace to invite anyone into, and nothing syncs. Sharing is a git repository, and the pulling, branching and merging are yours to do with the tools you already have. Two people editing the same request on two branches get a merge conflict in a text file, which is more work than a cloud workspace and less surprising than a silent overwrite.

The sidebar: test plans, load tests, then the request files of the workspace
The sidebar: test plans, load tests, then the request files of the workspace

What Postman does that Stampdrill does not

These are real gaps, not quibbles. If one of them is load-bearing for your team, you have your answer without reading further. Postman's own documentation is the place to check what it covers today.

One smaller edge comes from the Mac App Store sandbox: the app cannot start another program, so an MCP server launched with stdio: is tested from the command line rather than in the window. The app reads only the folders you hand it, which is the same rule seen from the other side.

What a .stamp file holds that a collection has nowhere to put

All of this is the same file, the same language and the same review as the request above it.

What moves across

stamp import reads a Postman collection, format 2.0 or 2.1, together with the environment and globals exports that belong with it. Export all of them, then name them in one command. The order does not matter, and -o is the folder to write into.

stamp import Blog.postman_collection.json staging.json production.json -o blog

  created blog/Auth.stamp
  created blog/Posts.stamp
  created blog/environment.stamp
  created blog/environment.local.stamp
Imported Blog (Postman collection): 2 requests in 2 files

One file per folder of the collection. The two environments became the values of one dimension instead of two copies of the same list, so the whole import points at staging or at production by choosing a value:

dimension environment = staging, production

vars {
  baseUrl = "https://dummyjson.com"
}

vars environment=staging {
  limit = "5"
}

vars environment=production {
  limit = "25"
}

The API key in the staging environment was not written there. Anything whose name reads like a credential goes to environment.local.stamp wrapped in secret(), so it is masked in output, and that file is added to .gitignore. Nothing has been sent at this point, which is the useful part of an import: stamp check parses the folder and touches no network.

stamp check blog

✓ 3 files, 2 requests

What came across, line by line: a folder becomes a .stamp file named after it; a request title becomes the ### line and the name other requests use, so Log in becomes logIn; pm.response.to.have.status(200) becomes > assert status == 200; pm.environment.set("token", jsonData.accessToken) becomes > set token = body.accessToken; bearer auth on the request becomes @auth bearer {{token}}; collection variables become a vars { } block. Response time and header checks convert as well. Script lines with no equivalent are kept as comments above the request, so nothing is dropped quietly, and a pre-request script is reported rather than translated.

Import never writes over a file that is already there, and it leaves alone every variable the workspace already declares, so it cannot change what an existing request sends. The guide follows one collection the whole way, with the output of every command and the two files it produced: Bringing collections in. The same section covers Insomnia, Bruno, HAR, curl and OpenAPI, which take the same shape of command.

The two edits an import needs

An import is a starting point, not a finished workspace. Two things are worth fixing first, and both exist because a collection has nowhere to record them.

Say what a request depends on. A collection relies on being run from the top, so nothing in the export says that listing posts needs a login first. Run that request on its own and it stops on the variable the login would have set. One line fixes it for good, whichever way the request is reached:

### List posts
@needs logIn
@auth bearer {{token}}
GET {{baseUrl}}/posts?limit={{limit}}

@needs logIn runs the login once per session, and the request it names can sit in another file.

Turn numbers back into numbers. Every Postman variable is text, so limit arrived as "5". Comparison is strict, and 5 == "5" is false, so a check that compares it to a number needs the quotes taken off in environment.stamp.

The guide shows the failure each one produces before the fix, under Two things to fix afterwards.

Side by side

StampdrillPostman
Price$49.99 once for the Mac app, on the Mac App Store. The stamp command is free, including commercially and in CI, so a build server and a colleague who lives in the terminal cost nothing.Free and paid plans, per user per month. See postman.com/pricing.
Where requests live.stamp text files in a folder you chose, usually your repository.A collection in a workspace.
What runs themThe Mac app, the free stamp command, or an agent through stamp mcp. All three read the same files.The app, the web client, and the command line runner.
What a team sharesA git repository, pulled and merged by you. Requests are reviewed in a pull request.A workspace, with accounts, roles and sync.
What CI runsOne static binary and the files in the repository. stamp check, then stamp test, with JUnit, HTML or JSON and an exit code. See Running in CI.The command line runner against an exported collection or a workspace.

Postman's prices are theirs to state, and the link above is the current list. For context on why this question is being asked in 2026 at all: third-party reporting through the year has it that Postman's free plan became a single user in March 2026, and that collaborating with other people now starts on a paid team plan at around $19 per user per month.

Trying it without deciding

The part worth testing is the import, and it needs neither the app nor an account. Install the free command, point it at a collection you already have, and read what it writes.

brew install stampdrill/tap/stampdrill
stamp import collection.json environment.json -o api
stamp check api
stamp list api

If the files look like something you would review, the quick start is the next five minutes and the guide is the rest. The engine and the command are open source under the Mozilla Public License 2.0 at github.com/stampdrill/stampdrill, so the files you write keep running whatever happens to this project. The Mac app is separate, proprietary, and $49.99 on the Mac App Store.

The guide Quick start Stampdrill and Bruno

Updated