Uptime Monitoring

API Monitors

Create multi-step API workflows with variable extraction, chained requests, and comprehensive assertions.

API Monitors

API monitors execute multi-step HTTP workflows, allowing you to test complex API scenarios like authentication flows, CRUD operations, and multi-service integrations.

Overview

Unlike URL monitors (single request), API monitors can:

  • Execute multiple requests in sequence
  • Extract values from responses
  • Use extracted values in subsequent requests
  • Validate each step independently

Creating an API Monitor

Basic Structure

Name: User Authentication Flow
Steps:
  - name: Login
    request:
      url: https://api.example.com/auth/login
      method: POST
      body:
        email: "{{USER_EMAIL}}"
        password: "{{USER_PASSWORD}}"
    extract:
      - name: accessToken
        from: body
        path: $.data.access_token
    assertions:
      - type: status_code
        equals: 200

  - name: Get User Profile
    request:
      url: https://api.example.com/users/me
      method: GET
      headers:
        Authorization: "Bearer {{accessToken}}"
    assertions:
      - type: status_code
        equals: 200
      - type: json_path
        path: $.data.email
        equals: "{{USER_EMAIL}}"

Request Configuration

HTTP Methods

Support for all standard methods:

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
  • HEAD
  • OPTIONS

Headers

request:
  headers:
    Content-Type: application/json
    Authorization: Bearer {{token}}
    X-Request-ID: "{{uuid}}"
    Accept: application/json

Body Types

JSON Body

request:
  body:
    type: json
    content:
      username: testuser
      email: [email protected]

Form URL Encoded

request:
  body:
    type: form
    content:
      grant_type: password
      username: "{{USER}}"
      password: "{{PASS}}"

Raw Body

request:
  body:
    type: raw
    content: |
      <?xml version="1.0"?>
      <request><action>check</action></request>

Multipart Form

request:
  body:
    type: multipart
    content:
      file:
        type: file
        path: /test-data/sample.pdf
      description: Test upload

Variable Extraction

Extract values from responses for use in subsequent steps.

From Response Body (JSON)

extract:
  - name: userId
    from: body
    path: $.data.user.id

  - name: totalCount
    from: body
    path: $.meta.total

From Headers

extract:
  - name: requestId
    from: header
    header: X-Request-ID

  - name: rateLimitRemaining
    from: header
    header: X-RateLimit-Remaining

From Status

extract:
  - name: statusCode
    from: status

Using Regex

extract:
  - name: orderId
    from: body
    regex: "order_([A-Z0-9]+)"
    group: 1

Using Variables

Reference extracted variables with double curly braces:

# In URLs
url: https://api.example.com/users/{{userId}}/orders

# In headers
headers:
  Authorization: Bearer {{accessToken}}

# In body
body:
  parent_id: "{{parentId}}"

# In assertions
assertions:
  - type: json_path
    path: $.user.id
    equals: "{{userId}}"

Assertions

Per-Step Assertions

Each step can have multiple assertions:

assertions:
  # Status code
  - type: status_code
    equals: 200

  # Response time
  - type: response_time
    less_than: 2000

  # JSON path value
  - type: json_path
    path: $.data.items
    not_empty: true

  # JSON path existence
  - type: json_path
    path: $.data.id
    exists: true

  # Array length
  - type: json_path
    path: $.data.items.length
    greater_than: 0

  # Header value
  - type: header
    name: Content-Type
    contains: application/json

Assertion Operators

OperatorDescriptionExample
equalsExact matchequals: 200
not_equalsNot equalnot_equals: null
containsString containscontains: "success"
not_containsString doesn't containnot_contains: "error"
greater_thanNumeric comparisongreater_than: 0
less_thanNumeric comparisonless_than: 1000
matchesRegex matchmatches: "^[A-Z]{3}$"
existsProperty existsexists: true
not_emptyNot null/emptynot_empty: true
is_arrayValue is arrayis_array: true

Common Patterns

Authentication Flow

Steps:
  - name: Login
    request:
      url: https://api.example.com/auth/login
      method: POST
      body:
        email: "{{EMAIL}}"
        password: "{{PASSWORD}}"
    extract:
      - name: token
        path: $.access_token
    assertions:
      - type: status_code
        equals: 200

  - name: Authenticated Request
    request:
      url: https://api.example.com/protected
      method: GET
      headers:
        Authorization: Bearer {{token}}
    assertions:
      - type: status_code
        equals: 200

CRUD Operations

Steps:
  - name: Create Resource
    request:
      url: https://api.example.com/items
      method: POST
      body:
        name: Test Item
        price: 99.99
    extract:
      - name: itemId
        path: $.data.id
    assertions:
      - type: status_code
        equals: 201

  - name: Read Resource
    request:
      url: https://api.example.com/items/{{itemId}}
      method: GET
    assertions:
      - type: status_code
        equals: 200
      - type: json_path
        path: $.data.name
        equals: Test Item

  - name: Update Resource
    request:
      url: https://api.example.com/items/{{itemId}}
      method: PUT
      body:
        name: Updated Item
    assertions:
      - type: status_code
        equals: 200

  - name: Delete Resource
    request:
      url: https://api.example.com/items/{{itemId}}
      method: DELETE
    assertions:
      - type: status_code
        equals: 204

Pagination Test

Steps:
  - name: Get First Page
    request:
      url: https://api.example.com/items?page=1&limit=10
      method: GET
    extract:
      - name: totalPages
        path: $.meta.total_pages
      - name: nextPage
        path: $.meta.next_page
    assertions:
      - type: json_path
        path: $.data
        is_array: true

  - name: Get Second Page
    request:
      url: https://api.example.com/items?page={{nextPage}}&limit=10
      method: GET
    assertions:
      - type: status_code
        equals: 200

OAuth Flow

Steps:
  - name: Get Access Token
    request:
      url: https://auth.example.com/oauth/token
      method: POST
      headers:
        Content-Type: application/x-www-form-urlencoded
      body:
        type: form
        content:
          grant_type: client_credentials
          client_id: "{{CLIENT_ID}}"
          client_secret: "{{CLIENT_SECRET}}"
    extract:
      - name: accessToken
        path: $.access_token
    assertions:
      - type: status_code
        equals: 200

  - name: Use Token
    request:
      url: https://api.example.com/resource
      method: GET
      headers:
        Authorization: Bearer {{accessToken}}
    assertions:
      - type: status_code
        equals: 200

Error Handling

Continue on Failure

By default, a failed step stops execution. To continue:

Steps:
  - name: Optional Step
    continue_on_failure: true
    request:
      url: https://api.example.com/optional

Conditional Steps

Execute steps based on previous results:

Steps:
  - name: Check Feature Flag
    request:
      url: https://api.example.com/features/new-flow
    extract:
      - name: featureEnabled
        path: $.enabled

  - name: New Flow
    condition: "{{featureEnabled}} == true"
    request:
      url: https://api.example.com/new-flow

Debugging

View Step Details

Each step logs:

  • Request sent (URL, headers, body)
  • Response received (status, headers, body)
  • Extracted variables
  • Assertion results

Common Issues

Variable not found: Ensure the extraction step ran successfully and the JSON path is correct.

Response body too large: Enable body truncation in settings.

Timeout on step: Increase step timeout or check API performance.

Best Practices

  1. Use environment variables for credentials
  2. Name steps clearly for easier debugging
  3. Extract early - Get values as soon as they're available
  4. Add meaningful assertions - Don't just check status codes
  5. Handle cleanup - Delete test data after creation
  6. Set appropriate timeouts - Account for slow APIs