Skip to main content
The rq.request object provides access to all details of the API request in your Requestly scripts. Read these properties in both pre-request and post-response scripts. In a pre-request script you can also change the request that is sent: its headers, query parameters, URL, method, body and auth are all writable. In a post-response script the request has already been sent, so changes have no effect on the wire.

What each script sees

When the request is sent:
  • Variables in values your script set are resolved, including dynamic variables such as {{$guid}}, the same as values you typed in the editor. A {{vault:...}} reference your script writes is resolved only when Allow scripts to access vault secrets is on; otherwise it is sent as written and the script console shows a warning.
  • The auth tab is applied after your scripts. A header or query parameter it adds replaces every header or query parameter with the same name, including one your script set. Header names are matched ignoring case; query parameter names are matched exactly. Auth that adds nothing, such as a bearer token left empty, leaves your header alone. To send an Authorization header from your script, set the request’s auth to No Auth.
  • Cookies are merged. If the request has its own Cookie header, saved or set by your script, its cookies come first and the cookie jar’s cookies for the URL follow in the same header.
  • Disabled headers and query parameters are never sent. Your script can read them and turn them on. See rq.request.headers and rq.request.url below.

Properties and Methods

rq.request.id

The request’s id.

rq.request.name

The request’s name. Example:

rq.request.description

The request’s description, or undefined when the request has none. It has:
  • content: the Markdown you wrote.
  • type: "text/markdown".
  • update(content, type) or update({ content, type }): changes the description in your script. type defaults to "text/plain".
  • toString(): the content, or "" when there is none.
  • toJSON(): { content, type }.
Example:

rq.request.method

The HTTP method of the request (e.g. GET, POST, PUT, OPTIONS, DELETE, PATCH, HEAD). Writable from a pre-request script: the value is uppercased on write (rq.request.method = 'post' sends POST), and it must be one of the methods above. Anything else is dropped with a console warning instead of being sent. Example:

rq.request.headers

The list of the request’s headers. Header names are matched ignoring case, and a name can appear more than once. Read a header with get(name), check for one with has(name), or get every header that is sent as a plain { name: value } object with all(). Use all() when you want to serialize the headers. Example:
The list also holds the headers you turned off in the editor, with disabled: true. They are not sent unless your script turns them on:
The methods that change the list change the headers that are sent with the request. Use them in pre-request scripts; in post-response scripts the request has already been sent, so header changes have no effect. Header changes apply to HTTP and GraphQL requests.

headers.add()

Adds a header. If a header with the same name already exists, this adds a second one (it does not replace the existing header). Parameters:
  • header (object or string): { key, value }, or a raw "Key: value" string (parsed at the first :, both sides trimmed). A header added with disabled: true is on the list but is not sent.
Example:

headers.upsert()

Replaces the value of the first header with the same name (matched ignoring case), or adds the header if there is none. Returns false when it replaced a value and true when it added a header. If the existing header is turned off, its value changes and it stays off, so it is not sent. Parameters:
  • header (object or string): { key, value }, or a "Key: value" string.
Example:

headers.remove()

Removes every header with the given name (matched ignoring case). Parameters:
  • name (string, function or header object): a name removes every header with that name. A function removes every header it returns true for, and a header object removes that header. Other headers with the same name stay.
Example:

headers.clear()

Removes all request headers. Parameters: none. Any argument passed is ignored. clear() always removes every header, so to remove a single header use remove(name) instead. Example:

headers.get()

Returns the value of the first header with that name, or undefined.

headers.one()

Returns the last header with that name as a header object (see Header objects), or undefined. Change the object to change the header that is sent.

headers.has()

Returns whether a header with that name exists. With a value, returns whether a header with that name has exactly that value. name can also be a header object.

headers.all()

Returns the headers that are sent as a { name: value } object. Disabled headers are left out, and a repeated name keeps its last value.

headers.toObject()

Returns the headers as an object. Names are lower-cased unless caseSensitive is true, and a repeated name becomes an array of values. Disabled headers are included unless excludeDisabled is true. With sanitizeKeys, headers with an empty name are left out.

Counting and positions

count() returns the number of headers, disabled ones included. idx(index) returns the header at that position. indexOf(header) returns the position of a header object, or of the last header with a given name, or -1.

Looping over headers

each(fn), map(fn), filter(fn), find(fn) and reduce(fn, initial) work like the array methods of the same name. Each callback receives the header object and its position. eachParent(fn) calls fn for each parent of the list. The header list has none, so fn is never called.

