API client
Scripts and tests
Pre-request and post-response scripts in the API client, with a complete reference for the Postman-compatible pm API, assertions, libraries and packages.
Scripts are JavaScript that runs around a request. A pre-request script runs before it’s sent, to compute a signature, set a variable or change the request. A post-response script runs after the response arrives, to check it with tests and pass values to the next request. Scripts use Postman’s pm API, so scripts from imported Postman collections run unchanged in most cases.
This page lists everything the sandbox implements. If a Postman feature isn’t here, Cloak Proxy doesn’t support it.
Write a test
Section titled “Write a test”A post-response script and its test results.
- Pre-request and Post-response; a green dot marks a phase with code
- Snippets inserts common scripts
- The script editor
- Test Results shows passed/total
- PASS, FAIL or SKIP for each test
-
Open a request and click Scripts.
-
Click Post-response. The editor’s hint reads “Runs after the response arrives. Write tests with pm.test and pm.expect.”
-
Write a test, or pick one from Snippets:
Post-response pm.test("Status code is 200", () => {pm.response.to.have.status(200);});pm.test("Returns the pet", () => {const pet = pm.response.json();pm.expect(pet.id).to.equal(1);pm.expect(pet.name).to.be.a("string").and.not.be.empty;}); -
Send the request. The response’s Test Results tab lists each test as PASS or FAIL with the reason, and the tab title shows the count, for example
2/2.
Collections and folders have the same Scripts tab. Their scripts run for every request inside them.
Snippets
Section titled “Snippets”The Snippets menu inserts one of these at the end of the current script:
| Snippet | Inserts |
|---|---|
| Status code is 200 | A test that the status is 200. |
| Response time is less than 200ms | A test on pm.response.responseTime. |
| Response body: JSON value check | A test comparing a JSON field with eql. |
| Response body: contains string | A test that the body text includes a string. |
| Response body: is equal to a string | A test that the body equals a string. |
| Content-Type header is present | A test for a header. |
| Validate the response against a JSON schema | A schema and a jsonSchema test. |
| Successful POST request | A test that the status is 201 or 202. |
| Set an environment variable | pm.environment.set(…) |
| Save a value from the response | Saves token from the JSON body into the environment. |
| Set a collection variable | pm.collectionVariables.set(…) |
| Set a global variable | pm.globals.set(…) |
| Get a variable | pm.variables.get(…) |
| Clear an environment variable | pm.environment.unset(…) |
| Read a secret from the Vault | await pm.vault.get(…) |
| Send a request | await pm.sendRequest(…) and a log of the JSON. |
| Visualize the response as a table | A pm.visualizer.set template. |
| Reuse a saved request | await pm.execution.runRequest(…) that saves a token. |
| Use a shared package | pm.require("helpers") |
| Skip this request (runner) | pm.execution.skipRequest() |
| Run another request next (runner) | pm.execution.setNextRequest(…) |
When scripts run
Section titled “When scripts run”Sending a request runs, in order:
- Pre-request scripts: the collection’s, then each folder’s from the outermost in, then the request’s.
- Variable resolution, path variables, auth and cookies.
- The network request.
- Post-response scripts, in the same order: collection, folders, request.
Each script sees the variables and request as the previous one left them. Empty scripts are skipped.
- Pre-request scripts see the request as written, with
{{variables}}still in place, before auth headers and cookies are added. Whatever they change is what gets resolved and sent. - Post-response scripts see the request as it was actually sent, with variables resolved and auth added.
- Post-response scripts run even when the request failed to send.
pm.responseis thenundefined, so guard tests withif (pm.response)when that matters. - If a pre-request script calls
pm.execution.skipRequest(), the remaining pre-request scripts don’t run, nothing is sent, and the response area says “Skipped by script”.
The Timing tab shows how long the pre-request and post-response scripts took. Console entries are labeled with their phase and owner, such as “Pre-request · Petstore” or “Post-response · Get pet”.
The script environment
Section titled “The script environment”Scripts run in JavaScriptCore, the engine in Safari, in a fresh sandbox for every script.
- Modern JavaScript works: arrow functions,
constandlet, template literals, destructuring,asyncandawait. - The script body is wrapped in an
asyncfunction, soawaitworks at the top level. - Each script has 30 seconds. After that it stops with “Script timed out after 30 seconds”.
- There’s no file system,
fetch,XMLHttpRequestor Node.js API. Usepm.sendRequestfor HTTP.
Globals available in every script:
| Global | What it is |
|---|---|
pm |
The Postman API, below. |
console |
log, info, warn, error and debug. Output goes to the Console tab. Objects are printed as indented JSON. |
setTimeout(fn, ms), clearTimeout(id) |
Timers. |
atob(text), btoa(text) |
Base64 decode and encode. atob also accepts Base64URL. |
xml2Json(xml) |
Converts XML to an object: elements become keys, attributes go under $, repeated elements become arrays, and text-only elements become strings. |
require(name) |
Loads a built-in library or workspace package. Same as pm.require. |
expect, chai |
The assertion library, also available as pm.expect. |
CryptoJS, _, uuid, tv4, Ajv |
The built-in libraries, also loadable with require. |
postman, responseBody, responseCode, responseTime, tests |
Legacy globals from Postman’s older API. |
pm API reference
Section titled “pm API reference”pm.info
Section titled “pm.info”Read-only information about the current run.
| Property | Value |
|---|---|
pm.info.eventName |
"prerequest" in pre-request scripts, "test" in post-response scripts. |
pm.info.iteration |
The runner iteration, starting at 0. Always 0 for a single send. |
pm.info.iterationCount |
The number of iterations in the run. 1 for a single send. |
pm.info.requestName |
The request’s name. |
pm.info.requestId |
The request’s ID. |
pm.request
Section titled “pm.request”The request being sent. Changes in a pre-request script are sent.
| Member | What it is |
|---|---|
pm.request.method |
The method, such as "POST". Assign to change it. |
pm.request.url |
A Url object. Assign a string or a Url to replace it: pm.request.url = "{{baseUrl}}/v2/pets". |
pm.request.headers |
A property list of headers. Header names match without regard to case. |
pm.request.body |
The body as text. Assign a string, { mode: "raw", raw: "…" }, or { mode: "urlencoded", urlencoded: [{ key, value }] }. |
pm.request.name |
The request’s name. |
pm.request.addHeader({ key, value }) |
Adds a header. |
pm.request.upsertHeader({ key, value }) |
Sets a header, replacing an existing one with the same name. |
pm.request.removeHeader(key) |
Removes every header with that name. |
// Sign the body with a shared secret. Pre-request scripts see {{variables}}// unresolved, so resolve them first to sign what will be sent.const secret = await pm.vault.get("webhook_secret");const body = pm.variables.replaceIn(pm.request.body);const signature = CryptoJS.HmacSHA256(body, secret).toString();pm.request.upsertHeader({ key: "X-Signature", value: signature });pm.request.url.query.upsert({ key: "ts", value: String(Date.now()) });A header added with disabled: true isn’t sent. Body changes apply to Raw, None, GraphQL and Binary bodies. x-www-form-urlencoded and form-data bodies are rebuilt from the Body tab after scripts run, so change their fields with variables instead; pm.request.body is empty for form-data in pre-request scripts.
Url objects
Section titled “Url objects”pm.request.url is parsed into parts. A URL that starts with a variable, like {{baseUrl}}/users, treats the first segment as the host.
| Member | What it is |
|---|---|
protocol |
The scheme, such as "https", or "". |
auth |
The user:password part before @, or "". |
host |
The host split on dots, as an array: ["api", "example", "com"]. |
port |
The port as a string, or "". |
path |
The path segments, as an array. |
query |
A property list of query parameters. |
hash |
The fragment after #, or "". |
getHost() |
The host as a string. |
getPath() |
The path, starting with /. |
getQueryString() |
The encoded query string of enabled parameters. |
getPathWithQuery() |
The path and query. |
getRemote() |
The host and port. |
addQueryParams(params) |
Adds one { key, value } or an array of them. |
removeQueryParams(keys) |
Removes parameters by name, or by an array of names. |
update(text) |
Parses a new URL into the same object. |
toString() |
The whole URL. |
When a script doesn’t change the URL, the original text is kept exactly, including its {{variables}}.
Property lists
Section titled “Property lists”Headers, query parameters, response headers and cookies are property lists: ordered { key, value, disabled } items with these methods.
| Method | What it does |
|---|---|
get(key) |
The value of the last enabled item with that key, or undefined. |
one(key) |
The first item with that key. |
has(key, value?) |
Whether an enabled item has that key (and value, when given). |
add(item) or add(key, value), append(…) |
Adds an item. |
upsert(item) or upsert(key, value) |
Updates the first item with that key and enables it, or adds one. |
remove(key) or remove(predicate) |
Removes matching items. |
clear() |
Removes everything. |
each(fn), map(fn), filter(fn), find(fn) |
Iterate over the items. |
all() |
A copy of the items as an array. |
count() |
How many items there are. |
idx(n) |
The item at a position. |
toObject() |
Enabled items as { key: value }. |
toString() |
Enabled items as Key: value lines. |
members |
The underlying array. |
pm.response
Section titled “pm.response”The response, in post-response scripts. undefined in pre-request scripts and when the request failed.
| Member | What it is |
|---|---|
pm.response.code |
The status code, such as 200. |
pm.response.status |
The reason phrase, such as "OK". |
pm.response.reason() |
The reason phrase. |
pm.response.headers |
A property list of headers. pm.response.headers.get("content-type") matches without regard to case. |
pm.response.text() |
The body as text. |
pm.response.json() |
The body parsed as JSON. Throws if it isn’t JSON. |
pm.response.stream |
The body text. |
pm.response.responseTime |
The total time in milliseconds. |
pm.response.responseSize |
The body size in bytes. |
pm.response.to |
Starts an assertion on the response, like pm.expect(pm.response). See Response assertions. |
pm.cookies
Section titled “pm.cookies”A property list of the cookies in the client’s cookie jar that match the request’s URL, as { key, value }.
const session = pm.cookies.get("session_id");pm.test("Has a session", () => pm.expect(pm.cookies.has("session_id")).to.be.true);pm.variables
Section titled “pm.variables”Reads across every scope with the normal priority: local, data, environment, collection, global.
| Method | What it does |
|---|---|
get(name) |
The value from the highest-priority scope that has it, or undefined. |
has(name) |
Whether any scope has it. |
set(name, value) |
Sets a local variable for the rest of this send. Objects are stored as JSON; other values as strings. |
unset(name) |
Removes a local variable. |
toObject() |
Every variable merged into one object, with higher-priority scopes winning. |
replaceIn(text) |
Resolves {{name}}, {{$dynamic}} and {{vault:name}} in a string. |
const url = pm.variables.replaceIn("{{baseUrl}}/users/{{$randomInt}}");pm.environment, pm.collectionVariables, pm.globals, pm.iterationData
Section titled “pm.environment, pm.collectionVariables, pm.globals, pm.iterationData”One object per scope, all with the same methods. pm.environment is the active environment, pm.collectionVariables the request’s collection, pm.globals the globals, and pm.iterationData the current runner row (empty outside the runner).
| Method | What it does |
|---|---|
get(name) |
The value in this scope, or undefined. |
set(name, value) |
Sets it in this scope. Objects are stored as JSON; other values as strings. |
unset(name) |
Removes it from this scope. |
has(name) |
Whether this scope has it. |
clear() |
Removes every variable in this scope. |
toObject() |
This scope’s variables as an object. |
replaceIn(text) |
Resolves variables in a string across all scopes, like pm.variables.replaceIn. |
Changes to the environment, collection variables and globals are saved after a single send. See Change variables from scripts.
Values are always strings. Parse numbers and objects you stored: JSON.parse(pm.environment.get("user")).
pm.vault
Section titled “pm.vault”Secrets in the macOS Keychain. Every method returns a promise.
| Method | What it does |
|---|---|
await pm.vault.get(name) |
The secret’s value, or undefined. |
await pm.vault.set(name, value) |
Saves a secret. |
await pm.vault.unset(name) |
Deletes a secret. |
set and unset are applied to the Keychain when a request you sent from its editor finishes; in the collection runner and cloakctl they have no effect. See Keep secrets in the Vault.
pm.test
Section titled “pm.test”pm.test(name, fn)pm.test.skip(name)pm.test runs fn and records a test called name. It passes unless fn throws, which every failed assertion does. Tests don’t stop the script: a failing test is recorded and the next line runs.
- If
fnreturns a promise, a rejection fails the test. - If
fntakes an argument, it’s called with a callback; calling it with an error fails the test. pm.test.skip(name)records a skipped test (SKIP) without running anything.
Tests can be in pre-request scripts too; they appear in the same Test Results list.
pm.expect
Section titled “pm.expect”pm.expect(value) starts a chai-style assertion. The sandbox implements the subset below; anything else throws “is not a function” or isn’t defined.
pm.expect(user.age).to.be.a("number").and.be.at.least(18);pm.expect(tags).to.include("admin");pm.expect(order).to.have.nested.property("customer.email", "ada@example.com");pm.expect(() => JSON.parse("{")).to.throw();Chains and flags
Section titled “Chains and flags”These words read naturally and do nothing: to, be, been, is, that, which, and, has, have, with, at, of, same, but, does, still, also, own.
| Flag | Effect |
|---|---|
.not |
Negates the assertion that follows. |
.deep |
Makes equal and property compare by value. (include and eql always do.) |
.nested |
Lets property take a dotted path, such as "items[0].id". |
.any |
With keys: at least one key must be present. |
.all |
With keys: the keys must be exactly these. |
.length |
Makes the next above, below, least, most or within compare the length (or size, or number of keys). |
Value assertions
Section titled “Value assertions”Properties, used without parentheses:
| Assertion | Passes when the value |
|---|---|
.true, .false |
Is exactly true or false. |
.null, .undefined |
Is null or undefined. |
.NaN |
Is NaN. |
.exist |
Is neither null nor undefined. |
.empty |
Is an empty string, array or object. |
.ok |
Is truthy. On a response, means status 200. |
Methods:
| Assertion | Passes when |
|---|---|
.equal(v), .equals(v), .eq(v) |
The value is === to v (deeply equal with .deep). |
.eql(v), .eqls(v) |
The value deeply equals v. |
.above(n), .gt(n), .greaterThan(n) |
The value is greater than n. |
.below(n), .lt(n), .lessThan(n) |
The value is less than n. |
.least(n), .gte(n) |
The value is at least n. |
.most(n), .lte(n) |
The value is at most n. |
.within(lo, hi) |
The value is between lo and hi, inclusive. |
.closeTo(n, delta), .approximately(n, delta) |
The value is within delta of n. |
.a(type), .an(type) |
The type is "string", "number", "boolean", "object", "array", "null", "undefined", "function", "regexp" or "date". |
.instanceOf(C), .instanceof(C) |
The value is an instance of C. |
.include(v), .includes(v), .contain(v), .contains(v) |
A string contains v; an array has an item deeply equal to v; an object has every key and value of object v, or has key v. |
.members(list) |
An array has exactly the same items as list, in any order. |
.oneOf(list) |
The value deeply equals an item of list. |
.match(re), .matches(re) |
The value, as a string, matches the regular expression. |
.string(s) |
The value, as a string, contains s. |
.lengthOf(n) |
The value’s length (or number of keys) is n. |
.property(name) |
The value has the property. Continues the chain on the property’s value. |
.property(name, value) |
The property equals value (deeply with .deep). |
.keys(…), .key(…) |
The object has these keys (names as arguments, an array, or an object’s keys). |
.satisfy(fn), .satisfies(fn) |
fn(value) returns something truthy. |
.throw(expected?), .throws(expected?) |
The function throws; optionally an error whose message matches a regular expression or contains a string, or that is an instance of a class. |
.jsonSchema(schema) |
The value (or a response’s JSON body) matches the JSON Schema. |
expect.fail(message) fails immediately.
Response assertions
Section titled “Response assertions”Start from pm.response.to (or pm.expect(pm.response).to).
| Assertion | Passes when |
|---|---|
.have.status(code) |
The status code equals code. |
.have.status(reason) |
The reason phrase equals the string, such as "Created". |
.have.header(name) |
The header exists (any case). |
.have.header(name, value) |
The header has exactly that value. |
.have.body() |
The body isn’t empty. |
.have.body(text) |
The body equals the string. |
.have.body(re) |
The body matches the regular expression. |
.have.body(object) |
The JSON body deeply equals the object. |
.have.jsonBody() |
The body is JSON. |
.have.jsonBody(path) |
The JSON body has a value at the dotted path, such as "data.items[0].id". |
.have.jsonBody(path, value) |
The value at the path deeply equals value. |
.have.jsonBody(object) |
The JSON body deeply equals the object. |
.have.jsonSchema(schema) |
The JSON body matches the schema. |
.have.responseTime.below(ms) |
The response time is under ms. Any number assertion works after responseTime. |
.be.ok |
Status 200. |
.be.success |
Status 2xx. |
.be.info |
Status 1xx. |
.be.redirection |
Status 3xx. |
.be.error |
Status 4xx or 5xx. |
.be.clientError |
Status 4xx. |
.be.serverError |
Status 5xx. |
.be.accepted |
Status 202. |
.be.badRequest |
Status 400. |
.be.unauthorized |
Status 401. |
.be.forbidden |
Status 403. |
.be.notFound |
Status 404. |
.be.rateLimited |
Status 429. |
.be.json |
Content-Type contains json and the body parses. |
.be.html |
Content-Type contains html. |
.be.xml |
Content-Type contains xml. |
.be.withBody |
The body isn’t empty. |
pm.test("Created", () => { pm.response.to.have.status(201); pm.response.to.have.header("Location"); pm.response.to.be.json; pm.response.to.have.jsonBody("id"); pm.response.to.have.responseTime.below(800);});JSON Schema
Section titled “JSON Schema”jsonSchema (and tv4 and Ajv, below) validate against a draft-07 subset. Supported keywords:
| Applies to | Keywords |
|---|---|
| Any value | type (including "integer" and arrays of types), enum, const, allOf, anyOf, oneOf, not |
| Numbers | minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf |
| Strings | minLength, maxLength, pattern, format (email, uuid, date-time) |
| Arrays | items (one schema, or an array for tuples), minItems, maxItems, uniqueItems |
| Objects | properties, required, additionalProperties (false or a schema) |
$ref isn’t resolved. A failure message lists up to five problems, such as id should be integer but is string.
const schema = { type: "object", required: ["id", "name"], properties: { id: { type: "integer" }, name: { type: "string", minLength: 1 }, email: { type: "string", format: "email" }, },};pm.test("Matches the schema", () => pm.response.to.have.jsonSchema(schema));chai.assert
Section titled “chai.assert”chai.assert(condition, message) and its methods assert.ok, assert.equal (==), assert.strictEqual, assert.deepEqual and assert.isTrue throw an AssertionError when they fail.
pm.sendRequest
Section titled “pm.sendRequest”Sends another HTTP request from a script and returns a promise of its response.
const res = await pm.sendRequest(url)const res = await pm.sendRequest(options)await pm.sendRequest(options, (err, res) => { … })| Option | What it’s for |
|---|---|
url |
The URL. {{variables}} are resolved. A plain string argument is a GET to that URL. |
method |
Defaults to GET. |
header or headers |
An array of { key, value }, or an object of name to value. |
body |
{ mode: "raw", raw: text or object } (objects are sent as JSON), { mode: "urlencoded", urlencoded: [{ key, value }] } (adds Content-Type: application/x-www-form-urlencoded if missing), or a string. |
The response has the same members as pm.response, including .to assertions. On a network error the promise rejects and the callback gets the error.
const res = await pm.sendRequest({ url: "{{baseUrl}}/oauth/token", method: "POST", header: { Accept: "application/json" }, body: { mode: "urlencoded", urlencoded: [ { key: "grant_type", value: "client_credentials" }, { key: "client_id", value: pm.environment.get("clientId") }, { key: "client_secret", value: await pm.vault.get("client_secret") }, ], },});pm.environment.set("token", res.json().access_token);pm.sendRequest sends only what you give it: no auth, scripts or cookie jar. It goes through Cloak Proxy when the proxy is running, follows redirects, verifies TLS, and times out after 30 seconds. Several calls can run at once with Promise.all.
pm.execution
Section titled “pm.execution”| Member | What it does |
|---|---|
pm.execution.setNextRequest(name) |
In the collection runner, runs the request with that name (or ID) next instead of the following one. |
pm.execution.setNextRequest(null) |
In the runner, stops the run after this request. |
pm.execution.skipRequest() |
In a pre-request script, cancels sending this request. |
pm.execution.runRequest(ref, options?) |
Runs another saved request and returns a promise of its response. |
pm.execution.location |
The path of the running request: collection, folders and request names, as an array. |
pm.execution.location.current |
"prerequest" or "test". |
Reuse a saved request
Section titled “Reuse a saved request”pm.execution.runRequest runs a saved request with its own scripts and auth, so a login request can be the single place your token logic lives.
const login = await pm.execution.runRequest("Auth/Login", { variables: { user: "ada@example.com" },});pm.variables.set("token", login.json().token);refis the request’s ID, its name, or a path ending in its name:"Login","Auth/Login"or"Petstore/Auth/Login". When several match, one in the current collection wins.options.variablesbecome local variables for that run only.- The other request’s variable changes don’t flow back to yours.
- Calls can nest up to five levels deep, so a request that runs itself fails instead of looping.
pm.visualizer
Section titled “pm.visualizer”Renders HTML from a template and data into the response’s Visualize tab.
| Method | What it does |
|---|---|
pm.visualizer.set(template, data) |
Renders template with data and shows the result. |
pm.visualizer.clear() |
Removes it. |
Templates use a Handlebars subset:
| Syntax | Meaning |
|---|---|
{{name}}, {{user.email}} |
A value, HTML-escaped. Objects are shown as JSON. |
{{{html}}} |
A value, not escaped. |
{{#each items}} … {{/each}} |
Repeats for each array item or object property. Inside: {{this}}, {{@index}}, {{@first}}, {{@last}}, {{@key}}. |
{{#if value}} … {{else}} … {{/if}} |
Shows a block when the value is truthy and not an empty array. |
{{#unless value}} … {{/unless}} |
The opposite of if. |
{{#with object}} … {{/with}} |
Changes the context to object. |
{{../name}} |
A value from the outer context. |
{{! comment }} |
Ignored. |
const template = ` <table> <tr><th>#</th><th>Name</th><th>Tag</th></tr> {{#each pets}}<tr><td>{{@index}}</td><td>{{name}}</td><td>{{tag}}</td></tr>{{/each}} </table>`;pm.visualizer.set(template, { pets: pm.response.json() });pm.require
Section titled “pm.require”pm.require(name) loads a module and returns its exports. It’s the same function as the global require.
| Name | Loads |
|---|---|
"crypto-js", "lodash", "uuid", "chai", "tv4", "ajv", "xml2js", "atob", "btoa" |
A built-in library. |
"helpers" or "@team/helpers" |
A workspace package named helpers. The @scope/ part is ignored. |
"npm:dayjs@1.11.13" |
A downloaded npm package at that version. |
"npm:dayjs" |
A downloaded npm package, whichever version you have. |
A module loads once per script, however many times you require it. Unknown names throw “No module ‘…’. Add it to the workspace’s Packages, or use one of: crypto-js, lodash, uuid, chai, tv4, ajv, xml2js”.
Legacy Postman API
Section titled “Legacy Postman API”Older Postman scripts keep working:
| Legacy | Equivalent |
|---|---|
postman.setNextRequest(name) |
pm.execution.setNextRequest(name) |
postman.getEnvironmentVariable(name), postman.setEnvironmentVariable(name, value), postman.clearEnvironmentVariable(name) |
pm.environment.get, set, unset |
postman.getGlobalVariable(name), postman.setGlobalVariable(name, value) |
pm.globals.get, set |
responseBody |
pm.response.text() |
responseCode.code, responseCode.name |
pm.response.code, pm.response.status |
responseTime |
pm.response.responseTime |
tests["name"] = condition |
A test that passes when condition is truthy. |
Built-in libraries
Section titled “Built-in libraries”These need no download. Each is also a global.
| Library | require name |
What’s included |
|---|---|---|
| CryptoJS | crypto-js |
MD5, SHA1, SHA256, SHA384, SHA512, HmacMD5, HmacSHA1, HmacSHA256, HmacSHA512, and enc.Hex, enc.Base64, enc.Utf8 with parse and stringify. Results print as hex with toString(), or Base64 with toString(CryptoJS.enc.Base64). |
lodash (_) |
lodash |
get, set, has, isEqual, cloneDeep, keys, values, pick, omit, map, filter, find, sortBy, uniq, random, sample, times, merge, isEmpty, isString, isNumber, isArray, isObject, isFunction, includes, groupBy, flatten, chunk, first, last, size, capitalize, camelCase, forEach, each. |
| uuid | uuid |
uuid.v4() |
| chai | chai |
expect, assert, AssertionError. |
| tv4 | tv4 |
tv4.validate(data, schema) returns true or false and sets tv4.error; tv4.validateResult(data, schema) returns { valid, error }. |
| Ajv | ajv |
new Ajv().compile(schema) returns a validator function with .errors; ajv.validate(schema, data). |
| xml2js | xml2js |
parseString(xml, callback), using the same conversion as xml2Json. |
| atob, btoa | atob, btoa |
Base64 decode and encode. |
The lodash, CryptoJS and schema libraries are small implementations of the listed functions, not the full packages.
const CryptoJS = require("crypto-js");const digest = CryptoJS.SHA256("hello").toString(CryptoJS.enc.Base64);const ids = _.uniq(pm.response.json().map((item) => item.id));Share code with packages
Section titled “Share code with packages”Packages are shared modules every script in the workspace can load. They’re saved as packages/<name>.js in the workspace, so they travel with Git.
Workspace packages
Section titled “Workspace packages”-
Click Packages in the rail, then + › New Package. A package named
helpersopens with example code. -
Rename it and write a CommonJS module that assigns
module.exports:helpers module.exports = {expectOk(response) {pm.expect(response.code, "status").to.be.within(200, 299);},bearer(token) {return { key: "Authorization", value: `Bearer ${token}` };},}; -
Click Copy Import to copy a line like
const helpers = pm.require("helpers");, and paste it into any script.
Inside a package, module, exports, require, pm and console are available, so packages can require each other and use the pm API of the script that loaded them.
npm packages
Section titled “npm packages”-
Click Packages in the rail, then + › Add from npm….
-
Type a package name with an optional version or range, such as
dayjs@1.11.13, and click Download. -
The client asks jsDelivr for the exact version, downloads the package’s main file, and saves it as a package named
npm:dayjs@1.11.13. -
Load it in a script:
const dayjs = pm.require("npm:dayjs@1.11.13");pm.environment.set("tomorrow", dayjs().add(1, "day").format("YYYY-MM-DD"));
Downloading is the only step that needs the internet; after that, scripts load the package from the workspace offline. Downloading the same name and version again replaces it.
Limits:
- Self-contained builds work, such as
dayjs,lodashandvalidator. Packages thatrequireother packages don’t. - The main file must be JavaScript and under 3 MB.
- Scoped names work:
@scope/name@1.2.3.
Find script errors
Section titled “Find script errors”- A script that throws stops at that line. The Console tab lists the error in red, prefixed with where it came from, such as “Post-response script (Get pet):” followed by the error message.
- Failed assertions inside
pm.testdon’t stop the script; they show in Test Results. console.logoutput appears in Console with its level and source. The tab title counts entries and errors.- Post-response scripts still run after a network error, so check
pm.responsebefore reading it.
Scripts in other protocols
Section titled “Scripts in other protocols”In the collection runner and cloakctl collection run, gRPC, MCP, AI, SQL, WebSocket, Socket.IO, MQTT and TCP requests run their scripts too. Each answers with an HTTP-style response, so the same pm.response tests apply. See API client protocols for what each protocol’s response contains.