On this page7 sections
CommandsIntermediate6-8 min reference

Postman API Testing

A practical reference for the Postman features you'll use across collections, environments, scripting, and CLI runs. All scripting examples use the modern pm.* API.

Collections & Requests

Creating requests

Pick the HTTP method and URL, then optionally configure headers, body, and auth.

GET    https://api.example.com/users
POST   https://api.example.com/users
PUT    https://api.example.com/users/42
PATCH  https://api.example.com/users/42
DELETE https://api.example.com/users/42

Request body types

In the Body tab:

  • raw + JSON / XML / Text / HTML / JavaScript
  • form-data for file uploads (multipart/form-data)
  • x-www-form-urlencoded for HTML form submissions
  • binary for raw file payloads
  • GraphQL with separate Query and Variables panes
{
  "name": "Ada Lovelace",
  "email": "ada@example.com",
  "roles": ["admin", "editor"]
}

Headers and authentication

Add headers under the Headers tab. Common entries:

Content-Type: application/json
Accept: application/json
Authorization: Bearer {{token}}
X-Request-ID: {{$guid}}

The Authorization tab attaches credentials at request time without polluting the headers list — pick Bearer Token, Basic, OAuth 2.0, API Key, etc.

Organizing requests

My API Collection
├── Auth
│   ├── POST Login
│   └── POST Refresh token
├── Users
│   ├── GET List users
│   ├── GET User by ID
│   ├── POST Create user
│   └── DELETE User
└── Orders
    └── ...

Folders inherit auth and pre-request scripts from their parent — define shared logic at the highest level that makes sense.

Variables & Environments

Variable scopes

ScopeSet viaLifetime
Globalpm.globals.set()Across all collections + workspaces
Collectionpm.collectionVariables.set()Within one collection
Environmentpm.environment.set()Within selected environment
DataCSV/JSON in Collection RunnerOne iteration
Localpm.variables.set()Single request

Resolution order (highest precedence first): Local → Data → Environment → Collection → Global.

Setting variables

pm.globals.set("api_version", "v2");
pm.collectionVariables.set("base_url", "https://api.example.com");
pm.environment.set("auth_token", responseToken);
pm.environment.unset("temp_value");
 
const value = pm.environment.get("auth_token");

Using variables

In URLs, headers, and bodies use double curly braces:

{{base_url}}/users/{{user_id}}
Authorization: Bearer {{auth_token}}
{
  "request_id": "{{$guid}}",
  "timestamp": "{{$isoTimestamp}}"
}

Dynamic variables

Built-in generators — refresh on every request:

{{$guid}}                 UUID v4
{{$timestamp}}            Unix timestamp
{{$isoTimestamp}}         ISO 8601 timestamp
{{$randomFirstName}}      random first name
{{$randomLastName}}
{{$randomEmail}}
{{$randomPhoneNumber}}
{{$randomInt}}            int 0–1000
{{$randomUrl}}
{{$randomIP}}

Pre-request Scripts

Sending a chained request

pm.sendRequest({
  url: pm.collectionVariables.get("base_url") + "/auth/token",
  method: "POST",
  header: { "Content-Type": "application/json" },
  body: {
    mode: "raw",
    raw: JSON.stringify({ client_id: "abc", client_secret: "xyz" })
  }
}, (err, res) => {
  if (err) return console.error(err);
  pm.environment.set("auth_token", res.json().access_token);
});

Generating signed timestamps and HMACs

const timestamp = Math.floor(Date.now() / 1000).toString();
const secret = pm.environment.get("api_secret");
const payload = pm.request.method + pm.request.url.toString() + timestamp;
 
const signature = CryptoJS.HmacSHA256(payload, secret).toString(CryptoJS.enc.Hex);
 
pm.request.headers.add({ key: "X-Timestamp", value: timestamp });
pm.request.headers.add({ key: "X-Signature", value: signature });

Conditional skipping

if (!pm.environment.get("auth_token")) {
  console.log("Skipping — no token set");
  postman.setNextRequest(null);
}

Test Scripts (pm.test)

Basic structure

pm.test("Response is 200", () => {
  pm.response.to.have.status(200);
});
 
pm.test("Response time is under 500ms", () => {
  pm.expect(pm.response.responseTime).to.be.below(500);
});

Status codes

pm.response.to.have.status(200);
pm.response.to.be.success;        // 2xx
pm.response.to.be.clientError;    // 4xx
pm.response.to.be.serverError;    // 5xx
pm.response.to.have.status("OK");

Headers

pm.response.to.have.header("Content-Type");
pm.response.to.have.header("Content-Type", "application/json; charset=utf-8");
pm.expect(pm.response.headers.get("X-Rate-Limit")).to.exist;

