Skip to main content

Chaining and postscripts

Chaining lets one API step use data returned by an earlier step. Use it for flows like login then fetch profile, create user then update user, or create order then verify order status.

How chaining works

Every step in an API scenario can declare captures. A capture is a JSONPath into the response body plus a name for the value. Later steps reference that name in headers, body, URL, query params, or any other string field. The runner substitutes the captured value when the request is sent. A two-step login-then-fetch scenario, captured shape:
{
  "steps": [
    {
      "order": 1,
      "action": "login",
      "target": "${API_BASE_URL}/auth/login",
      "method": "POST",
      "body": { "email": "${AUTH_EMAIL}", "password": "${AUTH_PASSWORD}" },
      "captures": [{ "as": "token", "from": "$.access_token" }],
      "expectedStatus": 200
    },
    {
      "order": 2,
      "action": "fetch profile",
      "target": "${API_BASE_URL}/users/me",
      "method": "GET",
      "headers": [{ "key": "Authorization", "value": "Bearer ${token}" }],
      "expectedStatus": 200
    }
  ]
}
What is happening:
  • Step 1 logs in. The capture { "as": "token", "from": "$.access_token" } reads access_token off the JSON response body.
  • Step 2 uses ${token} in the Authorization header. The runner substitutes the captured value before the request fires.
You can capture anything addressable by JSONPath: a top-level field, a nested object, or an array element. Chain across as many steps as you need.

Where you can use captured values

${var} interpolation runs on every string field of a step:
  • Request body (raw, JSON, form-urlencoded, multipart).
  • Headers.
  • URL path and query params.
  • Auth values (bearer token, API key).
The runner does plain textual substitution. There is no expression layer, so something like Authorization: Basic ${user}:${pass} will not produce valid Basic credentials. For Basic auth, use the structured step.auth = { type: "basic", username, password } shape and let the runner encode it.

Environment variables

Two flavors of variable resolve at send time:
  • Captures from earlier steps in the same scenario (${token}, ${userId}).
  • Environment variables from the active environment (${API_BASE_URL}, ${AUTH_EMAIL}, custom values you’ve added).
Captures are scenario-scoped: they exist for the duration of the run, not across scenarios. Environment variables persist on the environment record and apply to every scenario you run against it. Both use the same ${var} syntax. The runner builds one merged map at send time and substitutes.

Postscripts: writing values back to the environment

The API Playground supports declarative postscripts via the postExtract array on a saved request. After the response arrives, each rule runs and writes its captured value back into the active environment as a variable.
{
  "postExtract": [
    { "source": "body", "path": "$.access_token", "target": "AUTH_TOKEN" },
    { "source": "header", "path": "X-Request-Id", "target": "LAST_REQ_ID" }
  ]
}
Source decides where the rule reads from:
  • body reads JSON via a small JSONPath subset.
  • header reads a response header by name, case-insensitive.
  • status reads the numeric HTTP status; path is ignored.
After a successful login request in the playground, the rule above writes AUTH_TOKEN into the environment. Every later request in the same environment that references {{AUTH_TOKEN}} or ${AUTH_TOKEN} picks up the freshly captured value.

When to use captures vs postscripts

  • Captures belong on a scenario when one step’s output feeds another step’s input in the same run. They’re scoped to the scenario and disappear after the run.
  • Postscripts belong on a saved API Playground request when you want the captured value to persist across requests and across sessions, the playground equivalent of “save this token in my environment.”
Both share the same JSONPath grammar.

On the roadmap

Pre-request and post-response scripts via a QuickJS sandbox (Playground phase 2) for arbitrary JavaScript transforms before send and after receive. OAuth2 (four grant types) with token caching that reuses the environment cached-bearer pattern. Per-request and per-folder variables in the scope stack so a folder can declare its own vars.

Scenarios

See the full scenario shape captures attach to.

API Playground

Where postscripts live.

Auth profiles

Run the same scenario as multiple identities.

Request data generation

How Qodex fills request bodies.