Skip to main content
  • hopp [Experimental]
  • pw [Legacy]
It is not recommended to migrate or reformat your existing scripts to the new scripting APIs at this time. Upcoming updates are expected to introduce breaking changes as we continue to refine and improve the scripting experience.The current rollout is intentionally gradual, allowing us to gather user feedback and iterate based on real-world usage.All further updates to scripting will be scoped to the experimental scripting sandbox, which is the default, and the preference can be updated from Settings → Experiments.Your feedback will be invaluable as we shape the next generation of Hoppscotch scripting.
This new experimental implementation provides a robust foundation for API scripting with enhanced capabilities for environment management, request manipulation, response processing, cookie handling, and comprehensive testing. The new system maintains backwards compatibility while introducing powerful new features for modern API testing workflows.

hopp.env Namespace

Environment variable management with scope-specific operations and enhanced functionality.

hopp.env.get(key: string)

Retrieves the value of the selected environment’s variable. Accepts an environment variable as an argument.
hopp.env.get("variable");
hopp.env.get("baseURL");

hopp.env.getRaw(key: string)

Retrieves the raw value of the selected environment’s variable without variable resolution.
hopp.env.getRaw("variable");

hopp.env.set(key: string, value: string)

Sets the value of an environment variable in the selected environment.
hopp.env.set("baseURL", "https://httpbin.org");

hopp.env.delete(key: string)

Deletes an environment variable from the selected environment.
hopp.env.delete("baseURL");

hopp.env.reset(key: string)

Resets an environment variable to its initial value in the selected environment.
hopp.env.reset("baseURL");

hopp.env.getInitialRaw(key: string)

Retrieves the initial raw value of an environment variable.
hopp.env.getInitialRaw("baseURL");

hopp.env.setInitial(key: string, value: string)

Sets the initial value of an environment variable.
hopp.env.setInitial("baseURL", "https://httpbin.org");

Active Environment Scope

Operations specific to the currently active environment.

hopp.env.active.get(key: string)

Retrieves the value of the active environment’s variable.
hopp.env.active.get("variable");

hopp.env.active.getRaw(key: string)

Retrieves the raw value of the active environment’s variable.
hopp.env.active.getRaw("variable");

hopp.env.active.set(key: string, value: string)

Sets the value of an active environment variable.
hopp.env.active.set("baseURL", "https://httpbin.org");

hopp.env.active.delete(key: string)

Deletes a variable from the active environment.
hopp.env.active.delete("baseURL");

hopp.env.active.reset(key: string)

Resets a variable in the active environment to its initial value.
hopp.env.active.reset("baseURL");

hopp.env.active.getInitialRaw(key: string)

Retrieves the initial raw value of an active environment variable.
hopp.env.active.getInitialRaw("baseURL");

hopp.env.active.setInitial(key: string, value: string)

Sets the initial value of an active environment variable.
hopp.env.active.setInitial("baseURL", "https://httpbin.org");

Global Environment Scope

Operations specific to the global environment.

hopp.env.global.get(key: string)

Retrieves the value of the global environment’s variable.
hopp.env.global.get("variable");

hopp.env.global.getRaw(key: string)

Retrieves the raw value of the global environment’s variable.
hopp.env.global.getRaw("variable");

hopp.env.global.set(key: string, value: string)

Sets the value of a global environment variable.
hopp.env.global.set("baseURL", "https://httpbin.org");

hopp.env.global.delete(key: string)

Deletes a variable from the global environment.
hopp.env.global.delete("baseURL");

hopp.env.global.reset(key: string)

Resets a variable in the global environment to its initial value.
hopp.env.global.reset("baseURL");

hopp.env.global.getInitialRaw(key: string)

Retrieves the initial raw value of a global environment variable.
hopp.env.global.getInitialRaw("baseURL");

hopp.env.global.setInitial(key: string, value: string)

Sets the initial value of a global environment variable.
hopp.env.global.setInitial("baseURL", "https://httpbin.org");

hopp.request Namespace

Request manipulation with immutable properties and dedicated mutation functions.

Read-only Properties

hopp.request.url

The request URL as a string.
const url = hopp.request.url;

