Monitor an API response (API monitor)
The API monitor (API type api, shown in the app as API monitoring/text analysis) is a
Website / HTTPS check that also reads the response body: it parses it as JSON, XML or
text, picks one value out of it and compares that value with what you expect. Use it when “the endpoint answered
200” is not proof enough - you want $.status to be "ok", a queue length to stay under 100, or a price field
to exist.
At a glance
Section titled “At a glance”| API type token | api |
| Runs from | HostTracker’s public checkpoint fleet - you pick the locations |
| Intervals in the app | 1 minute to 24 hours, or a cron schedule |
| Default interval | 3 minutes |
| Plan gates | the API monitoring type is a package feature (apiTask); the Http options keep their own gates |
How Down is decided
Section titled “How Down is decided”Everything the Website monitor checks (DNS, connection, TLS, status below 400, your status-code rules), and then:
- The body must parse in the chosen Response format.
- The Selector picks a value (empty selector = the whole body).
- The Condition must hold for that value. If the selector matches nothing, every condition except
noandnullfails with “No value selected”.
With Assertion mode on, the rule list replaces steps 1-3. A failure is re-checked from other locations before the monitor turns Down - see How down detection works.
Settings reference
Section titled “Settings reference”The API editor is the Website editor with a different Response Validation group. Everything in Common monitor fields, Main Settings, Request Configuration and Monitoring Locations works exactly as on the Website page, with these differences:
- The address field is labelled API endpoint.
- Request body offers Raw body (
settings.body) and POST parameters (settings.postParameters, oneKEY=VALUEper line, sent form-encoded). - Attached monitors offers Domain Expiration, Certificate Expiration and Web Risk. DNSBL and Indexability are not available on API monitors.
- Keywords and Successful content check condition are not part of the API editor. The HTTP Policies picker is, but it has no API member yet.
Response Validation (API-specific)
Section titled “Response Validation (API-specific)”| Setting (app label) | API field | Type / allowed values | Default | Plan limits | What it does for you |
|---|---|---|---|---|---|
| Response format | settings.contentType |
application/json (JSON analysis), text/xml (XML analysis), text/plain (String analysis) |
application/json in the app; required in the API unless assertMode is on |
- | How the body is parsed before the selector runs. Needs GET (or another method that returns a body). |
| Selector | settings.valueSelector |
JSON: property selector or JSONPath ($.data.status); XML: XPath; text: a regular expression with a capture group (multiline, case-insensitive) |
empty = the whole body | - | Picks the value to test. It is compiled when you save, so a broken selector is refused then, not at check time. |
| What to check | settings.expectation.change, settings.expectation.cpt |
Check the obtained value itself (change: 0); Check the value change between checks (change: 1); Change per second (change: 1, cpt: "s"); Change per minute (change: 1, cpt: "m") |
the value itself | - | Judge the value, or how much a number moved since the previous check. Change modes work on numbers only. |
| Condition | settings.expectation.func + settings.expectation.args |
see the table below | any (no validation) - no expectation | - | The comparison that decides Up or Down. |
| Ignore HTTP Errors, Error on these HTTP statuses | settings.ignoredStatuses, settings.errorStatuses |
up to 20 codes each, 100-599 | none | - | As on the Website monitor. |
| Assertion mode | settings.assertMode + settings.assertsSource or settings.asserts |
up to 20 rules; your package may allow fewer | off | assertion count and stateful rules are package features | A rule list instead of format/selector/condition. See Assertions. |
| TLS Handshake switches, Expected IPs Validation, Max response size | as on the Website monitor |
The whole expectation object is limited to 1024 characters.
Condition values:
| App option | func |
args |
The check fails when |
|---|---|---|---|
| any (no validation) | omit expectation |
- | never on the value - only parsing and transport are judged |
| equal to | eq |
one value | the value differs |
| not equal to | neq |
one value | the value matches |
| in set of | in |
one or more values | the value is none of them |
| out of set | out |
one or more values | the value is one of them |
| less than / less or equal | ls / le |
one number | the value is not below (or at most) it |
| greater than / greater or equal | gt / ge |
one number | the value is not above (or at least) it |
| in range | inr |
two ascending numbers | the value is outside [args[0], args[1]] |
| out of range | outr |
two ascending numbers | the value is inside the range |
| json null | null |
none | the selected value is not null (nothing selected counts as null) |
| absent in content | no |
none | never - the check extracts the value and does not compare it |
args are strings in JSON (["ok"], ["100"]). eq, neq, in and out compare the value as it is; the
other conditions, and every condition in a change mode, compare numbers.
Set it up in the app
Section titled “Set it up in the app”- On the Sites dashboard, click Add Monitor and choose API monitoring/text analysis in Monitoring Type.
- Enter the API endpoint and a name.
- In Request Configuration, set the HTTP Method, any HTTP Headers (for example an API key) and the Request body if the endpoint needs one.
- In Response Validation, choose the Response format, type the Selector, pick What to check and a Condition with its value.
- Review Alert Subscriptions and Monitoring Locations, then click Save.
Do it with the API or MCP
Section titled “Do it with the API or MCP”POST /monitor (scope monitor:write), base URL https://api2.host-tracker.com:
curl -X POST https://api2.host-tracker.com/monitor \ -H "Authorization: Bearer $HT_TOKEN" -H "Content-Type: application/json" \ -d '{ "type": "api", "url": "https://api.example.com/health", "interval": 60, "locations": { "pools": ["allworld"] }, "settings": { "contentType": "application/json", "valueSelector": "$.status", "expectation": { "func": "eq", "args": ["ok"] } } }'The same check written as assertion rules instead:
{ "type": "api", "url": "https://api.example.com/health", "interval": 60, "locations": { "pools": ["allworld"] }, "settings": { "assertMode": true, "assertsSource": "status eq 200\nbody.json.path(\"$.status\") eq \"ok\"" }}Update - for example, alert when a queue grows past 100:
curl -X PATCH https://api2.host-tracker.com/monitor/<monitor-id> \ -H "Authorization: Bearer $HT_TOKEN" -H "Content-Type: application/json" \ -d '{ "settings": { "valueSelector": "$.queue.length", "expectation": { "func": "ls", "args": ["100"] } } }'MCP (interval is passed to the API as-is, in seconds):
create_monitor(type="api", url="https://api.example.com/health", interval=60, pools="allworld", settingsJson="{\"contentType\":\"application/json\",\"valueSelector\":\"$.status\",\"expectation\":{\"func\":\"eq\",\"args\":[\"ok\"]}}")update_monitor(id="<monitor-id>", settingsJson="{\"expectation\":{\"func\":\"ls\",\"args\":[\"100\"]}}")Recipes
Section titled “Recipes”- A JSON field equals a value -
contentType: application/json,valueSelector: $.status,expectation: {func: eq, args: ["ok"]}. - A number stays in range -
valueSelector: $.latency_ms,expectation: {func: inr, args: ["0", "500"]}. - A counter keeps growing -
expectation: {func: gt, args: ["0"], change: 1}(fails if it stops moving up). - An XML element -
contentType: text/xml,valueSelector: /response/status,func: eq. - A value in plain text -
contentType: text/plain,valueSelector: version=(\d+),func: ge. - Several conditions at once - use assertion mode; one rule per line.
- Authenticated API - add
headers: [{"name": "Authorization", "value": "Bearer ..."}].
What happens next
Section titled “What happens next”Each check downloads the body (up to Max response size), parses it and records the selected value in the check log, so you can see what was compared. A failed condition is re-checked from other locations, then opens an incident and alerts the subscribed contacts.
Limits and gotchas
Section titled “Limits and gotchas”403 package_limit- your package does not include the API monitoring type.422 invalid_settings- a malformed selector, a wrong number ofargsfor thefunc(two ascending numbers forinr/outr, at least one forin/out, exactly one for the comparisons), orcontentTypemissing while assertion mode is off.assertModerefusescontentType,valueSelectorandexpectationin the same monitor, as well as the Http status and keyword fields.- HEAD returns no body, so use GET (or POST/PUT/PATCH) for a format and selector check.
- The absent in content option (
no) does not test absence; to fail when a field is missing, use any comparison - a missing value fails it.