Adding at a position

insert(header, before), insertAfter(header, after), prepend(header) and append(header) add a header object or { key, value } definition at a position in the list: before the given header (or name), after it, first, or last. A string is ignored. The header is at that position in the list your script reads, but it is sent after the request’s other headers.

Adding many headers

populate() adds each header in a list of definitions, or in a string of Key: value lines. repopulate() removes every header first.

headers.assimilate()

assimilate(source, prune) upserts each header in source (a list of definitions, or another header list). With prune set to true, headers whose name is not in source are removed.

Converting the list

toString() returns Key: value lines, one per enabled header, each ending in \r\n. toJSON() returns every header as { key, value }, with disabled: true on the disabled ones. contentSize() returns the length of toString().

Header objects

Each header in the list is an object with:
  • key and value: the header’s name and value.
  • disabled: true when the header is turned off.
  • update({ key, value, disabled }): changes the header.
  • toString(): "Key: value". valueOf(): the value. toJSON(): { key, value, disabled }.
In a pre-request script, a change you make through a header object is sent, the same as one made through the list:

rq.request.addHeader()

Adds a header. Takes the same input as rq.request.headers.add(): { key, value } or a "Key: value" string.

rq.request.upsertHeader()

Replaces the value of a header with the same name, or adds the header. Parameters:
  • header (object): { key, value }. key must be a non-empty string; otherwise nothing happens.
Unlike rq.request.headers.upsert(), the name is matched case-sensitively: a differently-cased key adds a second header instead of replacing the existing one.

rq.request.removeHeader()

Removes every header with the given name. Parameters:
  • toRemove (string or object): the header name, or { key }.
  • options (object, optional): { ignoreCase: true } matches the name ignoring case.
Unlike rq.request.headers.remove(), the name is matched case-sensitively unless you pass { ignoreCase: true }.

rq.request.getHeaders()

Returns the headers as an object. A repeated name becomes an array of values. Parameters:
  • options (object, optional):
    • ignoreCase: true lower-cases the names.
    • enabled: true leaves out disabled headers.
    • sanitizeKeys: true leaves out headers with an empty name.

rq.request.forEachHeader()

Calls callback(header, request) for every header, disabled ones included. header is a header object and request is rq.request.

rq.request.body

The request body, as an object with mode, raw, urlencoded, formdata, graphql, file, options and disabled. It is undefined when the request has no body. A request with a binary file body reads as mode: "file", and a script cannot change a body to file mode (see below). It still reads as a string wherever JavaScript coerces: `${rq.request.body}`, String(rq.request.body), and JSON.parse(rq.request.body) all see the raw text. But it is an object, so string methods need rq.request.body.toString() first. Writable from a pre-request script. Whatever your script writes is sent as written, except that variables in it ({{name}}) are resolved when the request is sent. If you sign the body, resolve any variables in your script first, so the signature covers the bytes that are sent:
mode: 'file' is not supported: a script cannot choose local files to upload; the call is refused with a console warning and the body is left unchanged. On a body-less request rq.request.body is undefined, but assignment still works and creates the body. Example (reading):

rq.request.url

The request URL as an object. It converts to a string wherever one is expected ("Sending to " + rq.request.url, `${rq.request.url}`, new URL(String(rq.request.url))), and exposes the URL’s parts: getRaw() throws an error; use toString() instead. Example:
You can also edit the URL parts directly: rq.request.url.path.push("v2"), rq.request.url.host = ["api", "example", "com"], rq.request.url.port = "8443", or rq.request.url.update("https://...") to replace the whole URL (update() also takes a parts object). In a pre-request script every change applies to the request that is sent. In a post-response script the request has already been sent.
JSON.stringify(rq.request.url) returns the URL’s parts: { protocol, host: [...], port, path: [...], hash, query: [{ key, value }], variable: [...] }. Use rq.request.url.toString() when you want the URL as a string.
rq.request.url is an object, not a string. typeof rq.request.url is "object", a strict comparison such as rq.request.url === "https://..." is false, and string methods like .split() or .includes() are not available on it. Call rq.request.url.toString() first: rq.request.url.toString().split("?"), rq.expect(rq.request.url.toString()).to.equal(...).

url.query

