Rest Hippo ← Back to site

Scripts

← Back to contents

The Scripts tab on a request lets you run a little JavaScript before the request is sent and after the response comes back. Use it to prepare the outgoing request (set a header, rewrite the URL), to pull a value out of the response and stash it in a variable for a later request, or just to log something while you debug.

There are two panes:

Both panes are full code editors with JavaScript highlighting; syntax errors are underlined as you type.

Each pane header has an Enabled toggle — a script runs only when its pane is enabled, so you can keep a script on a request but switch it off without deleting it. Drag the divider between the two panes to resize them; the split is saved with the request.

When scripts run

Pre-request script  →  {{variables}} substituted  →  request sent
                                                         ↓
                          variables / UI updated  ←  After-response script

Because the pre-request script runs before variable substitution, a variable you set with hippo.variables.set(...) is available to the very request you are sending — {{thatVariable}} resolves with the new value. Variables set in either pane are also saved, so a later request can use them too.

The hippo API

Everything a script can do lives under the global hippo object. The surface is small and deliberately sandboxed (see Sandbox & limits).

Member Parameters Returns Available in Notes
hippo.variables.get(scope, name) scope: "global" | "environment" | "folder" · name: string string | undefined both Reads a variable from a specific scope. (A legacy "collection" is treated as "global".)
hippo.variables.set(scope, name, value) scope: "global" | "environment" · name: string · value: string void both Writes a variable; the value is saved for later requests. "folder" is read-onlyset throws. (A legacy "collection" is treated as "global".)
hippo.request.method · .url · .headers · .body string · string · object · string both Mutable in the pre-request script (changes the outgoing request); a read-only snapshot in the after-response script. In the pre-request pane these still contain {{templates}} — they are substituted after your script runs.
hippo.response.status · .time · .headers · .body number · number (ms) · object · string after-response only Reading these in a pre-request script throws — the response doesn't exist yet. .time is the elapsed response time in milliseconds.
hippo.response.json() parsed value after-response only Parses the response body as JSON; throws if the body isn't valid JSON.
hippo.environment { name, variables } both The active environment (read-only).
hippo.run(requestName) requestName: string literal { status, time, headers, body, json() } both Runs another saved request by name and returns its response (same shape as hippo.response). The name must be a string literal — see Run another request.
hippo.console.log / .info / .warn / .error ...args: any void both Logs to the response Console tab (see Console output).
hippo.test(name, fn) name: string · fn: function void after-response Runs fn as a named test; if it throws, the test fails (see Test assertions).
hippo.expect(value) value: any matcher after-response Returns a matcher with .toBe / .toEqual / .toContain / .toBeLessThan / .toBeGreaterThan / .toMatch / .toBeTruthy / .toBeFalsy (and .not), each throwing on mismatch.

Scopes follow the same precedence as everywhere else in Rest Hippo: folder → environment → global. get can read any of the three; set writes to global or environment (folder variables are read-only from a script). Global is the collection-wide tier.

Example: prepare the request (pre-request)

// Build an Authorization header from an environment variable.
const key = hippo.variables.get("environment", "apiKey");
hippo.request.headers["Authorization"] = "Bearer " + key;

// Or set a variable and reference it as {{token}} in the URL / headers — it is
// substituted into THIS request because the script runs before substitution.
hippo.variables.set("environment", "token", "abc123");

Example: run another request first (pre-request)

hippo.run("Name") runs another saved request and hands you back its response, so a script can chain a dependency — log in, grab a token, and use it on the request you are about to send:

// Log in first, then carry the token on this request.
const res = hippo.run("Login");
if (res.status === 200) {
  hippo.request.headers["Authorization"] = "Bearer " + res.json().token;
}

The returned response has the same shape as hippo.response: status, time (ms), headers, body, and json().

The request name must be a string literal — Rest Hippo finds and runs it before your script does, so a computed name like hippo.run(someVariable) can't work and throws. The named request runs with its own saved settings but does not run its own pre- or after-response scripts, so two requests can't recursively trigger each other. hippo.run works the same way in an after-response script.

Duplicate names. hippo.run("Name") matches by name, so if two saved requests share that name it runs the first one and shows a warning — give them distinct names to be sure. The cross-request function pills you insert into a field (run, response, responseHeader, responseStatus) don't have this problem: the picker stores the request's stable id, so they keep pointing at the same request even if you rename it, and the picker shows each request's folder path when a name is duplicated so you can tell them apart.

Example: capture from the response (after-response)

// On success, pull an id out of the JSON body and save it for a later request.
if (hippo.response.status === 200) {
  const body = hippo.response.json();
  hippo.variables.set("global", "userId", body.id);
  hippo.console.log("captured userId", body.id);
}

A following request can now use {{userId}} in its URL, headers, or body. (For simple field extraction without writing code, see also Captures.)

Test assertions

An after-response script can also validate the response, turning a request into an API check. Use hippo.test(name, fn) to declare a named test and hippo.expect(value) for the comparison — if the matcher (or anything inside the test) throws, the test is marked failed; otherwise it passes. Results appear on the response Tests tab with a pass/fail badge in the status bar.

hippo.test("status is 200", () => {
  hippo.expect(hippo.response.status).toBe(200);
});

hippo.test("responds quickly", () => {
  hippo.expect(hippo.response.time).toBeLessThan(500);
});

hippo.test("returns the right user", () => {
  const body = hippo.response.json();
  hippo.expect(body.id).toBe(42);
  hippo.expect(body.roles).toContain("admin");
});

Matchers: toBe (strict equality), toEqual (deep equality), toContain (substring / array member), toBeLessThan / toBeGreaterThan, toMatch (regex), toBeTruthy / toBeFalsy. Prefix any with .not to invert it, e.g. hippo.expect(hippo.response.status).not.toBe(500).

Prefer not to write code? The no-code Tests tab lets you build the same checks from a grid of source → matcher → expected rows. Grid assertions and scripted hippo.test() calls run together and share the one Tests tab.

Console output

hippo.console.log/info/warn/error(...) writes lines to the response Console tab, tagged so you can tell them apart from the HTTP verbose log. This is the easiest way to see what a script is doing — log a value, send the request, and read it back on the Console tab.

Errors

If a script throws, Rest Hippo surfaces it — it is never swallowed:

Sandbox & limits

Scripts run in a locked-down sandbox in Rest Hippo's main process. They cannot reach the filesystem, the network, process, or require, and eval / the Function constructor are disabled. A script that loops forever is stopped by a one-second timeout.

Scripts are synchronous — there is no await (there's nothing to wait for inside the sandbox). Keep them small: read a value, set a variable, log something. Even hippo.run("…") is synchronous: Rest Hippo runs the named request outside the sandbox before your script starts, then hands the response in — which is why the request name has to be a literal it can spot ahead of time.


Next: Import, Export & Backup →