Skip to main content

API Response Assertions and Variable Extraction

Written by Ines

The API Testing module in Thunders lets you call any HTTP endpoint from a test step, inspect the response, and turn parts of that response into automated checks or reusable variables. This page covers the two key capabilities built on top of API steps: Response Assertions and Variable Extraction.

TL;DR — Run an API step → open the Response Inspector by clicking on the API step → click Assert or Extract on any value → each click appends a step at the end of the test case → Execute

An API step after its run. The Response Inspector shows the Status code, Duration and Load Duration cards with Assert and Extract, and the JSON tree of the response body.

What the Feature Does

When an API step executes, Thunders captures the full HTTP response:

  • Status code (e.g. 200, 404)

  • Duration and load duration (in milliseconds)

  • Response body (parsed as JSON when possible)

  • Headers

From the Response Inspector you can:

  • Add Assertion steps to automatically verify that a value matches an expected result on every future run.

  • Add Extraction steps to save any value into a named variable that later steps can reuse.

  • Save a value as a project or environment variable, which stays available after the run.

Assertions and extractions are real test steps — they appear in the step list, show pass/fail results, and can be reordered or edited like any other step.

Saving a Full API Response Into a Variable

Every API step automatically saves its complete response into a variable. You can customize the name from the API step form.

  1. Press A (or click Add Step → API) to open the step modal.

  2. Fill in the method (GET, POST, PUT, PATCH, DELETE), URL, headers, body, and authentication.

  3. In the Save response as field, choose a name. Default values follow the pattern API_RESPONSE_1, API_RESPONSE_2, ...

  4. Run the step — the entire response object is now available under that name.

The Add new step dialog for an API Call step, with GET /products/1 and the response saved as API_RESPONSE_1.
A Test Case with one API Call step, GET /products/1, before its run.

Tip: Use descriptive names like LOGIN_RESPONSE, USER_PROFILE_RESPONSE, or LIST_ORDERS_RESPONSE so later references remain readable.

Variable name rules: uppercase letters, digits and underscores only. Must start with a letter. Regex: ^[A-Z][A-Z0-9_]*$.

Reusing Saved Response Data in Later Steps

Once a response is saved, any later step can reference it with [VARIABLE_NAME] syntax. You can also drill into nested fields with dot notation.

Reference

Resolves to

[LOGIN_RESPONSE].body.token

The token field from the JSON body

[LOGIN_RESPONSE].statusCode

The HTTP status code

[LOGIN_RESPONSE].duration

Request duration (milliseconds)

[USER_ID]

A variable explicitly extracted in a previous step

You can place these references:

  • In a later API step's URL — https://api.example.com/users/[USER_ID]

  • In a header — Authorization: Bearer [LOGIN_RESPONSE].body.token

  • Inside an assertion expected value

