Postman is one of the most widely used tools for sending HTTP requests and checking how an API behaves. It started as a browser extension and grew into a full desktop application that handles everything from a quick GET request to scripted test suites that run in CI. If you build or consume APIs, you will almost certainly run into it.
This guide walks through testing an API in Postman the way you would do it day to day. You will send a request, inspect the response, write assertions in the Tests tab, set up environments so you can switch between staging and production, and run a whole collection at once with the Collection Runner. The examples use a public API so you can follow along without setting anything up first.
Set up Postman and send your first request
Download Postman from the official site and install the desktop app. You can use it without an account for local work, though signing in syncs your collections across devices. Open the app and click the New button, then choose HTTP Request.
A request needs three things at minimum: a method, a URL, and sometimes a body. Pick GET from the method dropdown and enter a real endpoint. The JSONPlaceholder service is handy for practice:
GET https://jsonplaceholder.typicode.com/users/1
Click Send. The response panel fills with the body, the status code (200 OK), the response time, and the size. Switch the body view between Pretty, Raw, and Preview to see the JSON formatted or as the server sent it.
For a POST, change the method, open the Body tab, choose raw, and select JSON from the format dropdown. Paste a payload like this:
{
"name": "Maria Chen",
"email": "maria.chen@example.com"
}
Headers such as Content-Type: application/json are added for you when you pick the JSON body type. The Headers tab lets you add anything else the API needs, like an Authorization header. If you are new to which response codes to expect, the guide on HTTP status codes REST APIs should use is a useful reference.
Organize requests into collections
A single request is fine for a quick check. Real testing means many requests that belong together: create a user, fetch that user, update them, delete them. Postman groups these into collections.
Click Collections in the sidebar, then the + icon to create one. Name it something concrete like “User API smoke tests.” Save each request into the collection with Ctrl/Cmd + S and give it a clear name. You can nest folders inside a collection to separate, say, authentication requests from resource requests.
Collections are also the unit you share. Export one as a JSON file, or share a link if you sync to the cloud. Teammates import it and have the exact same requests you do. This is the foundation for everything else, because the Collection Runner and automated tests both operate on collections rather than loose requests.
A collection can also carry shared behavior. Postman lets you attach scripts at the collection or folder level, not just on a single request. A pre-request script on the collection runs before every request inside it, which is useful for refreshing a token or stamping a timestamp. A test script at the collection level runs after every request, which is handy for an assertion you want everywhere, such as “the response time is reasonable.” Defining these once keeps your individual requests focused on what is unique to them.
Write tests in the Tests tab
Sending a request tells you what came back. A test tells you whether what came back is correct, automatically, every time. Postman runs JavaScript in the Scripts area of a request (older versions called this the Tests tab) after the response arrives.
Postman exposes a pm object for writing assertions. The core pattern is pm.test(name, callback), where the callback throws if an expectation fails. Here are assertions you will use constantly:
// Check the status code
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// Check response time
pm.test("Response is under 500ms", function () {
pm.expect(pm.response.responseTime).to.be.below(500);
});
// Check a field in the JSON body
pm.test("User has the expected email", function () {
const body = pm.response.json();
pm.expect(body.email).to.eql("maria.chen@example.com");
});
// Check a header
pm.test("Content-Type is JSON", function () {
pm.expect(pm.response.headers.get("Content-Type"))
.to.include("application/json");
});
The assertion syntax comes from Chai, so pm.expect supports .to.eql, .to.include, .to.be.above, and the rest. Click Send and the results show up in the Test Results tab, each test green or red.
A few habits keep tests useful. Name each pm.test block after the behavior it checks, not the endpoint, so a failure message reads like a sentence. Check the things that would actually break a consumer of the API: the status code, the shape of the body, and the fields a client depends on. Avoid asserting on values you do not control, such as a server-generated timestamp, because those produce flaky failures that train people to ignore red. Postman also ships a Snippets panel next to the editor with ready-made assertions you can click to insert, which is the fastest way to learn the pm API. If you want a deeper look at assertion design, see the breakdown of API assertions and how to write them well. For the broader idea of structuring checks into named cases, the API test case example guide is worth reading alongside this.
Use environments and variables
Hardcoding https://api.staging.example.com into every request is painful the moment you need to point at production. Environments solve this. An environment is a named set of variables.
Click the environments icon in the sidebar and create one called “Staging.” Add a variable base_url with the value https://jsonplaceholder.typicode.com. Create a second environment called “Production” with a different base_url. Now reference the variable in your requests using double curly braces:
GET {{base_url}}/users/1
Pick the active environment from the dropdown in the top right, and every request using {{base_url}} switches with it.
Variables also carry data between requests. A login request can capture a token from its response and store it for later requests to use:
pm.test("Save the auth token", function () {
const token = pm.response.json().token;
pm.environment.set("auth_token", token);
});
Any later request can then send Authorization: Bearer {{auth_token}}. This chaining is how you test flows that depend on state, such as creating a resource and then verifying it exists.
Postman has two related variable scopes worth knowing. Environment variables belong to the selected environment and change when you switch environments. Collection variables belong to a collection regardless of environment, which suits values that are constant for that API. There are also global variables, which apply everywhere, and short-lived local variables that exist only for one run. Picking the right scope keeps a value where it belongs and avoids surprises when you switch targets.
Run a whole collection with the Collection Runner
Clicking Send on each request gets old fast. The Collection Runner executes every request in a collection in order, runs all their tests, and gives you a pass/fail summary.
Open a collection, click the Run button (or the three-dot menu, then Run collection). The runner shows your requests in sequence. Choose the environment, set how many iterations to run, and optionally attach a data file. Click Run and Postman fires every request, top to bottom, executing each request’s tests.
The results page lists every assertion across every request, with totals for passed and failed. This is your regression check. Run it after a deploy and you know in seconds whether the API still behaves. The runner also keeps a history of past runs, so you can compare today’s result against yesterday’s and spot when a previously green suite started failing.
Order matters in the runner. Because requests run top to bottom, you can put a login request first so it populates an auth_token, then let every request below it use that token. The same applies to setup and cleanup: create a resource near the start, exercise it in the middle, delete it at the end. A well-ordered collection effectively scripts a full user journey.
For data-driven testing, attach a CSV or JSON file in the runner. Each row becomes one iteration, and you reference columns as variables like {{username}}. This lets one request test dozens of input combinations without duplicating the request. A login endpoint, for instance, can be hit with one row of valid credentials and several rows of bad ones, each row asserting the status code it expects. The article on data-driven API testing with CSV and JSON covers the pattern in detail. To run the same collection in CI without the GUI, Postman provides the Newman command line tool, described in the Newman versus Postman comparison.
Where Postman gets heavy, and what to consider
Postman is excellent for exploratory testing and small-to-medium suites. Two friction points show up as projects grow. First, assertions live in JavaScript, so non-developers and QA folks who prefer a visual approach have a learning curve. Second, Postman keeps API design, testing, mocking, and documentation in separate places, which means your test data and your API contract can drift apart.
Apidog is an all-in-one API platform that addresses both. It imports Postman collections directly, so migration is not a rewrite. Assertions can be built visually without code, while still allowing scripts when you need them. Because design, debugging, mocking, testing, and documentation share one source of truth, your tests stay aligned with the actual API spec. If you are weighing options, the roundup of Postman alternatives for API testing lays out the tradeoffs. You can download Apidog and import an existing collection to compare directly.
None of this means you should drop Postman. It remains a solid choice, especially for quick checks and teams already invested in it. The point is to know where each tool fits.
Frequently asked questions
Do I need to write code to test APIs in Postman?
For sending requests and reading responses, no. For automated assertions, yes, at least a little. Postman’s Tests tab runs JavaScript and uses the pm object. The patterns are simple and you can copy them from Postman’s built-in snippets panel, but it is still JavaScript. If you want a no-code visual assertion builder, a dedicated platform like Apidog handles that.
What is the difference between a Postman collection and an environment?
A collection is a set of requests grouped together, often with their tests. An environment is a named set of variables, like base_url or auth_token. Collections hold what you send. Environments hold the values that change between staging, production, and local. You point one collection at different environments to test the same requests against different servers.
How do I run Postman tests automatically in CI?
Use Newman, Postman’s command line runner. Export your collection and environment, then run newman run collection.json -e environment.json. Newman exits with a non-zero code if any test fails, which is what your CI pipeline checks. The guide on automating API tests in CI/CD walks through wiring this into a pipeline.
Can Postman test more than REST APIs?
Yes. Modern Postman supports GraphQL, gRPC, WebSocket, and SOAP requests in addition to plain HTTP and REST. The Tests tab and assertions work across most of these, though the exact request setup differs per protocol.
How many assertions should one request have?
Enough to confirm the response is correct, not so many that a single change breaks a dozen tests. A common baseline is status code, response time, and the two or three fields that matter for that endpoint. Keep each pm.test block focused on one expectation so a failure tells you exactly what broke.
