
Postman Complete Guide: API Testing from Beginner to Advanced
Postman has evolved from a simple Chrome extension for sending HTTP requests into a comprehensive API development and testing platform. Whether you're exploring a new API, building automated test suites, or collaborating with a team on API design, Postman provides tools that make the process intuitive and efficient.
Quick Answer: Postman is a free API testing platform that lets you send HTTP requests (GET, POST, PUT, PATCH, DELETE), write automated tests in JavaScript, organize requests into collections, manage environment variables, and run test suites in CI/CD pipelines using Newman CLI. It supports REST, SOAP, and GraphQL APIs with built-in authentication, mock servers, monitoring, and team collaboration features.
This guide covers everything from basic request building to advanced automation techniques that transform Postman from a debugging tool into a full testing solution.
Table Of Contents-
- What is Postman?
- Why Use Postman?
- Getting Started
- Making Requests
- Collections and Organization
- Variables and Environments
- Writing Tests
- Pre-request Scripts
- Data-Driven Testing
- Running Collections
- Mock Servers
- API Documentation
- Monitoring APIs
- Debugging with Postman Console
- Troubleshooting Common Issues
- Best Practices
- Team Collaboration
What is Postman?
Postman is an API platform for building, testing, and documenting APIs. It's used by millions of developers worldwide for:
- API Exploration: Send requests and inspect responses interactively
- Automated Testing: Write and run API tests with JavaScript
- Documentation: Generate API docs from collections
- Mocking: Create mock servers for API prototyping
- Collaboration: Share collections, environments, and work together
Versions:
- Postman App: Desktop application (Windows, macOS, Linux)
- Postman Web: Browser-based version with most features
- Free Tier: Generous limits for individual and small team use
Why Use Postman?
Postman stands out among API testing tools for several practical reasons:
- Low Learning Curve: The visual interface lets you send your first API request within minutes, with no coding required
- All-in-One Platform: Test, document, mock, and monitor APIs from a single tool instead of juggling multiple utilities
- Free and Accessible: The free tier is generous enough for most individual developers and small teams
- Language Agnostic: Test any REST, SOAP, or GraphQL API regardless of the backend technology
- Built-in Automation: Write JavaScript tests and chain requests without external frameworks
- CI/CD Ready: Newman CLI integrates directly into build pipelines for automated regression testing
- Team Collaboration: Share collections, environments, and documentation with your team in real time
- Extensive Ecosystem: Thousands of pre-built public APIs, templates, and integrations available in the Postman API Network
Postman is particularly valuable for QA engineers transitioning from manual to automated API testing, developers debugging API integrations, and teams that need a shared workspace for API development.
Getting Started
Installation
Download from postman.com (opens in a new tab) and install. Create a free account to sync collections across devices and access team features.
Interface Overview
┌─────────────────────────────────────────────────────────────┐
│ Sidebar │ Request Builder │
│ ───────── │ ────────────── │
│ • Collections │ [GET ▼] [URL ][Send]│
│ • Environments │ │
│ • History │ Params | Auth | Headers | Body │
│ • APIs │ ───────────────────────── │
│ │ [Parameter input area] │
│ │ │
│ │ ═══════════════════════════════ │
│ │ Response │
│ │ Body | Headers | Test Results │
│ │ ───────────────────────── │
│ │ [Response content] │
└─────────────────────────────────────────────────────────────┘Making Requests
Basic GET Request
- Enter the URL:
https://jsonplaceholder.typicode.com/users/1 - Ensure method is
GET - Click Send
The response appears below with:
- Status code and time
- Response headers
- Response body (formatted JSON)
POST Request with JSON Body
- Change method to
POST - Enter URL:
https://jsonplaceholder.typicode.com/users - Click Body tab
- Select raw and JSON
- Enter JSON:
{
"name": "John Doe",
"email": "john@example.com",
"username": "johndoe"
}- Click Send
PUT Request (Full Update)
PUT replaces the entire resource with new data:
- Change method to
PUT - Enter URL:
https://jsonplaceholder.typicode.com/users/1 - Add JSON body:
{
"name": "Jane Doe",
"email": "jane@example.com",
"username": "janedoe"
}- Click Send — expect a
200 OKresponse
PATCH Request (Partial Update)
PATCH updates only the specified fields:
- Change method to
PATCH - Enter URL:
https://jsonplaceholder.typicode.com/users/1 - Add JSON body with only the fields to update:
{
"email": "newemail@example.com"
}- Click Send — the response shows the updated resource with unchanged fields preserved
DELETE Request
- Change method to
DELETE - Enter URL:
https://jsonplaceholder.typicode.com/users/1 - Click Send — expect a
200 OKor204 No Contentresponse
Use PUT when you need to replace an entire resource. Use PATCH when you only want to update specific fields. This distinction matters for writing accurate API tests.
Request Components
Query Parameters: Use the Params tab or add directly to URL:
https://api.example.com/users?page=2&limit=10Headers:
Content-Type: application/json
Authorization: Bearer your-token-here
Accept: application/jsonPath Variables:
https://api.example.com/users/:userId/posts/:postIdPostman prompts for values when you use :variableName syntax.
Authentication
Postman's Auth tab supports multiple types:
| Type | Use Case |
|---|---|
| No Auth | Public APIs |
| API Key | Key in header or query param |
| Bearer Token | OAuth 2.0 access tokens |
| Basic Auth | Username/password |
| OAuth 2.0 | Full OAuth flow with token refresh |
Setting authentication at the collection level automatically applies it to all requests within that collection, reducing repetition.
Collections and Organization
Collections are folders for organizing related requests.
Creating a Collection
- Click New → Collection
- Name it (e.g., "User API Tests")
- Add description (supports Markdown)
- Configure collection-level settings:
- Variables
- Authorization
- Pre-request scripts
- Tests
Organizing Requests
Structure collections logically:
User API Tests/
├── Authentication/
│ ├── Login
│ ├── Logout
│ └── Refresh Token
├── Users/
│ ├── List Users
│ ├── Get User by ID
│ ├── Create User
│ ├── Update User
│ └── Delete User
└── User Preferences/
├── Get Preferences
└── Update PreferencesSaving Requests
- Build your request
- Click Save
- Choose collection and folder
- Name the request descriptively
Naming conventions:
GET List Users- Action + ResourcePOST Create Order- Method + OperationDELETE Remove Item from Cart- Descriptive action
Variables and Environments
Variables make collections portable and maintainable.
Variable Scopes
Global → Collection → Environment → Local
(Lowest priority) (Highest priority)| Scope | Use Case |
|---|---|
| Global | Values used everywhere |
| Collection | Collection-specific values |
| Environment | Environment-specific (dev/staging/prod) |
| Local | Request-specific, temporary values |
Creating Environments
- Click Environments in sidebar
- Click + to create new
- Add variables:
Development Environment:
baseUrl: https://dev-api.example.com
apiKey: dev-key-12345
Production Environment:
baseUrl: https://api.example.com
apiKey: prod-key-67890Using Variables
Reference variables with double curly braces:
URL: {{baseUrl}}/users
Header: Authorization: Bearer {{apiKey}}
Body: {"email": "{{testEmail}}"}Setting Variables in Scripts
// Set environment variable
pm.environment.set('userId', 123)
// Set collection variable
pm.collectionVariables.set('authToken', 'abc123')
// Set global variable
pm.globals.set('timestamp', Date.now())
// Get variable value
const baseUrl = pm.environment.get('baseUrl')Writing Tests
Tests verify API responses automatically. Write them in the Tests tab using JavaScript.
Basic Test Structure
pm.test('Status code is 200', function () {
pm.response.to.have.status(200)
})
pm.test('Response time is less than 500ms', function () {
pm.expect(pm.response.responseTime).to.be.below(500)
})
pm.test('Content-Type is JSON', function () {
pm.response.to.have.header('Content-Type', 'application/json; charset=utf-8')
})Response Body Tests
// Parse JSON response
const response = pm.response.json()
pm.test('User name is correct', function () {
pm.expect(response.name).to.eql('John Doe')
})
pm.test('Email contains @', function () {
pm.expect(response.email).to.include('@')
})
pm.test('User has required fields', function () {
pm.expect(response).to.have.property('id')
pm.expect(response).to.have.property('name')
pm.expect(response).to.have.property('email')
})
pm.test('Returns array of users', function () {
pm.expect(response).to.be.an('array')
pm.expect(response.length).to.be.above(0)
})Schema Validation
const schema = {
type: 'object',
required: ['id', 'name', 'email'],
properties: {
id: { type: 'number' },
name: { type: 'string' },
email: { type: 'string', format: 'email' },
},
}
pm.test('Response matches schema', function () {
pm.expect(tv4.validate(pm.response.json(), schema)).to.be.true
})
// Or using ajv (more modern)
const Ajv = require('ajv')
const ajv = new Ajv()
const validate = ajv.compile(schema)
pm.test('Schema validation', function () {
pm.expect(validate(pm.response.json())).to.be.true
})Chaining Requests
Extract values from responses to use in subsequent requests:
// In first request's Tests tab
const response = pm.response.json()
// Save token for next request
pm.environment.set('authToken', response.token)
// Save created user ID
pm.environment.set('userId', response.id)// In second request, use the variable
// Header: Authorization: Bearer {{authToken}}
// URL: {{baseUrl}}/users/{{userId}}Pre-request Scripts
Execute JavaScript before the request is sent.
Dynamic Data Generation
// Generate random email
const randomEmail = `user${Date.now()}@test.com`
pm.environment.set('testEmail', randomEmail)
// Generate UUID
const uuid = require('uuid')
pm.environment.set('requestId', uuid.v4())
// Set timestamp
pm.environment.set('timestamp', new Date().toISOString())
// Random number in range
const randomId = Math.floor(Math.random() * 100) + 1
pm.environment.set('randomUserId', randomId)Authentication Token Refresh
// Check if token is expired
const tokenExpiry = pm.environment.get('tokenExpiry')
const now = Date.now()
if (!tokenExpiry || now > tokenExpiry) {
// Token expired, refresh it
const refreshToken = pm.environment.get('refreshToken')
pm.sendRequest(
{
url: pm.environment.get('baseUrl') + '/auth/refresh',
method: 'POST',
header: {
'Content-Type': 'application/json',
},
body: {
mode: 'raw',
raw: JSON.stringify({ refreshToken }),
},
},
function (err, response) {
const data = response.json()
pm.environment.set('authToken', data.accessToken)
pm.environment.set('tokenExpiry', now + data.expiresIn * 1000)
},
)
}Compute Signatures
// HMAC signature for API authentication
const crypto = require('crypto-js')
const timestamp = Date.now().toString()
const requestBody = pm.request.body ? pm.request.body.raw : ''
const message = timestamp + requestBody
const secret = pm.environment.get('apiSecret')
const signature = crypto.HmacSHA256(message, secret).toString()
pm.environment.set('timestamp', timestamp)
pm.environment.set('signature', signature)Data-Driven Testing
Run the same requests with different data using CSV or JSON files.
CSV Data File
Create testdata.csv:
username,email,expectedStatus
validuser,valid@test.com,201
invaliduser,,400
duplicate,existing@test.com,409JSON Data File
Create testdata.json:
[
{ "username": "validuser", "email": "valid@test.com", "expectedStatus": 201 },
{ "username": "invaliduser", "email": "", "expectedStatus": 400 },
{
"username": "duplicate",
"email": "existing@test.com",
"expectedStatus": 409
}
]Using Data in Requests
Body:
{
"username": "{{username}}",
"email": "{{email}}"
}
Tests:
pm.test("Status matches expected", function () {
pm.expect(pm.response.code).to.eql(pm.iterationData.get("expectedStatus"));
});Running with Data
- Click Run on the collection
- Select data file (CSV or JSON)
- Set iterations (or leave auto to match data rows)
- Click Run
Running Collections
Collection Runner
- Click Run button on collection
- Configure:
- Environment
- Iterations
- Delay between requests
- Data file
- Click Run [Collection Name]
Newman (CLI Runner)
Newman runs Postman collections from the command line - essential for CI/CD:
# Install Newman
npm install -g newman
# Run a collection
newman run collection.json
# With environment
newman run collection.json -e environment.json
# With data file
newman run collection.json -d testdata.csv
# With reporters
newman run collection.json -r cli,html --reporter-html-export report.html
# CI-friendly options
newman run collection.json \
--environment production.json \
--iteration-count 1 \
--bail \
--reporters cli,junit \
--reporter-junit-export results.xml⚠️
Export collections and environments as JSON files for Newman. Use Export from the collection menu in Postman.
CI/CD Integration
GitHub Actions example:
name: API Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Newman
run: npm install -g newman newman-reporter-htmlextra
- name: Run API Tests
run: |
newman run tests/collection.json \
-e tests/environment.json \
--reporters cli,htmlextra \
--reporter-htmlextra-export report.html
- name: Upload Report
uses: actions/upload-artifact@v3
with:
name: api-test-report
path: report.htmlMock Servers
Mock servers simulate API responses before the backend is built, enabling parallel frontend and backend development.
Creating a Mock Server
- Select a collection with saved examples
- Click Mock Collection from the collection menu
- Name the mock and configure settings
- Postman generates a mock URL:
https://mock-id.mock.pstmn.io
Adding Examples for Mocking
For each request, create examples that define the mock response:
- Open a request in the collection
- Click Add Example
- Set the response status code, headers, and body
- Save the example
// Example: GET /users returns mock data
{
"users": [
{ "id": 1, "name": "Mock User", "email": "mock@test.com" }
]
}Mock Server Use Cases
- Frontend development while the API is still being built
- Test isolation — run tests against predictable responses without relying on a live server
- API prototyping — validate design decisions before writing backend code
- Demo environments — showcase API behavior to stakeholders
API Documentation
Postman generates interactive API documentation directly from your collections.
Publishing Documentation
- Open the collection
- Click View Documentation or select Publish Docs from the menu
- Add descriptions to requests, parameters, and responses
- Choose visibility: Private (team only) or Public (anyone with the link)
Writing Effective Descriptions
Use Markdown in descriptions at every level:
- Collection level: API overview, authentication requirements, base URLs
- Folder level: Resource group descriptions
- Request level: What the endpoint does, required parameters, example use cases
- Parameter level: Data types, constraints, default values
Well-documented collections double as both test suites and API reference guides, reducing duplicate effort.
Monitoring APIs
Monitors run collections on a schedule to track API health and performance over time.
Setting Up a Monitor
- Select a collection
- Click Monitor Collection
- Configure:
- Frequency: Every 5 minutes to weekly
- Environment: Which environment to run against
- Regions: Run from multiple geographic locations
- Notifications: Email or Slack alerts on failures
What Monitors Track
- Uptime: Whether endpoints respond successfully
- Response time: Performance trends over time
- Test results: Whether assertions in your collection still pass
- Regression detection: Catch breaking changes before users report them
Monitors are particularly useful for production health checks, SLA verification, and early detection of performance degradation.
Debugging with Postman Console
The Postman Console is essential for troubleshooting scripts and request issues.
Opening the Console
Click Console at the bottom of the Postman window or use Cmd/Ctrl + Alt + C.
Console Logging
Add log statements to pre-request or test scripts:
// Log variable values
console.log('Base URL:', pm.environment.get('baseUrl'))
console.log('Auth Token:', pm.environment.get('authToken'))
// Log request details
console.log('Request URL:', pm.request.url.toString())
console.log('Request Headers:', JSON.stringify(pm.request.headers))
// Log response data
console.log('Response Status:', pm.response.code)
console.log('Response Body:', pm.response.text())
// Debug complex logic
const data = pm.response.json()
console.log('User count:', data.length)
console.log('First user:', JSON.stringify(data[0], null, 2))Common Debugging Scenarios
| Issue | Debugging Approach |
|---|---|
| Variable not resolving | Log pm.environment.get('varName') to check the value |
| Test failing unexpectedly | Log the response body to see actual data |
| Pre-request script error | Check Console for JavaScript errors |
| Auth not working | Log the Authorization header to verify the token |
| Wrong URL | Log pm.request.url.toString() to check the resolved URL |
Troubleshooting Common Issues
401 Unauthorized or 403 Forbidden
- Verify the API key or token is correct and not expired
- Check that the Authorization header is properly formatted
- Ensure you selected the right environment with valid credentials
- Look for token expiry — use a pre-request script to refresh automatically
400 Bad Request
- Validate your JSON body syntax (no trailing commas, proper quoting)
- Confirm required fields are included in the request body
- Check Content-Type header matches the body format
- Verify parameter names match the API specification exactly
Variables Not Resolving
- Confirm the correct environment is selected (top-right dropdown)
- Check variable scope — environment variables override collection variables
- Look for typos in variable names (case-sensitive)
- Verify the variable was set before the request runs (check execution order)
CORS Errors
- CORS restrictions apply to the web version of Postman, not the desktop app
- Switch to the desktop application to bypass browser CORS policies
- If testing locally, configure your API server to allow the Postman origin
SSL Certificate Errors
- For self-signed certificates, disable SSL certificate verification in Settings
- This is acceptable for development and testing but should never be disabled for production API monitoring
Tests Pass Locally but Fail in Newman
- Ensure the exported environment file contains current variable values
- Check that data files (CSV/JSON) are accessible from the Newman working directory
- Verify Newman version compatibility with your collection format
- Use
--verboseflag to see detailed request/response logs
Best Practices
Organize Collections by Feature
Group requests by API resource or user workflow rather than HTTP method. A "User Management" folder with Create, Read, Update, and Delete requests is more useful than grouping all POST requests together.
Use Descriptive Request Names
Name requests by their purpose, not just the endpoint:
- Good: "Create New User with Valid Data", "Get User by ID"
- Avoid: "POST /users", "GET /users/1"
Keep Environments Clean
- Store only environment-specific values (URLs, API keys) in environments
- Use collection variables for values shared across environments
- Never commit environment files with real production credentials to version control
Write Independent Tests
Each test assertion should verify one thing. If a test fails, the name should tell you exactly what went wrong:
// Good - specific, independent tests
pm.test('Status code is 200', () => pm.response.to.have.status(200))
pm.test('Response contains user ID', () => pm.expect(pm.response.json().id).to.exist)
pm.test('Response time under 500ms', () => pm.expect(pm.response.responseTime).to.be.below(500))
// Avoid - one test checking multiple things
pm.test('Everything works', () => {
pm.response.to.have.status(200)
pm.expect(pm.response.json().id).to.exist
pm.expect(pm.response.responseTime).to.be.below(500)
})Version Control Your Collections
Export collections and environments as JSON files and commit them to your Git repository. This provides:
- Change tracking — see who modified what and when
- Code review — review API test changes alongside code changes
- Backup — recover from accidental deletions or overwrites
- CI/CD integration — Newman can run directly from your repository
Validate Both Positive and Negative Scenarios
Test not just the happy path but also error cases:
- Missing required fields
- Invalid data types
- Unauthorized access
- Rate limiting behavior
- Boundary values (empty strings, maximum lengths, special characters)
Team Collaboration
Workspaces
Workspaces organize work and control access:
| Type | Visibility |
|---|---|
| Personal | Only you |
| Private | Invited members |
| Team | All team members |
| Public | Anyone on internet |
Sharing Collections
- Move collection to shared workspace, or
- Use Share button to generate link
- Export as JSON for version control
Version Control Best Practices
project/
├── postman/
│ ├── collections/
│ │ └── api-tests.json
│ ├── environments/
│ │ ├── development.json
│ │ ├── staging.json
│ │ └── production.json
│ └── data/
│ └── testdata.csv
├── .github/
│ └── workflows/
│ └── api-tests.yml
└── README.mdAPI Versioning Strategy
- Maintain separate collections per API version
- Use environment variables for version numbers
- Document breaking changes in collection descriptions
Postman bridges the gap between manual API exploration and automated testing. By mastering collections, environments, and scripting, you can build comprehensive test suites that run locally during development and automatically in CI/CD pipelines.
Quiz on Postman
Your Score: 0/15
Question: What is the correct syntax for referencing a variable in Postman?
Continue Reading
Frequently Asked Questions (FAQs) / People Also Ask (PAA)
Is Postman free to use?
Can I use Postman for automated testing in CI/CD?
How do I share collections with my team?
What's the difference between environment and collection variables?
Can Postman generate API documentation?
How do I handle authentication that requires tokens from another request?
What libraries are available in Postman scripts?
Can I import API specs from Swagger/OpenAPI?
What is Newman in Postman?
How do I debug Postman scripts?
Can Postman test GraphQL APIs?
How do I create a mock server in Postman?
What is the difference between PUT and PATCH in Postman?
How do I run the same Postman test with different data?
What are Postman monitors?
How do I set up Postman for team collaboration?