boltZharp Docs
apiMonitors

API Checks

Call an endpoint on a schedule and check what comes back — the status code and the values in the JSON body — or chain several calls and pass values from one to the next.

API endpoint or API workflow

Two monitor types check APIs. Pick the one that matches what the check needs to do.

TypeUse it when
API endpoint monitorOne request, optionally with a header, basic authentication or a proxy. You want to check the status code, the content type and fields in the JSON response.
API workflow monitorSeveral requests in order — log in, then call an endpoint with the token you got back — or more than one custom header.
info
Endpoints that need a token
An API endpoint monitor sends one request header of your choice. For a fixed token, set Header name to Authorization and Header value to Bearer <token>, or use the API key header your endpoint expects. When the token has to be fetched first, use an API workflow.

Create an API endpoint monitor

  1. 1
    Choose the type

    On the Monitors page, click New, open the type picker and choose API endpoint monitor.

  2. 2
    Enter the endpoint

    Fill in API endpoint URL with the full URL, for example https://api.example.com/v1/health. If you leave off the scheme, https:// is added.

  3. 3
    Add assertions (optional)

    Under Response assertions (optional), click Add assertion for each value you want to check: a path into the JSON body, an operator, and the expected value. See Assertions.

  4. 4
    Set the request and the expected status

    Open Advanced settings. The Request & validation section holds the options below. Then click Create monitor.

SettingDefaultWhat it does
HTTP methodGETGET, POST, PUT, PATCH, DELETE, HEAD or OPTIONS.
Expected status code200 OKThe status the response must have: 200 OK, 201 Created, 202 Accepted, 204 No Content, or Any 2xx (200–299). Any other status fails the check.
Request body (optional)EmptySent with the request as you type it, except that {timestamp} is replaced with the current Unix time in milliseconds on every check.
Max response time30 seconds5, 10, 20, 30 or 60 seconds. A response that takes longer fails the check with a timeout.
Expected content typeapplication/jsonThe media type the response's Content-Type header must have: application/json, text/html, text/plain, or Any to skip the check. Parameters such as ; charset=utf-8 and letter case are ignored.
Follow redirectsOnFollow up to five redirects and judge the final response.
Check frequency3 minutesHow often each region calls the endpoint.

Every request carries a User-Agent header that starts with Zharp Uptime Bot. Below Request & validation, the Request headers and HTTP authentication sections add one request header, HTTP Basic credentials, and an HTTP proxy for endpoints on a private network — they work the same as for website monitors, as do the SSL & domain verification settings.

warning
201, 204 and redirects
With the default of 200 OK, an endpoint that answers 201 or 204 fails. Choose that code or Any 2xx. The same goes for redirects when Follow redirects is off: a 301 never matches an expected 2xx code.

Assertions

Assertions are checked against the JSON response body, after the status code has passed. They run in order, and the first one that fails fails the check. With no assertions, the status code is the only thing checked.

Paths

  • Dots walk into objects: data.status reads {"data": {"status": "ok"}}.
  • Brackets pick an array item: items[0].id.
  • * matches every item of an array (or every value of an object): items.*.status.
  • $ on its own is the whole body.

When a path matches several values, an assertion passes if at least one of them satisfies it. The count operators are the exception: they count how many values the path matched. To count the items in an array, end the path with * — items.* — because items on its own matches one value, the array.

Operators

OperatorPasses when the value…
Equalsis the same as the expected value, compared as text (so 200 equals "200").
Not equalsdiffers from the expected value, compared as text.
Contains / Not containsincludes, or doesn't include, the expected text.
Starts with / Ends withbegins or ends with the expected text.
Greater than, Less than and the or equal formscompares as a number with the expected value.
Existsis present and not null.
Not existsis missing or null.
Is null / Is not nullis, or isn't, exactly null.
Is emptyis an empty string, an empty array or an empty object.
Is not emptyis a non-empty string, array or object.
Count equals, Count greater than, Count less than and the or equal forms— here the number of values the path matched is compared with the expected number.

Exists, Not exists, Is null, Is not null, Is empty and Is not empty take no value, so the value box is hidden for them.

Create an API workflow

Choose API workflow monitor in the type picker. Under Workflow Configuration, pick Designer to build the workflow from steps, or Script Editor to write it as a script.

Designer

Click New Step for each request. Steps run from top to bottom; drag them to change the order. Each step has:

  • Step Name, Method (GET, POST, PUT, PATCH or DELETE) and Endpoint URL.
  • Payload — Request Headers (Add Header) and, for POST, PUT and PATCH, Request Body (JSON). A body that is valid JSON is sent as JSON.
  • Assertions — New Assertion adds a path, operator and value, with the same paths and operators as above. In a workflow step the path status means the HTTP status code, not a field in the body, and a path starting with headers. reads a response header — headers.content-type, with the header name matched regardless of case. The value can use {{NAME}} like the request does.
  • Variables — Extract Value saves something from the response under a name. Choose JSON Body and give a path such as session.token, or Header and give a header name such as Location. If a path matches several values, the first is kept.