Start typing / (or [) in any supported field to open the Inline Variable Editor autocomplete and pick from available variables.

Typing / in a step field opens the list of variables, with API_RESPONSE_1 and the extracted TITLE and TITLE_KEY.

Asserting on Response Metadata (Status, Duration)

Response metadata appears as metric cards at the top of the Response Inspector.

To assert on a metric:

  1. Click Assert (or open the ⋯ menu on narrow screens) on the Status code card.

  2. The assertion modal opens with the field path pre-filled, e.g. [API_RESPONSE_1].statusCode.

  3. Pick an operator.

  4. Enter the expected value (e.g. 200).

  5. Click Add Assert — an Assert step is appended at the end of the test case.

The assertion dialog for statusCode, with the path [API_RESPONSE_1].statusCode, the operator is equal to and the value 200.
The new Assert step at the end of the Test Case: [API_RESPONSE_1].statusCode is equal to 200.

Common metadata assertions:

Goal

Field

Operator

Expected value

Success status

statusCode

is equal to

200

Accept any 2xx

statusCode

is less than

300

Enforce latency budget

duration

is less than

1000

Verify a redirect

statusCode

is equal to

302

Asserting on JSON Response Values

The response body renders as an interactive JSON tree. Expand any object or array to drill into a specific field.

To assert on a JSON value:

  1. Expand the JSON tree to the field you care about.

  2. Click Assert next to the value.

  3. The field path is auto-computed, e.g. [API_RESPONSE_1].body.title.

  4. Select an operator.

  5. Enter the expected value and click Add Assert.

The assertion dialog for body.title, with Target set to Value, the operator is equal to and the value Essence Mascara Lash Princess.
The new Assert step: [API_RESPONSE_1].body.title is equal to Essence Mascara Lash Princess.

Available operators:

Operator

Use it for

is equal to / is not equal to

Exact match (strings, numbers, booleans)

is greater than / is greater or equal to

Numeric comparisons

is less than / is less or equal to

Numeric comparisons

contains

Substring or array element check

starts with / ends with

Prefix / suffix on strings (IDs, URLs)

has key / does not have key

Check that a JSON object contains (or does not contain) a given key

Tip: Use has key / does not have key when you only care that a key exists, not what its value is — perfect for feature flags or optional fields.

Targeting Keys vs. Values

When you click Assert or Extract on a field that belongs to a JSON object, the modal shows a Target toggle with two options: Key and Value. It lets you decide whether the assertion or extraction applies to the field name or to its content. The path itself is filled in automatically — you never have to type it.

  • Value (default) — operates on the content of the field.

  • Key — operates on the field name itself.

The Target toggle of the assertion dialog for body.title, set to Value.
The Target toggle set to Key for body.title, with the operator has key and the value title.

The Target toggle only appears for values that are direct children of a JSON object. It is hidden for array items, metric cards (status, duration), and top-level response fields — there is no key to target there.

When to target the key:

  • Verify that a response object still exposes a specific field name (contract testing).

  • Extract a dynamically generated key (for example, an ID used as a map key) and reuse it in later steps.

Example — given a product response body:

{
"title": "Essence Mascara Lash Princess",
"price": 9.99,
"meta": {
"barcode": "5784719087687",
"qrCode": "https://cdn.dummyjson.com/public/qr-code.png"
}
}
  • Clicking Assert on meta.barcode with Target → Value checks that the barcode equals "5784719087687".

  • Clicking Assert on meta.barcode with Target → Key checks that the response still includes a field literally named "barcode" — a simple contract check that survives value changes.

Tip: If you only need to check that a given key exists, has key on the parent object is usually simpler. Reach for Target → Key when you actually need the key name as a value (for example to save it into a variable).

An assertion on the key of body.meta.barcode: Target set to Key, the operator has key and the value barcode.

Extracting Keys and Values Into Variables

Variable extraction stores a piece of the response under a named variable so later steps can use it.

To extract a value:

  1. In the Response Inspector, locate the value to reuse (a metric card or any JSON tree node).

  2. Click Extract.

  3. The extraction modal opens with the field path pre-filled.

  4. In Save as, enter a variable name — the input auto-uppercases and strips invalid characters.

  5. Click Extract — an EXTRACT step is appended at the end of the test case.

The Extract tab of the dialog for body.meta.barcode, with Target set to Key and the variable name BARCODE in Save as.
The new Extract step: [API_RESPONSE_1].body.meta.@keys[2] saved into [BARCODE].
The extracted variable BARCODE in the list of variables of a new AI Step.

Saving a Value as a Project or Environment Variable

An extracted variable lives for one run only. To keep a value for later runs and other Test Cases, for example a token, save it as a project or environment variable. This adds no step to the Test Case.

To save one value from the response:

  1. In the Response Inspector, hover a value of the JSON tree. Assert, Extract and Save appear next to it. On a metric card, Assert, Extract and Save show as buttons, or, on a narrow card, in its actions button.

  2. Click Save.

  3. The Create variable dialog opens. The Key is suggested from the field path, for example body.userId gives USER_ID, and the Value holds the value of the field, here 1. The dialog also shows the Make writable and Store as secure credential switches.

  4. Under Scope, choose Project level, or Environment and an Environment. The dialog opens on the Environment of the run.

  5. Change the key if you want, then click Create.

An API step after its run. In the Response Inspector, the userId value shows Assert, Extract and Save on hover. Save opens the Create variable dialog with the Environment scope and the Production Environment selected, the key USER_ID and the value 1.

To save the whole response body:

  1. Under the API step, hover the response chip in "Full API response stored in [API_RESPONSE_1]".

  2. Click Save as variable.

  3. The same Create variable dialog opens. The Value holds the response body, and the Key is suggested from the request, for example GET_ORDERS_RESPONSE for GET /orders.

  4. Choose the scope, then click Create.

The suggested key never takes a name that the chosen scope already uses. A key has 30 characters at most. A value has 2048 characters at most: for a larger response body, the dialog shows "Value is too long. Keep it to 2048 characters or fewer." and Create stays unavailable. In that case, save one field from the Response Inspector instead.

Save and Save as variable do not show on a read-only run report.

Using the Response Inspector

The Response Inspector is the discovery surface. It has three areas:

  • Metric cards — status, duration, load duration.

  • Copy Response button — copies the full response body to the clipboard.

  • JSON tree — expandable view of the response body with per-value actions.

Each click on Assert or Extract immediately appends a new step at the end of the Test Case. Add them one at a time — each step appears in the step list as soon as it is created, and can be reordered or edited like any other step.

Why this matters: You stay in the Response Inspector the whole time. Click Assert or Extract on any value in the JSON tree and the step lands directly in the Test Case — no step modal, no extra confirmation.

End-to-End Examples

Example 1 — Pull product data from the API and verify it on the storefront

Goal: fetch a real product from the catalog and check that the storefront UI displays the same values.

  1. Step 1 — API: GET /products/42. Response variable: PRODUCT_RESPONSE

  2. Step 2 — Extract (added from the Inspector): [PRODUCT_RESPONSE].body.title → PRODUCT_TITLE

  3. Step 3 — Extract (added from the Inspector): [PRODUCT_RESPONSE].body.price → PRODUCT_PRICE

  4. Step 4 — Browser: navigate to /shop/products/42

  5. Step 5 — Visual assertion: the page shows [PRODUCT_TITLE]

  6. Step 6 — Visual assertion: the page shows [PRODUCT_PRICE]

Example 2 — Create an item via API, then continue the journey in the browser

Goal: create a support ticket with the API so the UI test can open and act on it.

  1. Step 1 — API: POST /tickets with body {"title": "Cannot upload avatar"}. Response variable: NEW_TICKET

  2. Step 2 — Extract: [NEW_TICKET].body.id → TICKET_ID

  3. Step 3 — Browser: navigate to /support/tickets/[TICKET_ID]

  4. Step 4 — Visual assertion: Ticket #[TICKET_ID] is visible on the page

  5. Step 5 — Browser: click Mark as resolved

  6. Step 6 — Visual assertion: the Resolved status badge is visible

Example 3 — Capture server-side values so later steps work with real data

Goal: read the current account plan and credits, then confirm the same values appear on the billing page.

  1. Step 1 — API: GET /account/usage. Response variable: USAGE_RESPONSE

  2. Step 2 — Assert [USAGE_RESPONSE].body has key plan

  3. Step 3 — Extract [USAGE_RESPONSE].body.plan → CURRENT_PLAN

  4. Step 4 — Extract [USAGE_RESPONSE].body.creditsRemaining → CREDITS_REMAINING

  5. Step 5 — Browser: navigate to /settings/billing

  6. Step 6 — Visual assertion: the billing page displays [CURRENT_PLAN]

  7. Step 7 — Visual assertion: the billing page displays [CREDITS_REMAINING]

Tips and Troubleshooting

  • If you see Credential or Variable not found 'VARIABLE_NAME' at runtime, check the spelling and confirm the step that produces the variable ran before the step that consumes it.

  • Secrets (passwords, tokens) are hidden by default in auth fields — click the eye icon to reveal.

  • Environments: each environment keeps its own URL / headers / body for an API step, but variables extracted during a run are shared across that run.

Need to test a flow that spans several runs? Extracted step variables only live for the duration of a single Test Case run. For values that must persist across runs, use Project Variables or Environment Variables instead.

Other related reads you might find useful:

Did this answer your question?