All Products
Search
Document Center

Cloud Monitor:Guide to using multi-step probe expressions

Last Updated:Jan 30, 2026

Expressions are an advanced feature for multi-step probes that provide a flexible syntax for variable extraction and assertions. You can use built-in functions, operators, and pipelines to process response data, which lets you validate complex business logic.

Scenarios

Expressions are primarily used in the following two scenarios:

1. Variable extraction (recommended)

You can extract and process data from a response and then save the data as a variable. This is the most common use for expressions because it lets you process raw response data before you use it.

2. Assertion validation

You can verify that a response meets the expected conditions. Expressions can perform complex conditional checks, which makes assertions more precise and flexible.

Special variables

You can use the following built-in special variables in expressions:

Variable

Description

Scenarios

@body

HTTP response body (full text)

Variable extraction, assertion

@status

HTTP status code (number)

Assertion

@headers

HTTP response headers (object)

Variable extraction, assertion

@uuid

Generates a random UUID

URL, request header, request body

@timestamp

Current UNIX timestamp (in seconds)

URL, request header, request body

@random(n)

Generates a random string of n characters

URL, request header, request body

Built-in functions

Multi-step probes provide a rich set of built-in functions, which are categorized as follows:

Data extraction functions

jsonpath(json, path)

This function extracts data from a JSON object and is the most common way to process JSON responses.

API parameter example:

{
  "parser": {
    "parser_type": "expression",
    "value": "jsonpath(@body, '$.data.users[0].id')"
  }
}

regex(text, pattern, group)

This function extracts text using a regular expression. You can use this function for non-JSON responses or for extracting data in a specific format.

API parameter example:

{
  "parser": {
    "parser_type": "expression",
    "value": "regex(@body, 'token=([a-z0-9]+)', 1)"
  }
}

String manipulation functions

Function

Description

Example

upper(str)

Converts to uppercase

upper(@body.name)"JOHN"

lower(str)

Converts to lowercase

lower(@body.email)"test@example.com"

trim(str)

Removes leading and trailing spaces

trim(@body.token)

length(str)

Gets the length

length(@body) > 100

substring(str, start, end)

Extracts a substring

substring(@body.id, 0, 8)

replace(str, old, new)

Replaces a string

replace(@body.url, 'http', 'https')

concat(str1, str2, ...)

Concatenates strings

concat('User-', @body.id)

contains(str, substr)

Checks for inclusion

contains(@body, 'success')

Encryption and encoding functions

Function

Description

Example

md5(str)

MD5 hash

md5(@body.email)

sha1(str)

SHA1 hash

sha1(password)

sha256(str)

SHA256 hash

sha256(app_key + @timestamp)

base64(str)

Base64 encoding

base64('username:password')

base64_decode(str)

Base64 decoding

base64_decode(@body.encoded)

urlencode(str)

URL encoding

urlencode(@body.query)

urldecode(str)

URL decoding

urldecode(@body.param)

Utility functions

Function

Description

Example

default(val, defaultVal)

Provides a default value

default(@body.name, 'unknown')

coalesce(val1, val2, ...)

Returns the first non-empty value

coalesce(@body.token, backup_token, 'guest')

Operators

Arithmetic operators

  • + - Addition or string concatenation

  • - - Subtraction

  • * - Multiplication

  • / - Division

  • % - Modulo

Comparison operators

  • == - Equal to

  • != - Not equal to

  • > - Greater than

  • < - Less than

  • >= - Greater than or equal to

  • <= - Less than or equal to

Logical operators

  • && - Logical AND

  • || - Logical OR

  • ! - Logical NOT

  • ?? - Nullish coalescing

Special operators

Ternary operator ? :

This operator is used for conditional checks and value selection.

{
  "value": "@body.status == 'active' ? 'online' : 'offline'"
}

Pipeline operator |

This operator passes a value to a chain of functions for processing, which makes expressions easier to read.

{
  "value": "@body.email | trim | lower"
}

Usage examples

Example 1: Extract and process a user's email

{
  "extracted_variables": [
    {
      "name": "user_email",
      "parser": {
        "parser_type": "expression",
        "value": "@body.email | trim | lower"
      },
      "extracted_type": "http_body"
    }
  ]
}

Example 2: Extract the first element of an array

{
  "extracted_variables": [
    {
      "name": "first_post_id",
      "parser": {
        "parser_type": "expression",
        "value": "jsonpath(@body, '$[0].id')"
      },
      "extracted_type": "http_body"
    }
  ]
}

Example 3: Conditional extraction

{
  "extracted_variables": [
    {
      "name": "user_level",
      "parser": {
        "parser_type": "expression",
        "value": "@body.score > 100 ? 'VIP' : 'Normal'"
      },
      "extracted_type": "http_body"
    }
  ]
}

Example 4: Combine multiple fields

{
  "extracted_variables": [
    {
      "name": "full_name",
      "parser": {
        "parser_type": "expression",
        "value": "concat(@body.firstName, ' ', @body.lastName) | trim"
      },
      "extracted_type": "http_body"
    }
  ]
}

Example 5: Generate a signature

