Newman CLI — Running Postman Collections from Terminal
9 min read
The Collection Runner is great for interactive work; for CI, you need a runner that lives in a terminal. Newman is Postman's official command-line tool. It takes the same collection JSON the GUI runs and executes it identically — no Postman app required. This lesson covers installing Newman, running a collection from the terminal, the flags you'll reach for daily, and how its exit codes plug into any CI system. The masterclass API Testing in CI/CD lesson covered the why of CI testing; this lesson is the Postman-flavoured how.
Why a CLI runner exists
The GUI Runner is interactive — perfect for local exploration, useless for a pipeline. CI runs need:
The collection JSON, environment JSON, and test scripts behave identically between GUI and CLI. Develop in Postman, run in Newman.
The two are complementary, not alternatives. Develop a suite in Postman, ship it via Newman.
Installing Newman
Newman is an npm package. You need Node.js 18+ on the machine. To install globally:
npm install -g newmannewman --version
You should see something like 6.0.0. If newman isn't found, the npm global bin directory probably isn't on your PATH — fix with export PATH="$(npm bin -g):$PATH" or follow your shell's npm setup.
For a project-scoped install (recommended in real repos):
cd path/to/your/reponpm install --save-dev newmannpx newman --version
That keeps the Newman version pinned in package.json so every contributor and the CI runner use the same one.
Running a collection
Export your collection from Postman first (right-click → Export → Collection v2.1). Then in your terminal:
newman run JSONPlaceholder-API-Tests.postman_collection.json
Newman parses the JSON, executes every request in order, runs every test, and prints a summary at the end:
→ GET All Users
GET https://jsonplaceholder.typicode.com/users [200 OK, 5.6kB, 215ms]
✓ Status is 200
✓ Response time is under 500ms
✓ Body is a non-empty array
→ GET User by ID
GET https://jsonplaceholder.typicode.com/users/1 [200 OK, 510B, 180ms]
✓ Status is 200
✓ Email field present
┌─────────────────────────┬────────────┬────────────┐
│ │ executed │ failed │
├─────────────────────────┼────────────┼────────────┤
│ iterations │ 1 │ 0 │
├─────────────────────────┼────────────┼────────────┤
│ requests │ 2 │ 0 │
├─────────────────────────┼────────────┼────────────┤
│ test-scripts │ 2 │ 0 │
├─────────────────────────┼────────────┼────────────┤
│ prerequest-scripts │ 0 │ 0 │
├─────────────────────────┼────────────┼────────────┤
│ assertions │ 5 │ 0 │
└─────────────────────────┴────────────┴────────────┘
Five assertions, zero failed. Exit code: 0 (success).
With an environment
Export your environment too (Environments tab → ⋯ → Export). Then point Newman at it:
newman run collection.json -e staging-env.json
Variables resolve exactly as they did in the GUI — {{baseUrl}}, {{authToken}}, all of it. Switching from staging to production is one CLI flag away.
For sensitive environments where the JSON has placeholder values and the real values come from elsewhere, use --env-var:
Each --env-var overrides (or adds) one variable. Pull from shell environment variables and the secret never lives in a file.
Data-driven runs from the CLI
Same data file you used in the GUI Runner (Chapter 4 Lesson 2):
newman run collection.json -e env.json -d test-data.csv
Newman runs once per row, substituting the row's values into {{vars}}. The summary table now shows multiple iterations and a per-iteration breakdown of any failures.
Running directly from the Postman cloud
If you don't want to manually export the JSON, Newman can fetch a collection from the Postman API:
newman run "https://api.getpostman.com/collections/<COLLECTION_ID>?apikey=<YOUR_POSTMAN_API_KEY>"
Convenient — but means CI has live internet access to Postman, and the API key needs careful storage. Most teams settle on the export-and-commit-to-Git approach: the JSON is auditable, version-controlled, and CI runs are reproducible even when Postman's services are down.
The flags you'll reach for daily
A short list that covers most real cases:
-e <env-file> — pick an environment.
-d <data-file> — pick a data file (CSV/JSON).
-n <count> — run the collection N times. Without -d this is just looping.
--folder <name> — run only one folder of the collection. Saves time when smoke-testing.
--delay-request <ms> — pause between requests. --delay-request 200 is friendly for rate-limited APIs.
--timeout-request <ms> — kill any single request that takes longer than this. --timeout-request 10000 (10 seconds) is a sensible default.
--bail — stop on the first failure. Default is to keep running and report the aggregate. Use --bail when an early failure makes later assertions meaningless.
--reporters cli,htmlextra — output formats. CLI is default; combine with htmlextra for HTML reports (next lesson) or junit for JUnit XML.
--env-var "key=value" — inline variable overrides (one flag per variable).
--insecure — skip TLS verification. Useful against test environments with self-signed certs; never use against production.
--suppress-exit-code — exit 0 even when assertions fail. Niche use: report-only runs where you don't want CI to fail the build.
1 — one or more assertions failed, or Newman itself errored.
Every CI system in existence treats a non-zero exit code as a failed step. Wiring Newman into GitHub Actions, Jenkins, GitLab, CircleCI, or any other pipeline is just "add a step that runs newman run ..." — the system fails the build automatically if anything fails.
To verify locally:
newman run collection.jsonecho $? # 0 if all passed
Adding to package.json scripts
In a real repo, the Newman invocation usually lives in package.json so contributors run it the same way:
Then anybody on the team runs npm run test:api and gets the same invocation. CI does the same.
⚠️ Common mistakes
Hardcoding secrets in committed environment files. Newman reads them happily; Git remembers them forever. Use --env-var "key=$VAR" so secrets come from CI environment variables, never the file.
Forgetting --insecure is for tests only.--insecure disables TLS verification. Useful when staging has a self-signed cert; catastrophic if used against production where MITM is now undetectable.
Skipping --timeout-request. Without a per-request timeout, a single hung endpoint can stall a CI step indefinitely. Set 10000ms (or whatever your slowest legitimate request is) and let Newman fail fast on stuck requests.
🎯 Practice task
Run your suite from the terminal. 25-30 minutes.
Install Newman: npm install -g newman (you need Node.js 18+). Verify with newman --version.
Export your JSONPlaceholder API Tests collection from Postman to disk. Right-click → Export → Collection v2.1 → save to a folder e.g. ~/postman-course/.
Export the JSONPlaceholder environment too (Environments tab → ⋯ → Export).
In a terminal in that folder:
newman run "JSONPlaceholder API Tests.postman_collection.json" \ -e JSONPlaceholder.postman_environment.json
Watch every request fire and the summary table at the end. Confirm echo $? prints 0.
Force a failure. Edit one of the test scripts in Postman to assert pm.response.to.have.status(999). Re-export the collection. Re-run Newman. The summary should show a failed assertion; echo $? should print 1. Revert.
Run only one folder:
newman run "JSONPlaceholder API Tests.postman_collection.json" \ --folder "CRUD Chain" \ -e JSONPlaceholder.postman_environment.json
Notice only the chain's five requests run.
Override an env var:
newman run "JSONPlaceholder API Tests.postman_collection.json" \ --env-var "baseUrl=https://my-json-server.typicode.com/typicode/demo"
The collection now hits the alternative host without a separate environment file.
Add to package.json. Initialise an npm project (npm init -y), install Newman locally (npm install --save-dev newman), and add a script:
"scripts": { "test:api": "newman run \"JSONPlaceholder API Tests.postman_collection.json\" -e JSONPlaceholder.postman_environment.json" }
Run npm run test:api. Same output, but now versioned with the project.
Stretch: add --delay-request 100 and --timeout-request 5000. Run again. Notice the visible pause between requests in the CLI output.
You can now run any Postman collection from a terminal — and so can any CI system. The next lesson layers HTML and JUnit reports on top of the CLI output, so you have something to share with stakeholders and parse in dashboards.
// tip to track lessons you complete and pick up where you left off across devices.