Variable scopes in Postman (global, collection, environment, local) and when to use each
Variables let you reuse values across requests so you don’t hard-code base URLs, tokens, IDs, or test data. In Postman, the same variable name can exist in multiple scopes; Postman resolves the value by precedence (more specific scopes override broader ones). The practical takeaway: store a value in the narrowest scope that still fits your use case.
Global variables
Use for: quick experiments or values you truly want available everywhere (rare in team workflows). Avoid for: secrets and anything environment-specific, because globals can accidentally affect unrelated collections.
- Example: a temporary
debug_modeflag used across multiple collections on your machine.
Collection variables
Use for: values shared by all requests in a single collection, regardless of environment. This is ideal for stable defaults and reusable configuration that travels with the collection.
- Examples:
api_version,default_page_size,resource_path.
Environment variables
Use for: values that change between environments (dev/stage/prod) or per user. This is the best place for baseUrl, credentials, and tokens (often set at runtime).
- Examples:
baseUrl,auth_token,tenantId.
Local variables
Use for: temporary values within a single request execution (pre-request/test scripts). Local variables are not persisted and won’t leak into other requests.
Continue in our app.
You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.
Or continue reading below...Download the app
- Examples: computed timestamps, one-off payload values, intermediate parsing results.
Best-practice scope selection
- Put base URLs and credentials in environments.
- Put collection-wide constants in collection variables.
- Use locals for computed values you don’t want to persist.
- Avoid globals in shared/team setups unless you have a specific reason.
Setting and reading variables in requests (URL, headers, body)
Postman replaces variables using double curly braces: {{variableName}}. You can reference variables in the request URL, query parameters, headers, and body.
Reading variables in the URL and query parameters
Example URL using an environment variable for the host and a stored ID:
{{baseUrl}}/users/{{user_id}}Example query parameter using a collection variable:
{{baseUrl}}/users?pageSize={{default_page_size}}Reading variables in headers
Example Authorization header using a token stored in an environment variable:
Authorization: Bearer {{auth_token}}Example content type header using a constant:
Content-Type: application/jsonReading variables in JSON bodies
Example request body that reuses variables and dynamic values:
{ "email": "{{user_email}}", "name": "{{user_name}}" }Setting variables via scripts (pre-request and tests)
When you need to compute or update a value, set it in a script. Choose the scope deliberately.
- Environment:
pm.environment.set("auth_token", token) - Collection:
pm.collectionVariables.set("api_version", "v1") - Global:
pm.globals.set("debug_mode", "true") - Local:
pm.variables.set("requestStart", Date.now())
Reading values in scripts:
const baseUrl = pm.environment.get("baseUrl"); const userId = pm.collectionVariables.get("user_id"); const token = pm.environment.get("auth_token"); const temp = pm.variables.get("requestStart");Tip: Prefer pm.collectionVariables over pm.variables when you want persistence across requests in the collection. Use pm.variables for temporary values that should not persist.
Capturing values from responses (IDs, tokens) and storing them for later steps
A common API workflow is: create a resource (POST), capture its ID from the response, then use that ID in subsequent GET/PUT/DELETE requests. This eliminates manual copy/paste and makes your collection runnable end-to-end.
Step-by-step: capture an ID from a POST response
Scenario: Your POST /users returns JSON like:
{ "id": "9f2c1a", "email": "someone@example.com", "name": "Someone" }In the POST request’s Tests tab, parse the response and store the ID:
pm.test("Create user: status 201", function () { pm.response.to.have.status(201); }); const json = pm.response.json(); pm.test("Create user: has id", function () { pm.expect(json).to.have.property("id"); }); pm.collectionVariables.set("user_id", json.id);Why collection variables here? The ID is needed by multiple requests in the same collection run, and it’s not environment-specific.
Capturing tokens from a login response
If a login endpoint returns a token, store it in the environment so it can be used by all authenticated requests in that environment:
const json = pm.response.json(); pm.environment.set("auth_token", json.token);If the token is nested, extract it via the correct path:
pm.environment.set("auth_token", json.data.accessToken);Using captured values in follow-up requests
Once stored, reference the variable in subsequent requests:
- GET user:
{{baseUrl}}/users/{{user_id}} - PUT user:
{{baseUrl}}/users/{{user_id}} - DELETE user:
{{baseUrl}}/users/{{user_id}}
In headers for all those requests:
Authorization: Bearer {{auth_token}}Exercise: create, reuse ID, then update and delete
Goal: Build a 4-request sequence that can run without manual edits.
- Request 1: POST Create User
- URL:
{{baseUrl}}/users - Body (example):
{ "email": "{{randomEmail}}", "name": "{{randomName}}" } - Tests: store
user_idfrom response in a collection variable.
- URL:
- Request 2: GET User
- URL:
{{baseUrl}}/users/{{user_id}} - Test: assert the returned
idmatches{{user_id}}by comparing to the stored variable in script:const json = pm.response.json(); pm.expect(json.id).to.eql(pm.collectionVariables.get("user_id"));
- URL:
- Request 3: PUT Update User
- URL:
{{baseUrl}}/users/{{user_id}} - Body:
{ "name": "{{randomName}}" } - Test: assert the updated field changed (based on response contract).
- URL:
- Request 4: DELETE User
- URL:
{{baseUrl}}/users/{{user_id}} - Test: assert success status (commonly 200/204).
- URL:
Optional cleanup step: In the DELETE request’s Tests, unset the ID so reruns don’t accidentally reuse a stale value:
pm.collectionVariables.unset("user_id");Using dynamic variables for randomized data and timestamps
Dynamic variables help you generate unique or time-based values without writing custom code. They are especially useful for avoiding collisions when creating resources (unique emails, usernames) and for timestamp fields.
Common dynamic variables
{{$randomUUID}}for unique identifiers.{{$timestamp}}for Unix timestamp (seconds).{{$isoTimestamp}}for ISO 8601 time strings.{{$randomInt}}for numeric variation.{{$randomEmail}},{{$randomFirstName}},{{$randomLastName}}for realistic test data.
Using dynamic variables directly in a request
Example JSON body:
{ "externalRef": "{{$randomUUID}}", "email": "{{$randomEmail}}", "createdAt": "{{$isoTimestamp}}" }Freezing a dynamic value for reuse across multiple requests
Dynamic variables re-evaluate each time they’re used. If you need the same generated value across multiple requests (for example, create a user then search by the same email), generate it once and store it.
In a pre-request script (for the first request in the flow):
const email = `${pm.variables.replaceIn("{{$randomFirstName}}")}.${pm.variables.replaceIn("{{$randomLastName}}")}.${pm.variables.replaceIn("{{$timestamp}}")}@example.test`.toLowerCase(); pm.collectionVariables.set("user_email", email); const name = pm.variables.replaceIn("{{$randomFirstName}}") + " " + pm.variables.replaceIn("{{$randomLastName}}" ); pm.collectionVariables.set("user_name", name);Then use {{user_email}} and {{user_name}} in the body of POST and later requests.
Preventing variable collisions with naming conventions
As collections grow, collisions happen when multiple requests store different meanings under the same variable name (for example, id or token). Collisions cause flaky runs because later requests may read the wrong value.
Naming conventions that scale
- Prefix by domain/resource:
user_id,order_id,invoice_idinstead ofid. - Prefix by purpose:
auth_token,refresh_token,csrf_token. - Prefix by scope (optional but helpful):
env_baseUrl,col_user_id. Use this when teams frequently mix scopes. - Use consistent casing: pick
snake_caseorcamelCaseand stick to it. - Separate “input” vs “captured” values:
user_email_input(what you send) vsuser_id_captured(what you store from response) when debugging complex flows.
Collision-avoidance workflow tips
- Store IDs captured from responses at the collection scope unless they are truly environment-specific.
- Store tokens at the environment scope, and refresh them in a single dedicated request to avoid multiple requests overwriting them unexpectedly.
- Unset variables during teardown steps (for example after DELETE) to reduce accidental reuse.
- When troubleshooting, add a temporary test that prints key variables to the Postman Console by logging them from scripts.
console.log("user_id", pm.collectionVariables.get("user_id")); console.log("auth_token", pm.environment.get("auth_token"));