hopp.request.method

The HTTP method of the request.
const method = hopp.request.method;

hopp.request.params

The query parameters of the request.
const params = hopp.request.params;

hopp.request.headers

The headers of the request.
const headers = hopp.request.headers;

hopp.request.body

The body of the request.
const body = hopp.request.body;

hopp.request.auth

The authentication configuration of the request.
const auth = hopp.request.auth;

Mutation Functions (Pre-request Phase Only)

hopp.request.setUrl(url: string)

Sets the request URL.
hopp.request.setUrl("https://api.example.com/users");

hopp.request.setMethod(method: string)

Sets the HTTP method of the request.
hopp.request.setMethod("POST");

hopp.request.setHeader(name: string, value: string)

Sets a header on the request.
hopp.request.setHeader("Authorization", "Bearer token");

hopp.request.setHeaders(headers: HoppRESTHeader[])

Sets multiple headers on the request.
hopp.request.setHeaders([{ key: "Content-Type", value: "application/json" }]);

hopp.request.removeHeader(name: string)

Removes a header from the request.
hopp.request.removeHeader("Authorization");

hopp.request.setParam(name: string, value: string)

Sets a query parameter on the request.
hopp.request.setParam("userId", "123");

hopp.request.setParams(params: HoppRESTParam[])

Sets multiple query parameters on the request.
hopp.request.setParams([{ key: "userId", value: "123" }]);

hopp.request.removeParam(name: string)

Removes a query parameter from the request.
hopp.request.removeParam("userId");

hopp.request.setBody(body: Partial<HoppRESTReqBody>)

Sets the body of the request.
hopp.request.setBody({ body: '{"key": "value"}' });

hopp.request.setAuth(auth: Partial<HoppRESTAuth>)

Sets the authentication for the request.
hopp.request.setAuth({ authType: "bearer", token: "token" });

Request Variables

hopp.request.variables.get(key: string)

Retrieves the value of a request variable.
const value = hopp.request.variables.get("varName");

hopp.request.variables.set(key: string, value: string)

Sets the value of a request variable.
hopp.request.variables.set("varName", "value");
Please note that only updates to request variables get persisted and reflected in the UI while the remaining are specific to the session.

hopp.response Namespace

Response access with multiple data formats and comprehensive metadata.

Response Metadata

hopp.response.statusCode

The HTTP status code of the response.
const status = hopp.response.statusCode;

hopp.response.statusText

The status text of the response.
const statusText = hopp.response.statusText;

hopp.response.headers

The headers of the response.
const headers = hopp.response.headers;

hopp.response.responseTime

The response time in milliseconds.
const time = hopp.response.responseTime;

Response Body Access Methods

hopp.response.body.asJSON()

Parses the response body as JSON.
const data = hopp.response.body.asJSON();

hopp.response.body.asText()

Returns the response body as text.
const text = hopp.response.body.asText();

hopp.response.body.bytes()

Returns the response body as a Uint8Array.
const bytes = hopp.response.body.bytes();

hopp.cookies Namespace

Domain-aware cookie management with comprehensive CRUD operations.

hopp.cookies.get(domain: string, cookieName: string)

Retrieves a cookie by domain and name.
const cookie = hopp.cookies.get("example.com", "sessionId");
Sets a cookie for a domain.
hopp.cookies.set("example.com", {
  name: "session_id",
  value: "abc123",
  domain: "api.example.com",
  path: "/api",
  expires: new Date(Date.now() + 86400000).toISOString(), // 24 hours from now
  maxAge: 86400, // 24 hours in seconds
  httpOnly: true,
  secure: true,
  sameSite: "Lax",
});

hopp.cookies.has(domain: string, cookieName: string)

Checks if a cookie exists for a domain.
const exists = hopp.cookies.has("example.com", "sessionId");

hopp.cookies.getAll(domain: string)

Retrieves all cookies for a domain.
const cookies = hopp.cookies.getAll("example.com");

hopp.cookies.delete(domain: string, cookieName: string)

Deletes a cookie for a domain.
hopp.cookies.delete("example.com", "sessionId");

hopp.cookies.clear(domain: string)

