Scripting

Pre/post-request scripts, the im.* API, tests, and the sandbox.

Impostor runs JavaScript before and after a request using an embedded engine, with an im.* API. This lets you prepare requests, extract values from responses, chain requests, and assert on results.

Pre- and post-request scripts

Each request has a Pre and a Post script tab:

  • Pre-request scripts run before the request is sent — set up variables, compute signatures, or tweak the request.
  • Post-request scripts run after the response arrives — extract tokens, set variables for the next request, and run tests.

Folders can carry scripts too; descendant requests inherit them.

The im.* API

A familiar scripting API is available:

  • im.variables.get(key) — read any in-scope variable.
  • im.environment.set(key, value) — set a variable for subsequent requests (persisted to the active environment on send).
  • im.request.method, im.request.url — inspect the outgoing request.
  • im.response.code, im.response.status, im.response.responseTime — response metadata.
  • im.response.text(), im.response.json() — the response body.
  • im.response.headers.get(name) — a response header.
  • console.log(...) — write to the Console tab.
// Post-request: capture an auth token for later requests.
const body = im.response.json();
im.environment.set("token", body.access_token);

Tests and assertions

Write assertions with im.test and a chai-style im.expect:

im.test("status is 200", () => {
  im.expect(im.response.code).to.equal(200);
});

im.test("returns a user id", () => {
  im.expect(im.response.json()).to.have.property("id");
});

im.expect supports the common matchers (equal/eql, a, above/below, least/most, include, property, match, ok, true/false/null) and .not. Results show in the Tests tab, and are aggregated by the collection runner.

Postman Compatibility

We support Postman pm scripts fully. If you import a Postman collection or already have scripts using the pm.* API, they will run seamlessly in Impostor without any modifications. The im.* API is simply an Impostor-native alias for the exact same underlying functionality.

The sandbox

Scripts run in a fast, embedded JavaScript engine (QuickJS) that is sandboxed — no filesystem or network access by default. Each script has a hard time limit and a memory cap, so a runaway script can’t hang the app.

Opening or importing someone else’s workspace brings its pre/post-request and ƒx scripts, which run automatically. Because a script receives your fully resolved variables — including secrets pulled from encrypted storage — and can rewrite the outgoing request, Impostor makes you review and enable each script before it runs.

Trust is keyed by the script’s content, not by the workspace:

  • Each distinct script must be enabled once. The first time a request would run a script you haven’t enabled, Impostor shows it to you and asks you to confirm.
  • Editing a script — or a git pull that changes one — produces new content, so it must be reviewed again. If you don’t recognise a script, cancel and delete it.
  • The set of enabled scripts is stored on your machine, outside any workspace, so trust can never travel with (or be pre-seeded by) a shared workspace.

Because it’s keyed by content, even a script you wrote yourself prompts the first time — just review it and enable it.

Enforcement lives in the core, not the UI, so the gate can’t be bypassed:

  • Pre/post-request scripts that aren’t enabled are stripped before the request engine ever sees them (the response log notes that they were skipped).
  • ƒx value scripts that aren’t enabled resolve to an empty value instead of executing. This covers every path that resolves variables — HTTP send, collection runs, WebSocket/SSE/gRPC/MCP connect, and Copy as cURL/code — so an un-reviewed ƒx can never read a secret and bake it into a request or a generated snippet.