JSON body assertions

const data = pm.response.json();
 
pm.test("User has expected shape", () => {
  pm.expect(data).to.have.property("id");
  pm.expect(data.name).to.eql("Ada Lovelace");
  pm.expect(data.roles).to.include("admin");
  pm.expect(data.email).to.match(/@example\.com$/);
});
 
pm.test("Items array is non-empty", () => {
  pm.expect(data.items).to.be.an("array").that.is.not.empty;
  pm.expect(data.items).to.have.lengthOf.at.least(1);
});

JSON schema validation

const schema = {
  type: "object",
  required: ["id", "name", "email"],
  properties: {
    id:    { type: "integer" },
    name:  { type: "string" },
    email: { type: "string", format: "email" }
  }
};
 
pm.test("Response matches schema", () => {
  pm.response.to.have.jsonSchema(schema);
});

Storing values for the next request

const data = pm.response.json();
pm.collectionVariables.set("user_id", data.id);
pm.environment.set("auth_token", data.token);

Failing on a condition

pm.test("Inventory is in stock", () => {
  const stock = pm.response.json().stock;
  if (stock <= 0) {
    throw new Error(`Item out of stock: stock=${stock}`);
  }
});

Authentication

Postman attaches credentials from the Authorization tab automatically. Use it instead of hand-rolling headers — it surfaces in tests and Newman runs.

Bearer Token

Type: Bearer Token
Token: {{auth_token}}

Sends Authorization: Bearer {{auth_token}}.

Basic Auth

Type: Basic Auth
Username: {{username}}
Password: {{password}}

Sends Authorization: Basic <base64(user:pass)>.

OAuth 2.0

Configure under Authorization → OAuth 2.0:

  • Grant type: Authorization Code / Client Credentials / Password / etc.
  • Auth URL, Access Token URL
  • Client ID, Client Secret
  • Scope

Click Get New Access Token → token is saved and reused.

API Key

Type: API Key
Key: X-API-Key
Value: {{api_key}}
Add to: Header   (or Query Params)

Digest Auth

Type: Digest Auth
Username: {{user}}
Password: {{pass}}
Realm, Nonce, Algorithm, qop (advanced)

Postman computes the digest hash automatically.

Newman CLI

Newman is the command-line runner for Postman collections.

npm install -g newman
npm install -g newman-reporter-htmlextra   # nicer HTML report

Running a collection

newman run collection.json
newman run https://api.getpostman.com/collections/<id>?apikey=...

With environment

newman run collection.json -e environment.json
newman run collection.json -e env.json -g globals.json

Reporters

newman run collection.json --reporters cli,json,htmlextra
newman run collection.json \
  --reporters htmlextra \
  --reporter-htmlextra-export ./report.html

Data-driven runs (CSV / JSON)

newman run collection.json \
  --iteration-data data.csv \
  --iteration-count 10

data.csv:

username,password
alice,secret1
bob,secret2

In the request use {{username}} and {{password}} — Newman injects one row per iteration.

Throttling and timeouts

newman run collection.json --delay-request 500     # 500ms between requests
newman run collection.json --timeout-request 30000
newman run collection.json --bail                  # stop on first failure

CI/CD exit codes

Newman exits non-zero on test failures. In any CI:

newman run collection.json -e env.json \
  --reporters cli,junit \
  --reporter-junit-export results.xml

GitHub Actions example:

- name: API tests
  run: |
    newman run postman/collection.json \
      -e postman/staging.json \
      --reporters cli,junit \
      --reporter-junit-export newman-results.xml
- uses: actions/upload-artifact@v4
  with:
    name: newman-results
    path: newman-results.xml

Collection Runner

The Postman GUI Collection Runner mirrors Newman with a visual interface.

Data files

Pick a CSV or JSON file under Data. Variables bind by column name (CSV) or property name (JSON).

[
  { "username": "alice", "expected_status": 200 },
  { "username": "missing-user", "expected_status": 404 }
]

Tests can read iteration variables directly:

pm.test(`Status matches expected for ${pm.iterationData.get("username")}`, () => {
  pm.response.to.have.status(pm.iterationData.get("expected_status"));
});

Workflow control

Branch through the run with setNextRequest:

if (pm.response.code === 401) {
  postman.setNextRequest("Refresh token");
} else if (pm.response.code >= 500) {
  postman.setNextRequest(null);   // halt the run
} else {
  // continue in collection order
}

Run summary

After a run, expand each iteration to see request/response, console output, and assertion pass/fail. Export results as JSON for offline analysis or as a Postman Cloud share link.