Postman Variables and Collections: Complete Guide
Variables are what make a Postman collection reusable: the same requests run against Dev, QA and Staging, tokens flow from one request to the next, and every run can create unique test data. This guide explains environments, each variable scope, which scope wins when names clash (verified by running a collection with Newman), how to keep secrets safe, and how to organize and run collections.
Environments
An environment is a named set of variables for one target system — Dev, QA, Staging. The requests stay the same; you switch the environment in the top-right selector (or pass it to Newman), and {{baseUrl}} resolves to a different server.
| Variable | QA environment | Staging environment |
|---|---|---|
baseUrl |
https://qa.api.example.com | https://staging.api.example.com |
username |
qa_admin | stg_admin |
password (secret) |
•••••• | •••••• |
Requests then use GET {{baseUrl}}/users/{{userId}} — never a hard-coded host. Postman's naming is flexible, but pick one convention (baseUrl or base_url) and use it everywhere.
The Variable Scopes
| Scope | Available to | Typical use | Set in a script |
|---|---|---|---|
| Global | Every collection in the workspace | Rarely — a few truly shared values | pm.globals.set() |
| Collection | Requests in one collection | Values created during a run (tokens, IDs), collection defaults | pm.collectionVariables.set() |
| Environment | Whatever uses the selected environment | Per-environment settings: base URL, credentials | pm.environment.set() |
| Data | One iteration of a data-driven run | A row from a CSV/JSON file | Read-only: pm.iterationData.get() |
| Local | The current run only — never saved | Temporary overrides and calculated values | pm.variables.set() |
pm.variables.get('name') reads a variable from whichever scope wins, which is usually what scripts should use.
Which Scope Wins? ⭐
When the same name exists in several scopes, the narrowest scope wins:
Local > Data > Environment > Collection > Global
We verified this by defining level in every scope and running the collection with Newman:
| Run | {{level}} resolved to |
|---|---|
| Global + collection + environment | environment |
… plus a data file (-d level.csv) |
data |
… after pm.variables.set('level', 'local') |
local |
Two details from the same run worth knowing: names defined in only one scope still resolve normally (onlyGlobal and onlyCollection both worked), and a local variable set in one request was still visible in the next request of the same run — it disappears when the run ends, it isn't limited to one request. So don't rely on local variables "resetting" between requests.
Why it matters: a stale global or collection variable with the same name as an environment variable is invisible while the environment is selected — then suddenly used when someone runs without one. Avoid duplicate names across scopes.
Initial Value vs Current Value, and Secrets
- Initial value — saved with the environment or collection and shared with anyone you share it with (and exported to JSON).
- Current value — used when requests run; kept locally and not shared by default. Values set by scripts update the current value.
- Secret type — masks the value on screen. Still keep real passwords and tokens out of initial values, out of exported files committed to Git, and in CI pass them at run time (
--env-var "password=$API_PASSWORD") or through your CI's credential store.
Setting Variables From Scripts
// Tests tab of the Login request — store the token for the rest of the collection
pm.collectionVariables.set('token', pm.response.json().token);
// Store per-environment state
pm.environment.set('lastOrderId', pm.response.json().orderId);
// Read whichever scope wins
const base = pm.variables.get('baseUrl');
// Clean up at the end of a run
pm.collectionVariables.unset('token');
With Newman, --export-environment qa.after.json saves the environment after the run — in our test it contained the token set by a script. More scripting: Postman Scripting & Assertions.
Dynamic Variables
| Variable | Generates |
|---|---|
{{$guid}} / {{$randomUUID}} |
A UUID |
{{$timestamp}} |
Current Unix time in seconds |
{{$isoTimestamp}} |
Current ISO-8601 date-time |
{{$randomInt}} |
An integer from 0 to 1000 |
{{$randomEmail}}, {{$randomFirstName}}, {{$randomCity}} |
Realistic fake data |
{ "email": "{{$randomEmail}}", "firstName": "{{$randomFirstName}}", "ref": "{{$guid}}" }
Use them for data that must be unique (registration emails, order references). For values you need to assert later, generate them in a pre-request script and store them, so the test knows what it sent:
pm.variables.set('email', `qa_${Date.now()}@example.com`)
Organizing Collections
Shop API (collection)
├── Auth → Login, Refresh token
├── Users → Create, Get, Update, Delete
├── Orders → Create, Get, Cancel
└── Negative → Invalid JSON, No token, Unknown ID
- One collection per API or product; folders per resource or flow.
- Put authentication in a collection-level pre-request script and common checks (status, response time, JSON content type) in collection-level tests.
- Name requests by intent ("Create user — missing email"), and add descriptions — collections double as documentation.
- Keep collections in version control (export JSON, or Postman's Git integration) so changes are reviewed.
Running Collections
| Option | Use |
|---|---|
| Collection Runner | Run in Postman, optionally with a CSV/JSON data file and several iterations |
| Newman | Run from the command line and in CI |
| Postman Monitors | Scheduled runs from Postman's cloud with alerts |
newman run shop-api.json \
-e qa.postman_environment.json \
--env-var "password=$API_PASSWORD" \
-d users.csv \
-r cli,junit,htmlextra
Full CI setup: Postman Newman CI/CD. Chaining and data-driven examples: Postman API Chaining. Plan which requests and checks a collection needs in the API Testing Scenario Lab.
From Real Projects
I've worked with APIs at the level this page covers: CRUD operations, HTTP methods, JSON and XML formats, and extracting and validating values with JSON path. A good habit from that work: test the full create–read–update–delete cycle for a resource and check each response in detail. Testsigma supports web, mobile and API test automation, so understanding APIs was part of understanding the product I was testing. Separate environments for QA and staging prevent many accidental mistakes.
📚 Official documentation: Postman Learning Center
FAQs
What is an environment in Postman?
A named set of variables for one target system (Dev, QA, Staging), so the same requests can run against any of them.
Global vs environment vs collection variables?
Global: the whole workspace. Environment: the selected environment. Collection: one collection. Use environments for per-system settings and collection variables for values created during a run.
Which variable scope has the highest priority?
Local, then data, environment, collection and global — the narrowest scope wins.
What's the difference between initial and current values?
Initial values are saved and shared; current values are used at run time and stay local by default. Keep secrets out of initial values.
What are dynamic variables?
Built-in generators such as {{$guid}}, {{$timestamp}} and {{$randomEmail}} that produce a new value for every request.
How do you pass a secret to Newman?
At run time with --env-var "password=$API_PASSWORD", taking the value from your CI's credential store.