API client
Variables and environments
Use {{variables}} in the API client with globals, collection variables, environments, the Keychain Vault, secret values and about 50 dynamic variables.
Variables let one request work against several servers and accounts. Write {{baseUrl}}/users once, then switch the environment from Staging to Production and the same request goes to a different host with different credentials. Values can come from five scopes, from the macOS Keychain, or from dynamic variables that generate test data on every send.
Use a variable
Section titled “Use a variable”Type the variable’s name in double curly braces anywhere in a request:
{{baseUrl}}/v1/users/{{userId}}?limit={{pageSize}}Variables work in the URL, query params, path variable values, header names and values, every body type except the Binary file path (including form field values and form file paths), GraphQL variables, and every Authorization field.
- Spaces inside the braces are ignored:
{{ baseUrl }}is the same as{{baseUrl}}. - A value can contain other variables, for example
baseUrl=https://{{host}}/api. The client resolves up to ten levels, so a variable that refers to itself can’t loop forever. - Names that don’t resolve are left in the text as written, the way Postman does.
- Rows that are switched off, or have an empty name, are ignored. If a name appears twice in one scope, the last enabled row wins.
Where values come from
Section titled “Where values come from”When the same name is defined in more than one place, the narrowest scope wins:
| Priority | Scope | Where it’s set | How long it lasts |
|---|---|---|---|
| 1 (highest) | Local | pm.variables.set() in a script. |
One send of one request. |
| 2 | Data | The current row of a data file or dataset in the runner. | One runner iteration. |
| 3 | Environment | The active environment. | Saved in the workspace. |
| 4 | Collection | The collection’s Variables tab. | Saved in the workspace. |
| 5 (lowest) | Global | Environments › Globals. | Saved in the workspace. |
Two kinds of names sit outside this order:
{{vault:name}}reads a secret from the Vault.{{$name}}is a dynamic variable.
This is the same order Postman uses, so imported collections resolve the same way.
Environments
Section titled “Environments”An environment is a named set of variables, such as Staging or Production. Only one is active at a time.
An environment with one secret and one plain variable.
- Globals
- The green check marks the active environment; click the circle to switch
- Active label and Export…
- Reveal a secret value
- The lock marks a variable as secret
- Click Environments in the rail, then +. A “New Environment” opens with one empty row.
- Rename it and add variables, for example
baseUrl=https://staging.example.com. - Click the lock on any row that holds a secret.
- Make it active: click Use This Environment in its header, click the circle next to it in the sidebar, or pick it from the environment menu in the toolbar.
The toolbar’s environment menu shows the active environment’s name. Choose No Environment to turn environments off, or Manage Environments… to open this section.
Right-click an environment in the sidebar for Use This Environment, Duplicate (a copy named “… copy”), Export… (a Postman environment file) and Delete, which moves it to Recently Deleted.
Collection variables and globals
Section titled “Collection variables and globals”- Collection variables are on the collection’s Variables tab. They’re for values that belong to the API rather than to a server, such as a version path. Every request in the collection can use them, and the environment overrides them.
- Globals are at the top of the Environments sidebar. They’re available to every collection and environment, at the lowest priority.
Both tables have the same columns and lock button as environments.
Secret variables
Section titled “Secret variables”Click the lock on a variable to make it secret. A secret variable:
- Shows as dots; the eye button reveals it.
- Is saved with an empty value in the workspace’s shared files, while the real value stays in
.cloak/secrets.jsonon your Mac..cloak/is git-ignored, so the value never reaches Git. See Workspace and Git. - Is exported with an empty value in Postman collection and environment files.
- Is left out of the variables table in exported HTML docs.
- Is still a normal variable when you send:
{{token}}resolves to its value.
Secret variables are right for values each teammate fills in for themselves. For real credentials, the Vault is safer still.
Keep secrets in the Vault
Section titled “Keep secrets in the Vault”The Vault stores secrets in the macOS Keychain (as generic passwords under the service name CloakProxy Vault), never in the workspace folder, Git or exports. Requests reference them as {{vault:name}}.
The Vault view adds Keychain secrets and checks your workspace for hardcoded ones.
- Name and Value of a new secret
- Add saves it to the Keychain
- Hardcoded secrets found in collections and environments
- Click Vault in the rail.
- Type a Name, such as
stripe_key, and the Value, then click Add. - Use it in any request field as
{{vault:stripe_key}}, for example a Bearer Token or anX-API-Keyheader.
Each saved secret is listed with its reference and these controls:
| Control | What it does |
|---|---|
| Reveal / Hide | Shows or masks the value. |
| Copy Reference | Copies {{vault:name}}. |
| Trash button | Deletes the secret from the Keychain. |
Adding a secret with an existing name replaces its value. Scripts read and write the Vault with await pm.vault.get("name"), pm.vault.set() and pm.vault.unset(); see Scripts and tests. Agent Mode keeps its model API keys here too, under names like anthropic_api_key.
| Secret variable | Vault | |
|---|---|---|
| Reference | {{token}} |
{{vault:token}} |
| Value stored in | .cloak/secrets.json in the workspace folder |
The macOS Keychain |
| Shared through Git | Name only | Nothing |
| Can differ per environment | Yes | No, one value per name |
| Readable by scripts | pm.environment.get() and the other scope APIs |
await pm.vault.get() |
Find hardcoded secrets
Section titled “Find hardcoded secrets”The bottom of the Vault view lists API keys and tokens typed directly into your workspace: in request URLs, headers, raw bodies and auth fields, and in collection and environment variables that aren’t marked secret. Each finding names the kind of key, where it is and a masked copy of the value. It uses the same detectors as Insights › Secrets.
When it says “No API keys or tokens found in your collections and environments.” you’re clear. Otherwise, move each value into the Vault and replace it with {{vault:name}}.
Dynamic variables
Section titled “Dynamic variables”Dynamic variables start with $ and produce a new value every time they’re used, even twice in the same request. Use them for unique IDs, timestamps and test data.
{ "id": "{{$guid}}", "name": "{{$randomFullName}}", "email": "{{$randomExampleEmail}}", "createdAt": "{{$isoTimestamp}}"}| Variable | Produces |
|---|---|
{{$guid}}, {{$randomUUID}} |
A random UUID in lowercase. |
{{$timestamp}} |
The current Unix time in seconds. |
{{$isoTimestamp}} |
The current time in ISO 8601 with milliseconds, in UTC. |
{{$randomInt}} |
A whole number from 0 to 1000. |
{{$randomNumber}} |
A whole number from 0 to 99999. |
{{$randomDigit}} |
A single digit, 0 to 9. |
{{$randomAlphaNumeric}} |
One lowercase letter or digit. |
{{$randomBoolean}} |
true or false. |
{{$randomFirstName}} |
A first name, such as Grace. |
{{$randomLastName}} |
A last name, such as Hopper. |
{{$randomFullName}} |
A first and last name. |
{{$randomUserName}} |
first.last plus a number, such as grace.hopper42. |
{{$randomEmail}} |
An address like first.last@ at a common mail provider. |
{{$randomExampleEmail}} |
An address at example.com, such as ada317@example.com. |
{{$randomPhoneNumber}} |
A number in the form NNN-NNN-NNNN. |
{{$randomPassword}} |
15 characters of letters, digits and !@#$%. |
{{$randomCity}} |
A city name. |
{{$randomCountry}} |
A country name. |
{{$randomCountryCode}} |
A two-letter country code. |
{{$randomStreetAddress}} |
A street address, such as 1234 Hopper Street. |
{{$randomLatitude}} |
A latitude from -90 to 90, with four decimals. |
{{$randomLongitude}} |
A longitude from -180 to 180, with four decimals. |
{{$randomColor}} |
A color name, such as teal. |
{{$randomHexColor}} |
A hex color, such as #3fa2c7. |
{{$randomIP}} |
An IPv4 address. |
{{$randomIPV6}} |
An IPv6 address. |
{{$randomMACAddress}} |
A MAC address, such as 3a:1f:00:9c:42:7e. |
{{$randomUrl}} |
An https:// URL. |
{{$randomDomainName}} |
A domain name. |
{{$randomWord}}, {{$randomLoremWord}} |
One word. |
{{$randomWords}} |
Two to four words. |
{{$randomLoremSentence}} |
A sentence of five to ten words. |
{{$randomLoremParagraph}} |
Three sentences. |
{{$randomPrice}} |
A price from 1.00 to 999.00. |
{{$randomCurrencyCode}} |
A currency code, such as EUR. |
{{$randomCompanyName}} |
A company name. |
{{$randomJobTitle}} |
A job title, such as Software Engineer. |
{{$randomDatePast}} |
A date and time within the past year, in your Mac’s date format. |
{{$randomDateFuture}} |
A date and time within the next year. |
{{$randomDateRecent}} |
A date and time within the past day. |
{{$randomUserAgent}} |
A Safari, Chrome or iPhone user agent string. |
{{$randomSemver}} |
A version number, such as 3.12.7. |
{{$randomLocale}} |
A two-letter language code, such as ja. |
{{$randomFileName}} |
A file name with an extension, such as harbor.csv. |
{{$randomFileExt}} |
A file extension, such as pdf. |
{{$randomMimeType}} |
A MIME type, such as image/png. |
{{$randomBankAccount}} |
An eight-digit account number. |
{{$randomBitcoin}} |
A string shaped like a Bitcoin address. |
{{$randomImageUrl}} |
https://picsum.photos/640/480. |
{{$randomAvatarImage}} |
An avatar image URL at i.pravatar.cc. |
Scripts can generate the same values with pm.variables.replaceIn("{{$randomEmail}}").
Unresolved variables
Section titled “Unresolved variables”The editor warns you before you send:
- Under the URL bar: “Not defined in the active environment, collection or globals:” followed by each missing name, for variables in the URL and headers.
- In key and value tables, a value with an undefined variable turns orange.
If the URL still contains an undefined variable when you send, the request isn’t sent and the response area says, for example, “The URL uses {{baseUrl}}, which isn’t defined in the environment, collection or globals”. Undefined variables elsewhere, such as in a header or the body, are sent as the literal text.
The usual fixes: activate the right environment, add the variable to the collection’s Variables tab, or check its row is switched on.
Change variables from scripts
Section titled “Change variables from scripts”Scripts read and write every scope:
const body = pm.response.json();pm.environment.set("token", body.access_token); // saved in the active environmentpm.collectionVariables.set("lastUserId", body.id); // saved in the collectionpm.variables.set("traceId", pm.response.headers.get("X-Trace-Id")); // this send onlyWhen you send a single request, changes to globals, the active environment and collection variables are saved in the workspace afterwards: set updates an existing row (and switches it on) or adds one, and unset removes it. Local variables are dropped when the request finishes. In the collection runner, changes are saved when Keep variable changes is on.
The full scripting API is in Scripts and tests.