Skip to content

2.4Multi-step API

What it checks#

A multi-step API monitor runs several HTTP requests in order, as one check. Each request is a step. All steps share cookies: a cookie set by one step is sent by the next. A step can extract a value from its response, such as a login token. Later steps use it as {{name}}. Your plan must include API monitors. The monitor is saved as an API monitor.

When it is up, degraded or down#

  • Up: every step got a response, passed all its assertions, and found all its extractions. A step with no assertions passes on any 2xx status.
  • Degraded: all steps passed, but the total time was slower than your slow limit, if you set one.
  • Down: a step failed. The run stops at the first failing step. The message reads step N (<step name>): <reason>, for example step 2 (list orders): assertion status_code == 200: got 401.
  • Steps in these messages count from 1. A step with no label shows as #N.
  • An extraction that finds nothing fails its step: extract "token" from json "data.token": not found.

The response time is the total of all steps. The status code shown is the last step's.

Configuration#

The left column has name, check interval, timeout and on failure — notify. There is no locations picker. In the dashboard, multi-step monitors run from us-west.

Dashboard fieldDefaultLimits and notes
nameEmptyRequired. Up to 200 characters, on one line.
check interval60 secondsAt least 1 second. Your plan's minimum interval still applies: below it the form shows Your plan checks at most every N seconds.
timeout10 secondsApplies to each step. A value above 60 seconds counts as 60 seconds.
on failure — notifyNone (all team channels)Pick channels to limit who is alerted. Shown only when your team has channels.
stepsOne empty stepSelect + add step. Up to 50 steps.

Each step has these fields:

Step fieldDefaultLimits and notes
methodGETGET, POST, PUT, PATCH, DELETE or HEAD.
labelEmptyOptional. A short name, such as authenticate. Shown in messages.
urlEmptyRequired. Starts with http://, https://, {{var}} or ${SECRET}. No spaces.
headersNoneUp to 50 per step.
bodyEmptyThe text to send.
assertionsNoneUp to 50 per step. Same types and operators as URL.
extract →NoneSelect + add extraction. Pick a source and enter a variable name, such as access_token.

An extraction takes a value from one of three sources:

  • json: a dotted path into the JSON body, such as data.access_token.
  • header: a header name, such as X-Request-Id.
  • status: the status code. No path is needed.

Form errors: Add at least one step, step N: url required, step N: Start with http:// or https://, step N: extraction NAME needs a path.

Use values from earlier steps#

  • Give an extraction a name. Then write {{name}} in a later step's URL, headers or body.
  • A variable works only in a later step, not in the step that creates it.
  • The cookie jar & variables panel lists each variable. It shows the step it comes from and how many steps use it, or not used yet.
  • An unknown {{name}} is sent exactly as typed. Check that the names match.
  • {{name}} is a value from an earlier step. ${NAME} is a team secret.

Assertions supported#

Each step supports the same assertions as a URL monitor (2.2). A response_time_ms assertion in a step checks that step only.

Example#

Log in, then list orders with the token from the login reply. The password is the team secret CI_PASSWORD.

API request body (CreateApiMonitor with apiSteps)
json
{
  "name": "orders API — login and list",
  "intervalSeconds": 300,
  "apiSteps": [
    {
      "name": "authenticate",
      "method": "POST",
      "url": "https://api.acme.io/v1/auth/login",
      "headers": {"Content-Type": "application/json"},
      "body": "eyJlbWFpbCI6ImNpQGFjbWUuaW8iLCJwYXNzd29yZCI6IiR7Q0lfUEFTU1dPUkR9In0=",
      "assert": [
        {"type": "status_code", "op": "ASSERTION_OP_EQ", "value": "200"}
      ],
      "extract": [{"name": "token", "from": "json", "path": "data.token"}]
    },
    {
      "name": "list orders",
      "method": "GET",
      "url": "https://api.acme.io/v1/orders",
      "headers": {"Authorization": "Bearer {{token}}"},
      "assert": [
        {"type": "status_code", "op": "ASSERTION_OP_EQ", "value": "200"}
      ]
    }
  ]
}

Good to know#

  • In the API, a step's assertion list is assert, not assertions.
  • When apiSteps is set, the top-level url, method, headers, body and assertions are not used. You must send url or apiSteps: url or api_steps required.
  • The API can set locations for a multi-step monitor. The dashboard cannot.
  • Server messages count steps from 0: api_steps[0] is the first step. Example: api_steps[1]: url required.
  • Use a test account for flows that sign in, and save its password as a team secret.

Last updated