Skip to content

Script cookbook ​

Short scripts you can paste into a request's Scripts tab and adapt. Each recipe says whether it belongs in Pre-request or Post-response. New to scripts? Read Scripts first.

Tests ​

1. Check the status code ​

Post-response.

js
pm.test("Status is 200", () => {
  pm.response.to.have.status(200);
});

pm.test("Created or accepted", () => {
  pm.expect(pm.response.code).to.be.oneOf([201, 202]);
});

2. Check fields in a JSON body ​

Post-response. Parse the body once, then check as many fields as you need.

js
const user = pm.response.json();

pm.test("User has the expected fields", () => {
  pm.expect(user.id).to.be.a("number");
  pm.expect(user.name).to.equal("Ada");
  pm.expect(user.email).to.match(/@example\.com$/);
  pm.expect(user.roles).to.include("admin");
});

3. Check every item in a list ​

Post-response.

js
const items = pm.response.json().items;

pm.test("The list is not empty", () => {
  pm.expect(items).to.be.an("array").that.is.not.empty;
});

pm.test("Every item has an id and a price above zero", () => {
  for (const item of items) {
    pm.expect(item).to.have.property("id");
    pm.expect(item.price).to.be.above(0);
  }
});

4. Validate the shape with a JSON Schema ​

Post-response. A schema describes which fields must exist and what type each one is.

js
const schema = {
  type: "object",
  required: ["id", "title", "done"],
  properties: {
    id: { type: "number" },
    title: { type: "string" },
    done: { type: "boolean" },
  },
};

pm.test("Body matches the schema", () => {
  pm.response.to.have.jsonSchema(schema);
});

5. Check headers and speed ​

Post-response.

js
pm.test("The response is JSON", () => {
  pm.response.to.have.header("Content-Type");
  pm.expect(pm.response.headers.get("Content-Type")).to.include("application/json");
});

pm.test("Answered in under half a second", () => {
  pm.expect(pm.response.responseTime).to.be.below(500);
});

6. Check an error response ​

Post-response. Good API tests also check that bad input is refused. See Negative testing.

js
pm.test("Missing title is rejected", () => {
  pm.response.to.have.status(400);
  pm.expect(pm.response.json().error).to.include("title");
});

Variables and chaining ​

7. Save a token after logging in ​

Post-response, on the login request. Later requests use {{token}}.

js
const body = pm.response.json();

pm.test("Login returned a token", () => {
  pm.expect(body.token).to.be.a("string");
});

pm.environment.set("token", body.token);

For a single value like this, a capture does the same without code.

8. Keep an object in a variable ​

Variables hold text, so turn an object into JSON to store it and parse it to read it back.

Post-response, on the first request:

js
pm.collectionVariables.set("lastOrder", JSON.stringify(pm.response.json()));

In a later script:

js
const lastOrder = JSON.parse(pm.collectionVariables.get("lastOrder"));
console.log(lastOrder.id);

9. Use a row from a data file ​

Either phase. In a data-driven run, each row's columns are available by name. Values are always text.

js
const expectedName = pm.iterationData.get("name");

pm.test("Name matches the data row", () => {
  pm.expect(pm.response.json().name).to.equal(expectedName);
});

Change the request before it goes out ​

10. Add a timestamp and a unique id ​

Pre-request.

js
pm.request.headers.upsert({ key: "X-Request-Id", value: require("uuid").v4() });
pm.request.headers.upsert({ key: "X-Timestamp", value: new Date().toISOString() });

11. Compute a date ​

Pre-request. Sets {{dueDate}} to seven days from now.

js
const moment = require("moment");
pm.environment.set("dueDate", moment().add(7, "days").format("YYYY-MM-DD"));

12. Sign the request with HMAC ​

Pre-request. Many APIs want a signature made from the body and a secret key. In a pre-request script the body still has its {{placeholders}}, so fill them in first with pm.variables.replaceIn.