Clears all cookies for a domain.
hopp.cookies.clear("example.com");

hopp.test and hopp.expect Testing Framework

Comprehensive testing API with custom assertions and Chai.js-powered BDD assertions for advanced API testing.

hopp.test(testName: string, testFunction: () => void)

Creates a group of tests with a name.
hopp.test("API Tests", () => {
  hopp.expect(1).toBe(1);
});

hopp.expect(actual: any)

Returns an expectation object for assertions. Hoppscotch extends the testing framework with comprehensive Chai.js BDD assertion support, enabling advanced testing patterns with 50+ assertion methods.
hopp.expect(value).toBe(expected);

Basic Custom Assertions

hopp.expect(value).toBe(expected: any)

Tests for exact equality.
hopp.expect(1).toBe(1);

hopp.expect(value).toBeType(type: string)

Tests for type equality.
hopp.expect("hello").toBeType("string");

hopp.expect(value).toHaveLength(number: number)

Tests that a value has a specific length.
hopp.expect([1,2,3]).toHaveLength(3);

hopp.expect(value).toInclude(item: any)

Tests that a value includes an item.
hopp.expect([1,2,3]).toInclude(2);

HTTP Status Code Level Assertions

hopp.expect(statusCode).toBeLevel2xx()

Tests that the status code is in the 2xx range.
hopp.expect(200).toBeLevel2xx();

hopp.expect(statusCode).toBeLevel3xx()

Tests that the status code is in the 3xx range.
hopp.expect(302).toBeLevel3xx();

hopp.expect(statusCode).toBeLevel4xx()

Tests that the status code is in the 4xx range.
hopp.expect(404).toBeLevel4xx();

hopp.expect(statusCode).toBeLevel5xx()

Tests that the status code is in the 5xx range.
hopp.expect(500).toBeLevel5xx();

Negation Support

All assertions support .not for negation.
hopp.expect(1).not.toBe(2);
hopp.expect("hello").not.toBeType("number");
hopp.expect([1,2]).not.toHaveLength(3);
hopp.expect([1,2]).not.toInclude(3);
hopp.expect(200).not.toBeLevel4xx();

Chai.js Assertion Support

Hoppscotch includes comprehensive Chai.js BDD assertion support through hopp.expect() for native scripts and pm.expect() for Postman compatibility, enabling advanced testing patterns with 50+ assertion methods.

Type Assertions

Check value types and instances:
// Basic type checking
hopp.test("Type validation", () => {
  hopp.expect(hopp.response.statusCode).to.be.a('number')
  hopp.expect(hopp.response.body.asJSON()).to.be.an('object')
  hopp.expect([1, 2, 3]).to.be.an.instanceOf(Array)
  hopp.expect(new Date()).to.be.an.instanceOf(Date)
})

Equality Assertions

Test for strict and deep equality:
hopp.test("Equality checks", () => {
  hopp.expect(hopp.response.statusCode).to.equal(200)
  hopp.expect(hopp.response.body.asJSON()).to.eql({ userId: 1, name: 'John' })
  hopp.expect(hopp.response.statusCode).to.deep.equal(200)
})

Property Assertions

Validate object properties and nested structures:
hopp.test("Response structure", () => {
  const data = hopp.response.body.asJSON()
  hopp.expect(data).to.have.property('userId')
  hopp.expect(data).to.have.own.property('email')
  hopp.expect(data).to.have.nested.property('profile.name')
  hopp.expect(data).to.have.all.keys('id', 'name', 'email')
  hopp.expect(data).to.have.any.keys('id', 'name')
})

Collection and Array Assertions

Validate arrays and collections:
hopp.test("Array validation", () => {
  const tags = hopp.response.body.asJSON().tags
  hopp.expect(tags).to.have.lengthOf(3)
  hopp.expect(tags).to.include('nodejs')
  hopp.expect(tags).to.have.members(['nodejs', 'javascript', 'api'])
  hopp.expect(tags).to.have.ordered.members(['api', 'javascript', 'nodejs'])
})

Numeric Comparisons

