Postman Lesson 3 of 6 ⏱️ 4 min read

Variables & Request Chaining

Variable scopes, saving a login token for later requests, and chaining create → read → update → delete flows.

Updated Oct 30, 2026

Variable scopes

Postman resolves {{variable}} from the narrowest scope outwards:

Scope Lives in Use it for Set in scripts with
Local One request run Temporary values pm.variables.set()
Data A data file row Data-driven runs (from CSV/JSON)
Environment Selected environment baseUrl, credentials per server pm.environment.set()
Collection The collection Values shared by all requests pm.collectionVariables.set()
Global The workspace Rarely — avoid pm.globals.set()

If the same name exists in two scopes, the narrower one wins. A good default: environment for per-server settings, collection variables for values passed between requests.

Chaining: login, then use the token

Real APIs require authentication. The pattern: one request logs in and saves the token; every later request uses it.

The example uses DummyJSON (https://dummyjson.com), a free fake API with a working login.

1. Log in and save the token

Http
POST {{baseUrl}}/auth/login
Content-Type: application/json

{
  "username": "emilys",
  "password": "emilyspass"
}

Post-response script:

Javascript
pm.test('Login succeeded', () => {
  pm.response.to.have.status(200);
});

const { accessToken } = pm.response.json();
pm.expect(accessToken, 'access token').to.be.a('string');
pm.collectionVariables.set('accessToken', accessToken);

2. Use the token

Http
GET {{baseUrl}}/auth/me
Authorization: Bearer {{accessToken}}
Javascript
pm.test('Returns the logged-in user', () => {
  pm.response.to.have.status(200);
  pm.expect(pm.response.json().username).to.eql('emilys');
});

Better still, set Authorization → Bearer Token → {{accessToken}} once on the collection, and every request inherits it.

3. Prove authentication is enforced

Http
GET {{baseUrl}}/auth/me
Authorization: Bearer invalid-token
Javascript
pm.test('Rejects an invalid token', () => {
  pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});

Security tests like this catch real vulnerabilities — always include them.

Chaining a CRUD flow

A complete create → read → update → delete flow passes the new resource's ID along. Using DummyJSON's products endpoints:

Javascript
// 1. POST {{baseUrl}}/products/add   body: { "title": "QA Test Product", "price": 49 }
pm.test('Product created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));
pm.collectionVariables.set('productId', pm.response.json().id);
Javascript
// 2. PUT {{baseUrl}}/products/1     body: { "title": "Updated by Postman" }
pm.test('Title updated', () => {
  pm.response.to.have.status(200);
  pm.expect(pm.response.json().title).to.eql('Updated by Postman');
});
Javascript
// 3. DELETE {{baseUrl}}/products/1
pm.test('Product deleted', () => {
  pm.response.to.have.status(200);
  pm.expect(pm.response.json().isDeleted).to.be.true;
});

(DummyJSON simulates writes, so updates and deletes use an existing ID such as 1; against your own API, use {{productId}} from step 1.)

Controlling the run order

The Collection Runner executes requests in order, which makes chains work. You can also branch from a script:

Javascript
// Skip the rest of the flow if login failed
if (pm.response.code !== 200) {
  pm.execution.setNextRequest(null);       // stop the run
}
Javascript
// Jump to a specific request by name
pm.execution.setNextRequest('Get current user');

Use branching sparingly — straightforward, ordered collections are easier to maintain.

Refreshing tokens automatically

For long runs where tokens expire, a collection pre-request script can fetch a new token when needed:

Javascript
const token = pm.collectionVariables.get('accessToken');
const expiresAt = Number(pm.collectionVariables.get('tokenExpiresAt') || 0);

if (!token || Date.now() > expiresAt) {
  pm.sendRequest({
    url: `${pm.environment.get('baseUrl')}/auth/login`,
    method: 'POST',
    header: { 'Content-Type': 'application/json' },
    body: { mode: 'raw', raw: JSON.stringify({ username: 'emilys', password: 'emilyspass', expiresInMins: 30 }) },
  }, (err, res) => {
    if (err) { console.error(err); return; }
    pm.collectionVariables.set('accessToken', res.json().accessToken);
    pm.collectionVariables.set('tokenExpiresAt', Date.now() + 25 * 60 * 1000);
  });
}

Keeping secrets safe

  • Store passwords and tokens in environment variables marked secret.
  • Don't commit environment files with real credentials — pass them from CI secrets (see Newman).
  • Never paste production credentials into shared workspaces.

Next: making sure the response structure never silently changes with Schema & Contract Testing.

Finished this lesson?
Tick it off to track your Postman progress.
Next lesson