skip to content

In a Postman script, what does pm.vault.get('apiKey') return, and how must the script consume it?

level: juniorimportance: should knowfreq 34%

answer

  1. Compare it with an ordinary scope read
  2. The value does not live in the sandbox
  3. A round trip cannot return synchronously
  4. Three members, and each one settles later

basics

~20 s

It returns a Promise, so a Postman script must await it or chain then; the value never arrives synchronously. The vault interface offers get, set and unset, all promise-returning, unlike a variable scope's synchronous get.

solid answer

~40 s

`pm.vault` is a read-only namespace on `pm` exposing exactly `get`, `set` and `unset`, and **all three return Promises**. `pm.vault.get(key)` resolves to the stored value or to nothing; `set(key, value)` and `unset(key)` settle when the write is acknowledged. That is the opposite of `pm.environment.get(key)`, a synchronous lookup on a variable scope already serialised into the script's context. The reason is architectural: the sandbox holds no vault contents, so each member dispatches an event to the host on an execution-scoped channel and settles when the host answers — a round trip, which cannot be a synchronous return. Postman scripts allow a top-level `await`, so `const token = await pm.vault.get('apiKey');` is the normal spelling. Forget the `await` and you have stored a pending Promise, not a credential.

code

javascript · 3 lines
javascript
const token = await pm.vault.get('apiKey');
await pm.vault.set('apiKey', token);
await pm.vault.unset('accessToken');

go deeper

for a junior

Recall that a vault read in a Postman script comes back as a Promise, and that a top-level await is allowed, so the value must be awaited before you use it.

for a middle

Explain why the asymmetry exists: scope values are already in the script's context, while the vault lives outside the sandbox and each call is a dispatched round trip to the host.

for a senior

Be ready to diagnose the missing-await failure from its symptom — a call rejected as unauthenticated because a pending Promise was interpolated instead of a value — and to say where rejection surfaces.

for a principal

Own the design question this raises: which values belong in a store the script must ask for, versus a scope the script already carries, and what that choice costs in run time and failure modes.

## What `pm.vault` is Inside a Postman script, `pm.vault` is a namespace on the `pm` object, sitting alongside `pm.environment`, `pm.globals` and `pm.collectionVariables`. It is assigned as a **read-only** property — reassigning `pm.vault` leaves the original in place — and the interface handed to the script is built by a small factory that exposes exactly **`get`, `set` and `unset`**. There is no `has`, no `clear`, no `toObject`; those are members of a `VariableScope`, which the vault is not. The important difference is not the member list. It is that **every one of those members returns a Promise**. ## The interface and its return types | member | call | returns | |---|---|---| | `get` | `pm.vault.get(key)` | a Promise resolving to the value, or to nothing when unset | | `set` | `pm.vault.set(key, value)` | a Promise that settles when the write is acknowledged | | `unset` | `pm.vault.unset(key)` | a Promise that settles when the removal is acknowledged | Contrast that with `pm.environment.get(key)`, which is a synchronous lookup on a variable scope in the script's own execution context and hands the value straight back. ## Why it is asynchronous when a scope read is not A variable scope is **already in the script's context** — the values were serialised into the execution before the script started, so reading one is a lookup in memory. The vault is not. The sandbox holds no vault contents at all; `get` **dispatches an event to the host** on a channel named per execution and registers a callback, and the returned Promise settles only when the host answers on that channel. If the host answers with an error, the Promise rejects rather than returning a value. That is the whole reason for the asymmetry, and it is the answer an interviewer is listening for: the value lives outside the sandbox, so reaching it costs a round trip, and a round trip cannot be expressed as a synchronous return. ## Consuming it correctly 1. **`await` it** at the point of use. Postman scripts allow a top-level `await`, so `const token = await pm.vault.get('apiKey');` is the normal spelling — no wrapper function needed. 2. **Or chain `.then`**, if you prefer callbacks: `pm.vault.get('apiKey').then((token) => { ... })`. Everything that depends on the value belongs inside that callback. 3. **Handle rejection.** A failed vault read rejects; an unhandled rejection surfaces as a script error rather than as a quietly missing value. 4. **Await the writes too.** `set` and `unset` are promises as well, so code that writes and then immediately reads back must await the write first. ## The failure mode this produces The mistake is uniform and easy to spot once you know it. A script does something like `pm.environment.set('token', pm.vault.get('apiKey'))` and stores **the pending Promise**, not the secret. Nothing throws. The variable now holds an object, and the moment it is interpolated into a request it stringifies into something that is obviously not a credential, and the call comes back rejected by the server. The symptom looks like an authentication problem and is actually a missing `await`. The same shape appears with a value that is *read* correctly but *used* outside the async boundary — a `.then` callback that resolves after the code that needed the value has already run. Keep the whole use of the value inside the awaited scope. ## What to say in an interview - `pm.vault` exposes `get`, `set` and `unset`, and it is read-only on `pm`. - All three return **Promises**; `pm.environment.get` returns a value. - The reason is architectural: the vault's contents are not in the sandbox, so each member is a round trip to the host, dispatched as an execution-scoped event and resolved on the answer. - The practical rule: **await it, or you have stored a Promise.** That is four sentences, it is mechanically true, and it distinguishes someone who has actually written the code from someone who has read that "Postman has a vault".

  • What actually happens if a script stores the result of a vault read without awaiting it?
    The variable holds a pending Promise object. Nothing throws, so the run continues, and the moment the value is interpolated into a request it stringifies into something that is plainly not a credential. The call comes back rejected and the symptom looks like an authentication failure, when the cause is a missing `await`.
  • Why is a variable scope read synchronous when a vault read is not?
    A scope's values are serialised into the script's execution context before the script starts, so reading one is a lookup in memory. The vault's contents are never placed in the sandbox; each member dispatches an event to the host and waits for the answer. One is local state, the other is a round trip, and that difference is what the Promise expresses.

saying these in an interview costs you the question

  • Reads a vault value without awaiting the promise
  • Assumes vault and environment share one interface
  • Thinks the value arrives only after a request is sent
  • Expects has or clear on the vault namespace
  • Ignores rejection when a vault read fails