Perform numeric comparisons and range checks:
hopp.test("Numeric assertions", () => {
  const responseTime = hopp.response.responseTime
  hopp.expect(responseTime).to.be.below(500)
  hopp.expect(responseTime).to.be.above(0)
  hopp.expect(responseTime).to.be.within(0, 1000)
  hopp.expect(3.14159).to.be.closeTo(3.14, 0.01)
})

String Assertions

Validate string content and patterns:
hopp.test("String validation", () => {
  const contentType = hopp.response.headers['content-type']
  hopp.expect(contentType).to.include('application/json')
  hopp.expect(contentType).to.match(/^application\/json/)
  hopp.expect('hello').to.have.lengthOf(5)
})

Boolean State Assertions

Check boolean values and states:
hopp.test("Boolean checks", () => {
  hopp.expect(true).to.be.true
  hopp.expect(false).to.be.false
  hopp.expect(1).to.be.ok
  hopp.expect(null).to.be.null
  hopp.expect(undefined).to.be.undefined
  hopp.expect({}).to.exist
  hopp.expect([]).to.not.be.empty
})

Complex Assertion Chains

Combine multiple assertions for comprehensive validation:
hopp.test("Complex validation", () => {
  const data = hopp.response.body.asJSON()
  hopp.expect(data)
    .to.be.an('object')
    .and.have.property('userId')
    .that.is.a('number')
    .and.is.above(0)
})

Real-World Example: API Pagination

hopp.test("Pagination metadata validation", () => {
  const data = hopp.response.body.asJSON()
  
  // Validate pagination structure
  hopp.expect(data).to.have.all.keys('items', 'page', 'total', 'hasMore')
  hopp.expect(data.items).to.be.an.instanceOf(Array)
  hopp.expect(data.items).to.have.lengthOf.at.most(50)
  
  // Validate each item
  data.items.forEach(item => {
    hopp.expect(item).to.have.all.keys('id', 'name', 'createdAt')
    hopp.expect(item.id).to.be.a('string')
  })
  
  // Store next page cursor
  if (data.hasMore) {
    hopp.env.active.set('nextPage', String(data.page + 1))
  }
})

Complete Assertion Reference

Type assertions:
  • .a(type) / .an(type) - Check value type
  • .instanceof(constructor) - Check instance type
Equality assertions:
  • .equal(value) / .eq(value) - Strict equality (===)
  • .eql(value) - Deep equality
Property assertions:
  • .property(name) - Has property
  • .own.property(name) - Has own property (not inherited)
  • .nested.property(path) - Has nested property (e.g., ‘a.b.c’)
Collection assertions:
  • .include(value) / .contain(value) - Contains value
  • .members(array) - Has members (order-independent)
  • .ordered.members(array) - Has members in order
  • .keys(...keys) - Has keys
  • .lengthOf(n) - Length equals n
  • .lengthOf.at.least(n) - Minimum length
  • .lengthOf.at.most(n) - Maximum length
Comparison assertions:
  • .above(n) / .gt(n) - Greater than
  • .below(n) / .lt(n) - Less than
  • .at.least(n) / .gte(n) - Greater than or equal
  • .at.most(n) / .lte(n) - Less than or equal
  • .within(min, max) - Within range
  • .closeTo(expected, delta) - Approximately equal
Boolean assertions:
  • .ok - Truthy
  • .true - Strictly true
  • .false - Strictly false
  • .null - Strictly null
  • .undefined - Strictly undefined
  • .exist - Not null or undefined
  • .empty - Empty (string, array, object)
String assertions:
  • .match(regex) - Matches regular expression
  • .string(substring) - Contains substring
Function assertions:
  • .throw() / .throw(ErrorType) - Throws error
  • .respondTo(method) - Has method
Object state assertions:
  • .extensible - Object.isExtensible()
  • .sealed - Object.isSealed()
  • .frozen - Object.isFrozen()
Modifiers:
  • .not - Negation
  • .deep - Deep comparison
  • .own - Own properties only
  • .ordered - Order matters
  • .nested - Nested property access
  • .all - All items/keys
  • .any - Any items/keys
  • .to / .be / .is / .that / .and / .have / .with - Language chains for readability

pm Namespace - Postman Compatibility Layer

