Variables & Request Chaining
Variable scopes, saving a login token for later requests, and chaining create → read → update → delete flows.
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
POST {{baseUrl}}/auth/login
Content-Type: application/json
{
"username": "emilys",
"password": "emilyspass"
}
Post-response script:
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
GET {{baseUrl}}/auth/me
Authorization: Bearer {{accessToken}}
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
GET {{baseUrl}}/auth/me
Authorization: Bearer invalid-token
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:
// 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);
// 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');
});
// 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:
// Skip the rest of the flow if login failed
if (pm.response.code !== 200) {
pm.execution.setNextRequest(null); // stop the run
}
// 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:
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.