Skip to content

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.

Type the variable’s name in double curly braces anywhere in a request:

URL
{{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.

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:

This is the same order Postman uses, so imported collections resolve the same way.

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.

  1. Globals
  2. The green check marks the active environment; click the circle to switch
  3. Active label and Export…
  4. Reveal a secret value
  5. The lock marks a variable as secret
The Environments section with Globals and a Staging environment marked active, and the Staging editor showing a secret token variable masked with dots and a region variable set to eu-west-1
  1. Click Environments in the rail, then +. A “New Environment” opens with one empty row.
  2. Rename it and add variables, for example baseUrl = https://staging.example.com.
  3. Click the lock on any row that holds a secret.
  4. 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 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.

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.json on 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.

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.

  1. Name and Value of a new secret
  2. Add saves it to the Keychain
  3. Hardcoded secrets found in collections and environments
The Vault view with Name and Value fields and an Add button, the message No secrets yet, and a Hardcoded secrets section reporting no API keys or tokens found
  1. Click Vault in the rail.
  2. Type a Name, such as stripe_key, and the Value, then click Add.
  3. Use it in any request field as {{vault:stripe_key}}, for example a Bearer Token or an X-API-Key header.

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()

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 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.

Body (raw JSON)
{
"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}}").

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.

Scripts read and write every scope:

Post-response script
const body = pm.response.json();
pm.environment.set("token", body.access_token); // saved in the active environment
pm.collectionVariables.set("lastUserId", body.id); // saved in the collection
pm.variables.set("traceId", pm.response.headers.get("X-Trace-Id")); // this send only

When 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.