Postman API compatibility for seamless migration with experimental Postman collection import support (v2.0/v2.1). The pm namespace provides pm.expect() with full Chai.js assertion support for Postman-compatible testing.
Experimental Script Import: When importing Postman collections, Hoppscotch can now import pre-request scripts and test scripts (experimental feature requiring user consent). This enables you to migrate your existing Postman workflows including their scripting logic.

Core APIs

// Environment and variable management
pm.environment.get(key: string): string | null
pm.environment.set(key: string, value: string): void
pm.environment.unset(key: string): void
pm.environment.has(key: string): boolean

pm.globals.get(key: string): string | null
pm.globals.set(key: string, value: string): void
pm.globals.unset(key: string): void
pm.globals.has(key: string): boolean

pm.variables.get(key: string): string | null
pm.variables.set(key: string, value: string): void
pm.variables.has(key: string): boolean
pm.variables.replaceIn(template: string): string

// Request access (read-only)
pm.request.url: URL-like (toString available; additional properties may be limited initially)
pm.request.method: string
pm.request.headers: HoppRESTHeader[]
pm.request.body: HoppRESTReqBody
pm.request.auth: HoppRESTAuth

// Response access (post-request only)
pm.response.code: number
pm.response.status: string
pm.response.responseTime: number  // ms
pm.response.json(): Record<string, any>
pm.response.text(): string
pm.response.headers.get(name: string): string | null
pm.response.headers.has(name: string): boolean
pm.response.headers.all(): HoppRESTResponseHeader[]
pm.response.stream: Uint8Array  // Raw response bytes

// Testing integration
pm.test(testName: string, testFunction: () => void): void
pm.expect(actual: any): Expectation

// Script context information
pm.info.eventName: string  // "pre-request" or "post-request"
pm.info.requestName: string
pm.info.requestId: string

// Asynchronous requests
pm.sendRequest(request: string | Object, callback: (err: any, res: any) => void): void

Postman Chai.js Assertions

Use pm.expect() with full Chai.js BDD assertion support for Postman-compatible scripts:
// Basic assertions
pm.test("Status code is 200", () => {
  pm.expect(pm.response.code).to.equal(200)
  pm.expect(pm.response.responseTime).to.be.below(500)
})

// Response body validation
pm.test("Response structure", () => {
  const jsonData = pm.response.json()
  pm.expect(jsonData).to.have.property('success')
  pm.expect(jsonData.success).to.be.true
  pm.expect(jsonData.data).to.be.an('array')
})

// Array validation
pm.test("Array contains expected items", () => {
  const items = pm.response.json().items
  pm.expect(items).to.have.lengthOf.at.least(1)
  pm.expect(items).to.include('apple')
  pm.expect(items).to.have.members(['apple', 'banana', 'cherry'])
})

// Header validation
pm.test("Headers are correct", () => {
  pm.expect(pm.response.headers.get('content-type')).to.include('application/json')
})

Postman Response Assertions

Postman-specific response validation methods:
pm.test("Response validation", () => {
  pm.expect(pm.response.to.have.status(200))
  pm.expect(pm.response.to.have.header('content-type'))
  pm.expect(pm.response.to.have.body())
  pm.expect(pm.response.to.have.jsonBody())
  pm.expect(pm.response.to.be.ok) // 2xx status
  pm.expect(pm.response.to.be.json)
})

pm.test("JSON body validation", () => {
  pm.expect(pm.response.to.have.jsonBody('userId'))
  pm.expect(pm.response.to.have.jsonBody('profile.name'))
  pm.expect(pm.response.to.have.jsonSchema({
    type: 'object',
    required: ['userId', 'email'],
    properties: {
      userId: { type: 'number' },
      email: { type: 'string' }
    }
  }))
})

OAuth Token Handling Example

pm.test("OAuth token handling", () => {
  const response = pm.response.json()
  const expiresIn = response.expires_in // 3600 seconds
  const expiryTime = Date.now() + (expiresIn * 1000)

  // Auto-converts number to string
  pm.environment.set('token_expiry', expiryTime)
  pm.environment.set('access_token', response.access_token)

  // Verify storage
  pm.expect(pm.environment.get('access_token')).to.equal(response.access_token)
})

