SpecFormula AI
ISABackendInstructions

ResponseValidate

Validate HTTP API response correctness

ResponseValidate lets you validate both HTTP status code and response content in a single step, supporting both DataTable and JSON formats.

Basic Usage

Then create todo(201) response, with table:
  | >todo1.id | userId    | title    | completed |
  | <todoId   | $Alice.id | Buy milk | false     |

This instruction will:

  1. Validate HTTP status code is 201
  2. Validate field values in the response JSON
  3. Extract todoId from response and store in variable todo1.id

Two Formats

FormatUse Case
DataTableField-level validation, supports variable extraction
DocString JSONComplete JSON structure validation

JSON format note: Symbol system expressions ($ variables, & CAS constraints, @ time symbols, >/< extraction keys) must NOT be placed inside JSON string quotes "", otherwise they are treated as plain strings.

{ "todoId": $todo1.id }    // ✅ Correct: symbol outside quotes
{ "todoId": "$todo1.id" }  // ❌ Wrong: symbol wrapped in quotes, treated as plain string

DataTable Format

Then get todo(200) response, with table:
  | todoId    | title    | completed |
  | $todo1.id | Buy milk | false     |

JSON Format

Then get todo(200) response, with JSON:
  """json
  {
    "todoId": $todo1.id,
    "title": "Buy milk",
    "completed": false
  }
  """

Nested Paths

Supports dot notation and array indexing for nested JSON validation:

Then get order(200) response, with table:
  | data.order.id | data.items[0].name | data.items[1].name |
  | $order1.id    | Product A          | Product B          |

Escaping Keys Containing .

When a JSON key itself contains a . character, use ["..."] bracket notation to prevent it from being split into nested levels:

Then get settings(200) response, with table:
  | content.["btn.save"] | content.["btn.cancel"] |
  | Save                 | Cancel                 |

Response Header Validation

Use the H: prefix to validate HTTP Header values in the response:

# DataTable
Then create resource(201) response, with table:
  | H:Location       | id |
  | /api/resources/1 | 1  |

# JSON
Then create resource(201) response, with JSON:
  """json
  {
    H"Location": "/api/resources/1",
    "id": 1
  }
  """

Bare Value and Top-Level Array Response Body

When API returns bare values (e.g., true, 42) or top-level arrays, use B: to mark the entire response body:

# Bare value validation
Then get resource status(200) response, with JSON:
  """json
  { B: true }
  """

# Top-level array validation + Response Header
Then batch create resources(201) response, with JSON:
  """json
  {
    H"X-Total-Count": "2",
    B: [
      { "id": 1, "name": "Resource A" },
      { "id": 2, "name": "Resource B" }
    ]
  }
  """

Variable Extraction

> and < must be paired vertically in the same column: the header holds the variable name (>), and the row holds the source field in the response (<).

Then login(200) response, with table:
  | >userToken | >userId |
  | <token     | <id     |

After execution:

  • userToken = value of token from response
  • userId = value of id from response

Variable Reference

Use $variable to reference previously stored variables for comparison:

Then get user(200) response, with table:
  | userId    | name  |
  | $Alice.id | Alice |

CAS Constraint Validation

Use CAS constraints for flexible validation:

Then get order(200) response, with table:
  | orderId  | amount     | status                     | createdAt                        |
  | &isNum   | &gt(1000)  | &oneOf("pending","active") | &sameTime("2026-01-27T10:00:00") |

Common constraints:

  • &isNum, &isStr, &isNull — type checks
  • &gt(), &lt(), &between() — numeric ranges
  • &contains(), &startsWith() — string matching
  • &sameTime() — time comparison

See CAS Symbols for the complete constraint list.

Validation Flow

ResponseValidate executes four validation layers in sequence:

  1. HTTP Status Code: Fails immediately if status code doesn't match
  2. JSON Structure Comparison: Recursively compares JSON nodes
  3. Value-Level Validation: Numeric comparison, CAS constraints, variable resolution
  4. Schema Validation: Checks types against API Spec definitions

Error Handling

Lint Phase

ErrorDescription
Field not foundField name not found in Response Schema
Extract field not foundField specified with < not found in Response Schema

Runtime

ErrorDescription
Status code mismatchActual status code differs from expected
Field value mismatchField value doesn't match expected
JSON structure mismatchArray length or object fields don't match
Schema validation failedDoesn't conform to API Spec Schema definition

Complete Example

Feature: Update Todo

  Background:
    # TimeControl instruction (see TimeControl docs)
    Given current time is "2026-01-27T10:00:00"

    # EntitySetup instruction (see EntitySetup docs)
    Given prepare a user, with table:
      | >Alice.id | name  | email             | status |
      | <userId   | Alice | alice@example.com | ACTIVE |

  Example: Update todo title

    # ApiCall instruction (see ApiCall docs)
    When (UID="$Alice.id") create todo, call table:
      | >todo1.id | title    |
      | <todoId   | Buy milk |
    When (UID="$Alice.id") update todo, call table:
      | P:todoId  | title        |
      | $todo1.id | Buy soy milk |

    # ResponseValidate instruction — validate status code and response fields
    # $todo1.id: references a previously extracted variable
    # &sameTime(...): CAS time constraint, validates time value
    Then update todo(200) response, with table:
      | todoId    | title        | completed | updatedAt                        |
      | $todo1.id | Buy soy milk | false     | &sameTime("2026-01-27T10:00:00") |

On this page