The list of query parameters. Names are matched exactly (case-sensitive), and a name can appear more than once.
  • Read: get(name) and one(name) (the last parameter with that name), has(name, value), count(), idx(i), indexOf(...), each(fn), eachParent(fn), map(fn), filter(fn), find(fn), reduce(fn, initial), toString() (the query string without ?). all() returns an array of the parameter objects, disabled ones included (unlike rq.request.headers.all(), which returns a { name: value } object). toJSON() returns an array of { key, value }, with disabled: true on the disabled ones. toObject(excludeDisabled, caseSensitive, multiValue, sanitizeKeys) returns { name: value }; a repeated name becomes an array of values.
  • Change: add(param), insert(param, before), insertAfter(param, after), prepend(param), append(param), upsert(param), remove(name | fn), clear(), populate(list), repopulate(list), assimilate(list, prune). add, upsert, populate and repopulate take { key, value } or a "key=value" string. insert, insertAfter, prepend and append take a parameter object or { key, value }; a string is ignored. remove(name) removes the last parameter with that name; remove(fn) removes every parameter the function matches. Assigning a list, rq.request.url.query = [{ key, value }], replaces every parameter.
  • Each parameter is an object with key, value, disabled, update(param), toString() ("key=value"), valueOf() (the value) and toJSON(). In a pre-request script, a change you make through a parameter object is sent.
Query parameters you turned off in the editor are on the list with disabled: true and are not sent unless your script turns them on. rq.request.url.toString() and getQueryString() leave them out. A post-response script sees only the query parameters that were sent. rq.request.url.addQueryParams(params) and rq.request.url.removeQueryParams(params) add or remove several parameters at once.

url.variables

The list of the request’s path variables (:id in the URL). It has the same list methods as query, matched by exact name, except that get(name) and one(name) return the first variable with that name and remove(name) removes it. It also has:
  • replace(text, overrides): replaces every {{name}} in text with the variable’s value.
  • substitute(object, overrides, mutate): replace() applied to every string in an object or array.
  • syncFromObject(object, track, prune): sets variables from a { name: value } object. With prune, variables not in the object are removed.
  • syncToObject(object): writes the variables into a { name: value } object.
  • oneNormalizedVariable(name): the last enabled variable with that name, or else the variable with that name.
Each variable is an object with key, value, type, disabled, get(), set(value), update(definition), toString(), valueOf() and toJSON(). In a pre-request script, a change you make through a variable object is sent:
Assigning a list, rq.request.url.variables = [{ key, value }], replaces the path variables.

rq.request.queryParams

A read-only object mapping each enabled query parameter’s name to its value ({ name: value }), as the request was when the script started. Iterate it with Object.entries(). It does not show changes your script makes; read rq.request.url.query for those. Example:

rq.request.addQueryParams()

Adds query parameters. The same as rq.request.url.addQueryParams(). Parameters:
  • params: a { key, value } object, a "key=value" string, or a list of them.

rq.request.removeQueryParams()

Removes query parameters. The same as rq.request.url.removeQueryParams(). Parameters:
  • params: a name, a { key } object, or a list of them.

rq.request.auth

The request’s auth, which your script can read and change. It has:
  • type: bearer, basic, apikey, oauth1, oauth2, jwt, digest, hawk, awsv4, ntlm or noauth.
  • One parameter list per type, under the type’s name, for example rq.request.auth.bearer. Each list has the same methods as rq.request.url.variables: rq.request.auth.bearer.get("token").
  • parameters(): the parameter list of the type in use.
  • use(type, options): switches to type and sets its parameters from options, a { key: value } object or a list of { key, value }.
  • update(options, type): sets parameters of type, or of the type in use.
  • clear(type): empties the parameters of type. A type that is not in use is removed.
  • toJSON(): { type, <type>: [{ key, value, type }] } for each type the auth holds.
  • current(): throws an error; use parameters() instead.
In a pre-request script every change to the auth is sent, whether you make it with authorizeUsing(), the auth object’s methods, or a parameter object (rq.request.auth.parameters().one("token").value = "..."). Settings the parameters have no field for, such as an AWS profile name or an OAuth 2.0 grant’s settings, are kept when you change the parameters without changing the type. Reading the auth and writing it back unchanged changes nothing. Assigning rq.request.auth = ... has no effect; use authorizeUsing().
How the auth your script sets is sent:
  • OAuth 2.0 sends the token in accessToken (authorizeUsing("oauth2", { accessToken: "..." })). No new token is fetched.
  • JWT Bearer is signed from the key and claims your script gives it.
  • AWS Signature is signed with the access keys your script gives it. No AWS profile is read.
  • When one of these is missing its token or keys, or a JWT cannot be signed, the request is sent without auth and the script console shows a warning.
  • Any other type, such as edgegrid or asap, makes the request inherit its auth, with a console warning naming the type.

