Skip to content

Script reference

Everything a script can reach.

This is Sendwire's scripting surface — the objects available inside a pre-request or post-response script. It is not a web API: Sendwire has no server and exposes no HTTP endpoints of its own.

Everything below is available bare as well — response works exactly as sw.response does — so a pasted snippet usually runs unchanged.

There is no pm

Importing a Postman collection rewrites pm to sw automatically. Type it anyway and the editor underlines it before you run anything; run it anyway and you get an error naming the sw equivalent.

sw.response

Only available in a post-response script. There is no response before the request has been sent.

codeStatus code, as a number. 200
statusStatus text. "OK"
responseTimeTotal milliseconds.
sizeBody size in bytes.
text()The body, unparsed.
json()The body parsed as JSON. Throws if it is not.
xml()The body as a plain object.
soapBody()Inside <soap:Body>, as an object.
xmlValue(name)The text of the first element with that local name.
xmlValues(name)The text of every element with that local name.
soapFault()The fault as an object, or null.
headers.get(name)One header, case-insensitively.
headers.has(name)Whether it is present.
headers.all()Every header, as { key, value }.
connectionAddress, port, reuse, ALPN.
certificateThe leaf certificate the server presented.
js
sw.test("the order was created", () => {
  sw.expect(sw.response.code).to.equal(201)
  sw.expect(sw.response.json().status).to.equal("active")
  sw.expect(sw.response.headers.get("content-type")).to.include("json")
})

Namespace prefixes are ignored by the XML helpers, so soapBody().return works whether the server wrote <return> or <ns2:return>.

sw.environment

The active environment. Values set here are visible to every later request as {{name}}, and are written to your workspace.

get(key)The value, or undefined.
set(key, value)Store it. Non-strings are stringified.
unset(key)Remove it.
has(key)Whether it is set.
toObject()Everything, as a plain object.

sw.globals and sw.collectionVariables are the same object under different names, so Postman scripts that use them keep working.

js
// Capture it in one request
sw.environment.set("token", sw.response.json().data.token)

// Spend it in the next
// Authorization: Bearer {{token}}

sw.environment.get("token")
sw.environment.has("token")
sw.environment.unset("token")

sw.variables

Reading, plus one thing environment cannot do.

get(key)The value.
set(key, value)Same as environment.set.
has(key)Whether it is set.
replaceIn(text)Substitute every {{name}} in a string.

replaceIn is how you reach the dynamic values:

js
sw.environment.set("nonce", sw.variables.replaceIn("{{$guid}}"))
sw.environment.set("sentAt", sw.variables.replaceIn("{{$isoTimestamp}}"))

sw.request

The request about to be sent. Only useful in a pre-request script — afterwards it has already gone.

js
sw.request.headers.upsert({
  key: "X-Signature",
  value: sw.crypto.hmacSha256(sw.environment.get("apiSecret"), "message")
})

upsert replaces any header of the same name rather than adding a second one.

sw.test and sw.expect

js
sw.test("name", () => {
  sw.expect(actual).to.equal(expected)
})

Each test is one line in the Scripts tab, and one assertion in a suite run or a CI report. A test that throws fails; a test that returns passes.

The matchers, all of which chain through .to, .be and .not:

.equal(x)Strictly equal.
.eql(x)Deeply equal.
.above(n) / .below(n)Greater / less than.
.least(n) / .most(n)At least / at most.
.include(x)Substring, array member, or subset of an object.
.match(re)Matches a regular expression.
.property(key)Has that own property.
.a(type)"string", "number", "array", "object", "null"
.lengthOf(n)Has that length.
.okTruthy.
.nullExactly null.
js
sw.expect(sw.response.responseTime).to.be.below(500)
sw.expect(sw.response.json().items).to.have.lengthOf(2)
sw.expect(sw.response.json().name).to.not.equal("")

sw.crypto

Signing, hashing and nonces, without pulling in a library.

hmacSha256(key, message)Hex.
hmacSha256Base64(key, message)Base64.
hmacSha1Base64(key, message)Base64. Some older APIs still want this.
sha256(message)Hex.
md5(message)Hex. Checksums only — not for anything security-bearing.
base64(text)Encode.
randomUUID()A v4 UUID.
randomInt(min, max)Inclusive of both ends.
nonce(bytes = 16)Random hex.

A signed request, in a pre-request script:

js
const stamp = Math.floor(Date.now() / 1000)
const nonce = sw.crypto.nonce()

const signature = sw.crypto.hmacSha256(
  sw.environment.get("apiSecret"),
  `${stamp}\n${nonce}\nPOST\n/v1/orders`
)

sw.request.headers.upsert({ key: "X-Signature", value: signature })
sw.request.headers.upsert({ key: "X-Timestamp", value: String(stamp) })

sw.sendRequest

Another request from inside a script — a token fetch before the real call, most often. Pre-request scripts wait for it.

js
sw.sendRequest("https://auth.example.com/token", (error, response) => {
  if (error) throw error
  sw.environment.set("token", response.json().access_token)
})

Or with options, and awaited:

js
const response = await sw.sendRequest({
  url: "https://auth.example.com/token",
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ client_id: sw.environment.get("clientId") })
})
sw.environment.set("token", response.json().access_token)

There is a limit on how many a single script may send, so a loop that has lost its exit condition stops rather than hammering somebody's API.

sw.console

log, warn, error and info. Output appears in the Scripts tab beside the test results, not in a devtools console you would have to open.

Also available

btoa and atob for base64, and the ordinary JavaScript standard library — JSON, Math, Date, Object, Array, String, RegExp, Promise. It is real JavaScript, so if it runs in JavaScript it runs here.

Not available

No require, no import, no filesystem, no network except sw.sendRequest. Scripts run in a sandbox with a time limit, so an accidental infinite loop fails that request instead of freezing the application.

No account. No cloud. No telemetry.