How to Use Postman for API Testing: Beginner Guide (2026)
Quick answer
Postman tests APIs through a GUI request builder: set the method and URL, send the request, then add pm.test() assertions in the Tests tab to check the status code and response body. Group related requests into a Collection, use an Environment for variables like {{base_url}}, and chain data between requests with pm.environment.set(). Once the collection is built, run it headless in CI/CD with the Newman CLI instead of the desktop app — the same collection file works in both places.
Reviewed by Smeet Gohel
Postman is a GUI application for building, sending, and testing HTTP requests — you set the method, URL, headers, and body in a visual editor, send the request, and inspect the response without writing any networking code. It remains the most common first tool for API testing because there is nothing to install beyond the app itself and no framework to learn before sending your first request.
This guide covers the actual beginner path: building and sending a request, writing your first pm.test() assertion, organizing requests into a Collection, using an Environment for variables, chaining data between requests, and — the step most beginner tutorials skip — running the whole collection headless in CI/CD with Newman.
Table of Contents
- Building and Sending Your First Request
- Writing Your First Test Assertion
- Organizing Requests into a Collection
- Using Environments for Variables
- Chaining Requests with Variables
- Testing POST, PUT, and DELETE
- Running a Collection with the Collection Runner
- Running Headless in CI/CD with Newman
- Common Pitfalls for Postman Beginners
- When a Hand-Built Collection Stops Scaling
- FAQ
Building and Sending Your First Request
Open Postman, click New → HTTP Request, set the method dropdown to GET, and enter a URL:
https://jsonplaceholder.typicode.com/users/1
Click Send. The response panel below shows the status code, response time, body (formatted as JSON by default), and headers as separate tabs — no code required to get this far.
Writing Your First Test Assertion
Click the Tests tab (next to Body, Headers, etc. in the request editor) and add:
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Response has an email field", function () {
const jsonData = pm.response.json();
pm.expect(jsonData).to.have.property("email");
});
Send the request again. A Test Results tab now appears in the response panel showing each pm.test() as pass or fail. Postman bundles the Chai assertion library, which is where pm.expect()'s fluent syntax (.to.have.status(), .to.have.property(), .to.equal()) comes from.
Organizing Requests into a Collection
Click Save, and Postman prompts you to create or choose a Collection — a named, saved group of requests. Build out a few more requests (list users, get a single post, create a post) and save each into the same Collection. This is the container that gets run all at once later, exported for version control, and executed in CI.
Using Environments for Variables
Hardcoding https://jsonplaceholder.typicode.com into every request works until you need to point the same collection at staging vs. production. Click the Environments tab in the sidebar, create a new Environment, and add a variable:
| Variable | Initial Value |
|---|---|
base_url | https://jsonplaceholder.typicode.com |
Select this Environment from the dropdown in the top-right corner, then rewrite your request URLs to use it:
{{base_url}}/users/1
Switching the active Environment (staging, production, local) now changes every request in the collection with no per-request edits.
Chaining Requests with Variables
A realistic test sequence often needs output from one request as input to the next — create a resource, then fetch it. In the Tests tab of the create request:
pm.test("Status code is 201", function () {
pm.response.to.have.status(201);
});
const jsonData = pm.response.json();
pm.environment.set("newPostId", jsonData.id);
Ready to shift left with your API testing?
Try our no-code API test automation platform free. Generate tests from OpenAPI, run in CI/CD, and scale quality.
A later request in the same Collection run can then use {{newPostId}} in its URL:
{{base_url}}/posts/{{newPostId}}
pm.environment.set() writes to the currently active Environment, so this value is available to any request that follows it in the same run — but be aware it persists between runs too unless explicitly cleared, which can cause a stale value to leak into a later, unrelated run.
Testing POST, PUT, and DELETE
Set the method dropdown, go to the Body tab, select raw and JSON, and enter the payload:
{
"title": "foo",
"body": "bar",
"userId": 1
}
// Tests tab for the POST request
pm.test("Status code is 201", function () {
pm.response.to.have.status(201);
});
pm.test("Title matches request", function () {
const jsonData = pm.response.json();
pm.expect(jsonData.title).to.eql("foo");
});
The same pattern applies to PUT and DELETE — only the method, path, and expected status code change.
Running a Collection with the Collection Runner
Click the Collection's ⋮ menu → Run collection to open the Collection Runner. It executes every saved request in order, shows a pass/fail summary across all their pm.test() assertions, and supports an Iterations count plus an optional CSV or JSON data file for running the same sequence with different input data per iteration — Postman's equivalent of parametrized tests.
Running Headless in CI/CD with Newman
The desktop app has no place to run inside a CI pipeline. Newman is Postman's official CLI collection runner — it executes the exact same Collection and Environment files from the command line.
Export both from Postman (⋮ menu → Export on the Collection, and the Environment's own export button), then:
npm install -g newman
newman run collection.json -e environment.json
# .github/workflows/api-tests.yml
name: API Tests
on: [push, pull_request]
jobs:
postman-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install -g newman
- run: newman run collection.json -e environment.json --reporters cli,junit --reporter-junit-export results.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: newman-results
path: results.xml
Newman exits with a non-zero status code if any pm.test() assertion fails, which is what lets a normal CI step fail the pipeline. The exported collection.json should be committed to version control alongside your code so CI always runs the version that matches the current branch, not a stale local export.
Common Pitfalls for Postman Beginners
- Hardcoding URLs instead of using an Environment variable. It works for one request; it becomes a find-and-replace exercise across dozens once you need a second environment.
- Forgetting the Environment is selected.
{{base_url}}resolves to nothing if no Environment is active in the top-right dropdown — a common source of confusing failures for beginners. - Testing only the happy path. A collection with only 200-status assertions never proves the API rejects bad input correctly — add requests with invalid IDs or malformed bodies and assert on the expected 4xx.
- Letting chained variables persist stale values between runs. Clear or overwrite
pm.environment.set()values at the start of a run if a previous run's leftover value could produce a false pass. - Exporting a Collection once and never re-exporting after edits. The
collection.jsonNewman runs in CI is a snapshot — if you edit the collection in the app and forget to re-export, CI keeps testing the old version. - Storing secrets as plain Environment values committed to version control. Use a separate, gitignored Environment file for real credentials, or Postman Vault / CI secrets for the values that matter.
Free Guided worksheet
Build Your Testing Strategy in 30 Minutes
A structured worksheet that walks you through defining your testing strategy in 30 minutes. Cover architecture, tools, layers, and team responsibilities.
Download FreeWhen a Hand-Built Collection Stops Scaling
Everything above scales linearly with effort: twice the endpoints means roughly twice the requests, pm.test() blocks, and environment variables to keep in sync with the real API. For a service with a dozen endpoints, that is a completely reasonable, fast way to get both manual exploration and an automated regression suite from one tool.
Somewhere past a few dozen endpoints across multiple services, keeping the collection accurate by hand — updating it every time a field changes, an endpoint is added, or a status code changes — starts competing with the API's own development for engineering time. This is exactly the transition point covered in migrating from Postman to spec-driven testing: instead of hand-maintaining requests and assertions, Total Shift Left generates the equivalent suite directly from your OpenAPI spec and regenerates it automatically when the spec changes.
Frequently Asked Questions
Do I need to know how to code to use Postman?
No for basic request sending — the GUI handles that. Writing pm.test() assertions uses JavaScript, but it's a small, repeatable pattern most beginners pick up from a few examples.
What is the difference between a Postman Collection and an Environment?
A Collection is the saved group of requests (the tests). An Environment is a named set of variables those requests reference with {{variable}} syntax.
How do I pass data from one Postman request to the next?
Call pm.environment.set("name", value) in the first request's Tests tab, then reference {{name}} in a later request in the same Collection run.
How do I run a Postman Collection outside the app?
Export the Collection and Environment as JSON, install Newman, and run newman run collection.json -e environment.json.
What is Newman and why do I need it for CI/CD? Newman is Postman's official CLI collection runner — it executes the same Collection and Environment files from the command line, producing an exit code CI can gate on, since the desktop app can't run in a pipeline.
When does a hand-built Postman collection stop scaling? Past roughly a few dozen endpoints across services, keeping every request and assertion synced with the API by hand becomes a real maintenance burden.
Key Takeaways
pm.test()+pm.expect()(via bundled Chai) is Postman's entire assertion model — a small pattern, not a full JavaScript framework to learn.- Environments decouple requests from a specific URL — switch staging/production/local by changing the active Environment, not the requests.
pm.environment.set()chains data between requests, but values persist between runs unless explicitly cleared.- Newman is what makes a Collection CI/CD-usable — the desktop app itself has no place in a pipeline.
- Re-export the Collection after every edit. CI runs whatever
collection.jsonwas last committed, not your current app state. - A hand-built collection scales linearly with endpoint count. Past a few dozen endpoints across services, generating tests from an OpenAPI spec becomes the more maintainable path.
Related Articles
- Migrating from Postman to Spec-Driven Testing — the transition once a hand-built collection stops scaling.
- Postman vs Shiftleft AI — a full comparison for teams evaluating both.
- API Testing with Python: pytest + requests Tutorial — a code-first alternative to a GUI-built collection.
- API Test Automation with CI/CD: Step-by-Step Guide — wire any test suite into your pipeline.
When Your Collection Outgrows Hand Maintenance
Every request and assertion in this guide can also be generated automatically. Import your OpenAPI specification into Total Shift Left and get positive, negative, and boundary test cases for every endpoint — regenerated the moment your spec changes, with no Postman collection to keep in sync by hand.
Start your free trial and compare the generated suite against your own collection, or see plans and pricing if you're already evaluating.
Ready to shift left with your API testing?
Try our no-code API test automation platform free.