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

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.

Assertions and extractions are real test steps — they appear in the step list, show pass/fail results, and can be re-ordered 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 Response variable name 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.

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:

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

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 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.

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.

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 / not_has_key

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

Tip: Use has_key / not_has_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 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": "Toold",   "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).

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. Enter a variable name — the input auto-uppercases and strips invalid characters.

  5. Click Add — a Mechanical Extraction step is appended at the end of the test case.

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.titlePRODUCT_TITLE

  3. Step 3 — Extract (added from the Inspector): [PRODUCT_RESPONSE].body.pricePRODUCT_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.idTICKET_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.planCURRENT_PLAN

  4. Step 4 — Extract [USAGE_RESPONSE].body.creditsRemainingCREDITS_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?