Variables & Computed Fields

Chain requests with {{name}} variables, extractors, and the computed-field DSL.

Multi-step flows rarely replay from static bytes: a login returns a session token, a derived cookie must be re-signed per send, a nonce has to match in two places at once. The Replay dialog (API lab → route catalog → Replay on a request) substitutes {{…}} templates in the URL, headers, and body at send time — from saved chain variables, from values extracted out of earlier responses, and from an expression DSL that recomputes derived tokens per send.

Chain requests with {{name}} variables

A template is {{name}} (whitespace inside braces is fine). Names must match [A-Za-z_][A-Za-z0-9_.-]*. At send time every occurrence in the draft URL, headers, and body is replaced with the value.

  1. In the Replay dialog, find the Replay chain variables panel.
  2. Enter a name and value, click Add. The chip list shows current variables; values are masked until you reveal secrets.
  3. Reference it in any editable field, e.g. Authorization: Bearer {{token}} or /users/{{userId}}, then replay.

Variables persist locally in localStorage under the key traffic-jam:replay-variables, so they survive dialog closes and page reloads and feed the next request in the chain. Delete a chip with its trash button.

If a referenced variable has no value, the template is left in place and the panel shows an unresolved: name badge; the replay is blocked until you define it or remove the reference.

[!NOTE] Replay excludes captured credentials by default and asks for confirmation before state-changing methods. Variables you type are treated as deliberate values and sent as entered — only test systems you are authorized to test.

Extract values from a response

After a replay completes, the Extract response into chain panel appears under the result and saves one value from the response as a workspace variable.

SourceExpressionNotes
JSON path$.access_token, $.users[0].idLeading $. optional; [n] indexes arrays. Non-string values are JSON-stringified. Errors if the body is not JSON or the path is absent.
Headerx-session-tokenCase-insensitive; response trailers are searched too.
Regex"token":"([^"]+)"First capture group wins; with no group, the whole match.

Pick the source, type the expression and a variable name, click Extract. On success you get Saved {{name}} for the next replay; the variable joins the same persisted store as manually added ones.

Computed fields: the expression DSL

Plain {{name}} substitution is a fast path; anything more complex inside the braces is evaluated as an expression against the captured request’s context at send time — covering derived tokens that cannot be copied verbatim because they change with every request.

Field references read from the captured request:

ReferenceResolves to
cookie:nameCookie parsed from the captured Cookie header (first occurrence wins)
header:nameCaptured request header (case-insensitive)
query:nameQuery parameter (URL-decoded)
var:nameA chain variable (same as bare name)
bodyCaptured request body text (empty if truncated)

Functions (multiple arguments are concatenated before hashing; for HMAC the first argument is the key):

FunctionOutput
sha1(x) / sha256(x) / md5(x)Lowercase hex digest
hmac-sha1(key, msg) / hmac-sha256(key, msg) / hmac-md5(key, msg)Lowercase hex HMAC
crc32(x)Unsigned CRC-32 as decimal; crc32() with no argument hashes the body
base64(x) / base64url(x)Standard / URL-safe base64 (no padding)
nowMs() / nowSec()Unix timestamp in milliseconds / seconds
uuid4()Random UUID
randomHex(n)n random hex chars (default 8)

Pipes transform a value with |:

PipeEffect
skip:N (alias trunc:N)Drop the first N characters
take:N (alias prefix:N)Keep the first N characters
upper / lowerCase conversion
urlencodeencodeURIComponent
base64 / base64urlEncode the value

String literals use double quotes with \n, \t, and \\ escapes; + concatenates; parentheses group. A missing scoped field degrades to an empty string (with an error for unknown scopes); a missing plain variable keeps the unresolved-marker behavior above.

Named nonces and multi-statement templates

Statements separated by ; run in order; the last statement’s value is the result. An assignment name = expr stores a per-send local — the way to mint a nonce once and reuse it, since one computed context is shared across every field of a replay (URL, headers, and body all see the same locals):

{{ p = randomHex:4; p + sha1(secret + cookie:session + p) | skip:4 }}

A second field referencing {{ p }} in the same send gets the identical nonce. Locals shadow chain variables of the same name. randomHex:N and randomB64:N also work as scoped generators (randomHex:4 → 4 hex chars; randomB64:8 → base64 of 8 random bytes).

If evaluation fails (unknown function, pipe, or scope), the template is left untouched and the error surfaces as Computed field error: …, blocking the send.

A real-world construction: the fgssca-goldapple cookie is a 4-hex random prefix followed by sha1(appSecret + gsscCookie + prefix) with the first 4 hex characters dropped. To replay it, add the app secret as a chain variable (e.g. fgsscSecret), then put this in the draft Cookie header as the fgssca-goldapple value:

{{ p = randomHex:4; p + sha1(fgsscSecret + cookie:gssca-goldapple + p) | skip:4 }}

The result is 40 hex characters: the 4-char prefix plus the truncated SHA-1. Because p is a named local, any other field needing the same prefix can reference {{ p }}.

[!TIP] Don’t know the formula yet? The Signature tab in the API lab brute-forces exactly this class — prefix + hash(secret + <field> + prefix)[dropN:] alongside classic canonicalizations — and reports the derivation inputs. See /docs/en/api-re/.

Local hash primitives

The DSL evaluates synchronously inside payload construction, so it cannot call WebCrypto. Hashes run on local, synchronous implementations — FIPS 180-4 SHA-1/SHA-256, RFC 2202/4231 HMAC, and a local MD5/HMAC-MD5 (WebCrypto omits MD5, which legacy mobile signature schemes still use) — validated against standard test vectors. Nothing leaves the workspace to compute a signature, and the same derivation logic is exportable in the standalone Go collector; see /docs/en/collector/. Value masking in the variables panel follows the workspace reveal setting — see /docs/en/security/.

The replay workbench, batch limits, TLS fingerprint control, and mTLS are covered in /docs/en/replay/.

Traffic Jam documentation. Built with Hugo.