PM-Specific Response Assertions

The following assertions are specific to the Postman compatibility layer:
  • pm.response.to.have.status(code) - Status code check
  • pm.response.to.have.header(name) - Header existence
  • pm.response.to.have.body() - Has response body
  • pm.response.to.have.jsonBody() - JSON body exists
  • pm.response.to.have.jsonBody(path) - JSON property exists
  • pm.response.to.have.jsonSchema(schema) - Validates JSON schema
  • pm.response.to.be.ok - 2xx status code
  • pm.response.to.be.success - Alias for ok
  • pm.response.to.be.json - JSON content type

Sending Requests

The pm.sendRequest method allows you to send HTTP requests asynchronously from your scripts. This is useful for chaining requests or fetching data from other APIs.
pm.sendRequest("https://postman-echo.com/get", (err, res) => {
  if (err) {
    console.log(err);
  } else {
    pm.expect(res).to.have.property('code', 200);
    pm.expect(res).to.have.property('status', 'OK');
  }
});

Unsupported Postman Features

The following Postman features are not currently supported:
  • pm.visualizer
  • pm.collectionVariables
  • pm.iterationData
  • pm.execution.setNextRequest()
  • Legacy patterns like global responseBody variable, require(), etc.
These limitations are documented in error messages when attempting to use unsupported APIs. The supported version range for Postman collections is v2.0/v2.1.

pw Namespace - Legacy Compatibility

Maintained for backwards compatibility with existing scripts:
// Legacy environment operations
pw.env.get(key: string): string | null
pw.env.getResolve(key: string): string | null
pw.env.set(key: string, value: string): void
pw.env.unset(key: string): void
pw.env.resolve(template: string): string

// Legacy response access
pw.response.status: number
pw.response.body: any
pw.response.headers: HoppRESTResponseHeader[]

// Legacy testing framework
pw.test(testName: string, testFunction: () => void): void
pw.expect(actual: any): Expectation
Cookies are represented as objects with the following properties:
type Cookie = {
  name: string           // Cookie name
  value: string          // Cookie value
  domain: string         // Domain the cookie belongs to
  path: string           // Path scope of the cookie (default: "/")
  expires?: string       // Expiration date in ISO format, null for session cookies
  maxAge?: number        // Maximum age in seconds, null if not set
  httpOnly: boolean      // Whether cookie is HTTP-only
  secure: boolean        // Whether cookie should only be sent over HTTPS
  sameSite: 'None' | 'Lax' | 'Strict'  // SameSite attribute
}

Usage Examples

Environment Management

// Set and get environment variables
hopp.env.set("api_token", "abc123")
const token = hopp.env.get("api_token")

// Scope-specific operations
hopp.env.global.set("base_url", "https://api.example.com")
hopp.env.active.set("user_id", "12345")

// Reset to initial values
hopp.env.reset("api_token")

Request Manipulation

// Modify request before sending
hopp.request.setHeader("Authorization", "Bearer " + hopp.env.get("token"))
hopp.request.setUrl("https://api.example.com/users/" + hopp.env.get("user_id"))
hopp.request.setMethod("POST")

Response Testing

hopp.test("API responds successfully", () => {
  hopp.expect(hopp.response.statusCode).toBeLevel2xx()
  hopp.expect(hopp.response.responseTime).toBe(1000)

  const data = hopp.response.body.asJSON()
  hopp.expect(data).toBeType("object")
  hopp.expect(data.users).toHaveLength(10)
})
// Set authentication cookie
hopp.cookies.set("api.example.com", {
  name: "session_id",
  value: "abc123",
  domain: "api.example.com",
  path: "/api",
  expires: new Date(Date.now() + 86400000).toISOString(), // 24 hours from now
  maxAge: 86400, // 24 hours in seconds
  httpOnly: true,
  secure: true,
  sameSite: "Lax",
})

// Check if cookie exists
if (hopp.cookies.has("api.example.com", "session_id")) {
  const cookie = hopp.cookies.get("api.example.com", "session_id")
  hopp.env.set("session_token", cookie.value)
}