js
const secret = pm.environment.get("apiSecret");
const timestamp = String(Math.floor(Date.now() / 1000));
const body = pm.variables.replaceIn(pm.request.body.toString());

const signature = CryptoJS.HmacSHA256(timestamp + "." + body, secret).toString(CryptoJS.enc.Hex);

pm.request.headers.upsert({ key: "X-Timestamp", value: timestamp });
pm.request.headers.upsert({ key: "X-Signature", value: signature });

Use CryptoJS.enc.Base64 in place of CryptoJS.enc.Hex when the API expects base64.

13. Build a Basic auth header by hand ​

Pre-request. The Auth tab does this for you; this shows how to do it in code.

js
const user = pm.environment.get("user");
const password = pm.environment.get("password");

pm.request.headers.upsert({
  key: "Authorization",
  value: "Basic " + btoa(user + ":" + password),
});

14. Fetch a token when it is missing or expired ​

Pre-request, best placed on the collection so it covers every request. It calls the login endpoint only when needed.

js
const expiresAt = Number(pm.environment.get("tokenExpiresAt") || 0);

if (!pm.environment.get("token") || Date.now() > expiresAt) {
  const response = await pm.sendRequest({
    url: pm.variables.replaceIn("{{baseUrl}}/login"),
    method: "POST",
    header: { "Content-Type": "application/json" },
    body: {
      mode: "raw",
      raw: JSON.stringify({
        user: pm.environment.get("user"),
        password: pm.environment.get("password"),
      }),
    },
  });

  const body = response.json();
  pm.environment.set("token", body.token);
  pm.environment.set("tokenExpiresAt", Date.now() + body.expiresIn * 1000);
}

This assumes the login answers with token and expiresIn (seconds). Adjust the field names to your API.

Control the run ​

15. Skip a request ​

Pre-request. The request is not sent, and the runner lists it as skipped.

js
if (pm.environment.get("stage") === "production") {
  pm.execution.skipRequest();
}

16. Jump to another request ​

Post-response. Works in the collection runner and the command-line runner. The name must match a request in the run.

js
// After "List items": create one only when the list is empty.
if (pm.response.json().items.length > 0) {
  pm.execution.setNextRequest("Get first item");
}

Without a jump, the run carries on with the next request in the list. Take care not to jump backwards without a condition that ends: a pass is stopped after 10,000 jumps.

To stop the current pass after this request:

js
pm.execution.setNextRequest(null);

17. Poll until a job is finished ​

Post-response, on a "get job status" request in a run. The request repeats itself until the job is done, up to ten tries. Set Delay between (ms) in the runner so the tries are spaced out.

js
const tries = Number(pm.environment.get("pollTries") || 0) + 1;
const status = pm.response.json().status;

if (status !== "done" && tries < 10) {
  pm.environment.set("pollTries", tries);
  pm.execution.setNextRequest(pm.info.requestName);
} else {
  pm.environment.unset("pollTries");
  pm.test("Job finished", () => {
    pm.expect(status).to.equal("done");
  });
}

See what is going on ​

18. Log while you debug ​

Either phase. Output goes to the Console.

js
console.log("Request:", pm.info.requestName, "iteration", pm.info.iteration);
console.log("Sending to", pm.request.url.toString());
console.warn("Token is", pm.environment.has("token") ? "set" : "missing");

In a post-response script you can also log the response:

js
console.log(pm.response.code, pm.response.json());

19. Show the response as a table ​

Post-response. The result appears in a Visualize tab in the response. The template uses Handlebars: {{#each}} repeats a row for every item.

js
const template = `
<table>
  <tr><th>Id</th><th>Name</th></tr>
  {{#each users}}
  <tr><td>{{id}}</td><td>{{name}}</td></tr>
  {{/each}}
</table>`;

pm.visualizer.set(template, { users: pm.response.json().users });

Post-response.

js
pm.test("A session cookie is set", () => {
  pm.expect(pm.cookies.has("session")).to.equal(true);
});

Next steps ​