Use a saved value in any later step by writing {{NAME}} in its URL, a header value, the body or an assertion value. Names under Environment Variables work the same way from the first step on. A name that hasn't been set is left in the request as written.

A step fails when one of its assertions fails or when its response status is 400 or higher. Add an assertion on status to decide the status yourself — for example to expect a 404. The workflow stops at the first failed step. Each request times out after 30 seconds, follows up to five redirects and sends User-Agent: Zharp/1.0 (Multi-Step Bot) unless you set your own. A workflow with no steps — or a script editor workflow with an empty script — is reported as down, since it checked nothing.

Script Editor

The script editor takes a Playwright test, run in headless Chromium on Zharp's servers. Use the request fixture for API calls. Import lines are ignored, and the whole script must finish within 30 seconds. Store secrets under Environment Variables and read them as process.env.NAME. The script runs in an isolated sandbox: process.env holds only these variables, and there is no access to Node.js modules (require), files or anything else on the server. Requests the script makes — the request fixture, fetch and axios — can't reach private, loopback or cloud-metadata addresses. Run Script runs the script once, with the same environment variables, and shows its output. Supported expect checks are toBe, toEqual, toContain, toBeTruthy, toBeOK, toHaveURL, toContainText, toBeVisible and toHaveTitle.

Example: log in, then call an authenticated endpoint

This workflow checks that users can sign in and load their profile. It logs in with a dedicated monitoring account, keeps the token from the response, and uses it on the next call.

  1. 1
    Step 1 — Log in

    Method POST, Endpoint URL https://api.example.com/v1/auth/login. Request Body (JSON):

    { "email": "monitor@example.com", "password": "your-monitor-password" }

    Assertions: status Equals 200, and token Exists. Variables: name AUTH_TOKEN, from JSON Body, path token.

  2. 2
    Step 2 — Load the profile

    Method GET, Endpoint URL https://api.example.com/v1/me. Add a header Authorization with the value Bearer {{AUTH_TOKEN}}.

    Assertions: status Equals 200, and email Equals monitor@example.com.

The same workflow in the Script Editor, with the password stored as the environment variable MONITOR_PASSWORD:

Playwright script
import { test, expect } from '@playwright/test';

test('log in and read the profile', async ({ request }) => {
  const login = await request.post('https://api.example.com/v1/auth/login', {
    data: { email: 'monitor@example.com', password: process.env.MONITOR_PASSWORD },
  });
  expect(login).toBeOK();
  const { token } = await login.json();

  const me = await request.get('https://api.example.com/v1/me', {
    headers: { Authorization: `Bearer ${token}` },
  });
  expect(me).toBeOK();
  const profile = await me.json();
  expect(profile.email).toBe('monitor@example.com');
});

When it goes down

Expand a failed row under Recent checks or Recent runs on the monitor page to see the message. The incident describes the cause in plain words.

What happenedMessage on the check
The status didn't match Expected status codeHTTP Error: 503 (Expected: 200)
An endpoint assertion failedAssertion Failed: Assertion [data.status equals ok] failed. Actual: degraded
The response's Content-Type wasn't the expected oneUnexpected content type: text/html (Expected: application/json)
The endpoint took longer than Max response timeThe timeout error, for example timeout of 30000ms exceeded
A workflow step got a status of 400 or moreStep failed with status 500
A workflow step assertion failedAssertion [token exists ] failed. Actual: undefined
A workflow step got no responseStep 2 Error:
A workflow script threw or timed outScript Execution Failed:
The workflow has no stepsWorkflow has no steps — add at least one request.

The last two are followed by the underlying error. An API endpoint monitor's page shows the Last response — status, time, size and content type — with each assertion marked passed or failed. Its Recent checks rows open into the request headers, the response status and time, and which assertions passed. An API workflow's page lists Recent runs; open one to see its duration, how many steps completed and the request of the step that failed.

Troubleshooting

  • An assertion fails although the field is there. Assertions read the parsed JSON body. If the endpoint doesn't return JSON, only $ refers to anything. Call the endpoint yourself and check the shape of what comes back — paths are case-sensitive.
  • A count assertion always sees 1. End the path with *, as in items.*.
  • A body field named status can't be checked in a workflow. In a workflow step status is the HTTP status code. Use an API endpoint monitor for that field.
  • The second step gets {{AUTH_TOKEN}} literally. The variable wasn't set. Check the extraction path against what the first step's endpoint returns, and that the name in {{…}} matches the variable name exactly.
  • Only some regions fail. The monitor stays up and its page shows which regions are failing; nobody is alerted. See Core Concepts.