{
  "extracted_variables": [
    {
      "name": "signature",
      "parser": {
        "parser_type": "expression",
        "value": "md5(concat(app_key, @timestamp, app_secret))"
      },
      "extracted_type": "http_body"
    }
  ]
}

Using expressions in assertions

Basic assertion

{
  "assertions": [
    {
      "type": "expression",
      "target": "@status == 200"
    }
  ]
}

Complex conditional assertion

{
  "assertions": [
    {
      "type": "expression",
      "target": "(@status == 200 || @status == 201) && length(@body) > 0"
    }
  ]
}

JSON field validation

{
  "assertions": [
    {
      "type": "expression",
      "target": "@body.userId == user_id && @body.status == 'active'"
    }
  ]
}

Response content check

{
  "assertions": [
    {
      "type": "expression",
      "target": "contains(@body, 'success') && length(@body) > 50"
    }
  ]
}

Array length validation

{
  "assertions": [
    {
      "type": "expression",
      "target": "length(@body) > 1"
    }
  ]
}

Using extracted variables (Note: Only for subsequent steps)

{
  "assertions": [
    {
      "type": "expression",
      "target": "jsonpath(@body, '$.id') == expected_id"
    }
  ]
}

Complete example: API test flow

The following is a complete example of a multi-step probe configuration that shows how to use expressions in a real-world scenario.

{
  "config_variables": [
    {"name": "base_url", "value": "https://jsonplaceholder.typicode.com"},
    {"name": "post_id", "value": ""},
    {"name": "user_id", "value": ""}
  ],
  "steps": [
    {
      "step_name": "Get post list",
      "step_type": "http",
      "url": "{{base_url}}/posts",
      "option": "{\"http_method\":\"GET\",\"assertions\":[{\"type\":\"expression\",\"target\":\"@status == 200 && length(@body) > 0\"}]}",
      "extracted_variables": [
        {
          "name": "post_id",
          "parser": {
            "parser_type": "expression",
            "value": "jsonpath(@body, '$[0].id')"
          },
          "extracted_type": "http_body"
        },
        {
          "name": "user_id",
          "parser": {
            "parser_type": "expression",
            "value": "jsonpath(@body, '$[0].userId')"
          },
          "extracted_type": "http_body"
        }
      ]
    },
    {
      "step_name": "Get post details",
      "step_type": "http",
      "url": "{{base_url}}/posts/{{post_id}}",
      "option": "{\"http_method\":\"GET\",\"assertions\":[{\"type\":\"expression\",\"target\":\"@status == 200\"},{\"type\":\"expression\",\"target\":\"@body.id == post_id\"},{\"type\":\"expression\",\"target\":\"@body.userId == user_id\"}]}"
    }
  ]
}

Best practices

1. Prioritize JSONPath

For JSON responses, use the jsonpath() function because it is more reliable than using regular expressions.

✅ "jsonpath(@body, '$.data.token')"
❌ "regex(@body, '\"token\":\"([^\"]+)\"', 1)"

2. Use pipelines to simplify code

Use the pipeline operator to make expressions easier to read.

✅ "@body.email | trim | lower"
❌ "lower(trim(@body.email))"

3. Provide default values

Provide default values for potentially empty values to make your scripts more robust.

"@body.name | default('Anonymous')"

4. Write specific and clear assertions

Write specific and clear assertions to ensure validation accuracy.

✅ "@status == 200 && @body.code == 0 && length(@body.data) > 0"
❌ "length(@body) > 0"

5. Avoid overly complex expressions

  • Limit expressions to three or fewer nested layers.

  • Break down complex logic into multiple steps.

FAQ

Q1: How do I access array elements?

You can use the jsonpath() function:

"jsonpath(@body, '$[0].id')"  // First element
"jsonpath(@body, '$[*].id')"  // All elements (returns the first match)

Q2: How do I debug a failed expression assertion?

If a failure occurs, the system provides detailed information:

  • Content of the expression.

  • The actual result of the expression.

  • The values of the variables used in the expression.

Q3: Can I use a variable extracted in the current step in an assertion for the same step?

No, you cannot. Assertions are executed before variables are extracted. Therefore, to use an extracted variable in an assertion, you must place the assertion in a subsequent step.

Q4: What is the difference between @body.field and jsonpath(@body, '$.field')?

  • @body.field is a simplified syntax for accessing simple fields.

  • jsonpath(@body, '$.field') is the full syntax that supports complex paths and array operations.

Recommendation: Use the jsonpath() function for arrays or complex nested objects.

Related reference

Syntax cheat sheet

Scenario

Expression example

Access a simple field

@body.userId

Access an array element

jsonpath(@body, '$[0].id')

String manipulation

@body.email | trim | lower

Conditional logic

@body.age > 18 ? 'adult' : 'minor'

Handle null values

@body.name ?? 'default'

Encrypted signature

md5(app_key + @timestamp)

Concatenate strings

concat('prefix-', @body.id, '-suffix')

Status validation

@status == 200 && @body.success == true

Content check

contains(@body, 'success')

Length validation

length(@body) > 100