rq.request.authorizeUsing()

Replaces the request’s auth. Parameters:
  • type (string, object or null): the auth type, such as "bearer". null makes the request inherit its auth, and "noauth" sets it to No Auth. You can also pass one object, { type, ...parameters }.
  • options (object or list, optional): the type’s parameters, as a { key: value } object or a list of { key, value }.
Example:

rq.request.proxy

In a post-response script, the proxy the request was sent through: a proxy you configured in Requestly, or the one your system settings named. It is undefined in a pre-request script, when no proxy was used, and when the proxy came from environment variables. It has:
  • host, port, protocol ("http"), id.
  • username, password and authenticate (true when the proxy has credentials). A post-response script can read the proxy’s password.
  • tunnel, match (the URLs the proxy is used for, as a pattern) and bypass (URLs that skip it). Only the host, port and credentials come from the proxy the request used, so tunnel is false, match is http+https://*:*/* and bypass is undefined.
  • test(url): whether a request to that URL goes through the proxy. It is true for any http or https URL unless your script changed match or bypass with update().
  • getProxyUrl(): protocol://[username[:password]@]host:port, with the credentials only when authenticate is true.
  • getProtocols(): the protocols match covers.
  • update(definition), updateProtocols(protocols) and toJSON().
Changes your script makes to the proxy object stay in that script and are never sent.

rq.request.certificate

In a post-response script, the client certificate the request was sent with, from the certificates in App Settings. It is undefined in a pre-request script and when no client certificate was used. It has:
  • name: the host the certificate is set for. id: its host and port, such as "api.example.com:443".
  • matches: the URLs it is for, as a list of patterns.
  • cert.src and key.src for a PEM certificate, or pfx.src for a PFX bundle: the file paths. The contents of the certificate files are never shown.
  • passphrase: when the certificate has one. A post-response script can read it.
  • canApplyTo(url): whether the certificate is sent to that URL. Always false for a URL that is not https.
  • update(definition) and toJSON().
Changes your script makes to the certificate object stay in that script and are never sent.

rq.request.update()

Changes several parts of the request at once. Only the keys you pass change. Parameters:
  • definition (object):
    • url: a URL string or a parts object.
    • method: the method. null means GET.
    • header: replaces every header. A list of { key, value }, or a string of Key: value lines.
    • body: a raw string, a body definition such as { mode: "raw", raw: "..." }, or null to send without a body.
    • auth: replaces the auth, as { type, <type>: [{ key, value }] }. A falsy value changes nothing.
    • proxy, certificate: replace those objects in your script only.
Example:

rq.request.clone()

Returns a detached copy of the request. Changing the copy changes nothing that is sent.

rq.request.size()

Returns the request’s size in bytes as { body, header, total, source }. body comes from a numeric Content-Length header when there is one (source is "CONTENT-LENGTH"), and otherwise from the body’s UTF-8 length (source is "COMPUTED"). header counts the request line and the enabled headers.

rq.request.toJSON()

Returns the request as a plain object: id, name, description, url, header (every header, left out when there are none), method, body, auth, proxy and certificate when the request has them, plus headers (a { name: value } object of the enabled headers) and queryParams. JSON.stringify(rq.request) returns the same.

rq.request.to

Assertions about the request, for use inside rq.test():
  • to.have.header(name): a header with that name is present (matched ignoring case). Headers that are turned off count.
  • to.have.header(name, value): the last header with that name has exactly that value.
  • to.be.ok: always passes for the request.
  • to.be.a.postmanRequest and to.be.a.postmanRequestOrResponse pass, and to.be.a.postmanResponse fails, because rq.request is a request. to.be.an.* and to.be.* work the same as to.be.a.*.
  • to.not.have and to.not.be negate each assertion.

Common Use Cases

Logging Request Details

Conditional Logic Based on Request Method

Accessing Query Parameters

Adding an Authentication Header

If the request’s auth tab adds an Authorization header, it replaces this one. Set the request’s auth to No Auth to send the header your script sets, or set the token through the request’s auth instead: