HTTP monitors (advanced)
The “light” http type in active monitors performs only
GET <url> and compares the status code with 2xx (or expectedStatus). That’s
enough for a simple health-check, but doesn’t cover cases like “send POST /api/login
with a JSON body and an Authorization header, then check that the response contains
"status":"ok" and code 200”.
An HTTP monitor is a separate entity with its own REST API that supports:
- arbitrary method —
GET,POST,PUT,PATCH,DELETE,HEAD; - arbitrary headers (
headers) — a JSON object{"Header": "Value"}; - request body (
body) — forPOST/PUT/PATCH; - response filtering — by status code, range of codes, substring/regex in body, value by JSONPath, and maximum response time;
- two reaction modes — alert on a filter “match” or “mismatch”.
Interval, timeout, consecutive failures, alert/recovery texts and pausing work the same as for regular monitors.
Monitor fields
Section titled “Monitor fields”| Field | Type | Required | Description |
|---|---|---|---|
appid | number | yes | ID of the channel to send notifications to |
name | string | yes | Monitor name, 1–200 characters |
method | string | yes | GET, POST, PUT, PATCH, DELETE, HEAD (case-insensitive) |
url | string | yes | A valid http(s) URL pointing to a public address |
headers | string | no | JSON object of headers: {"Authorization": "Bearer ..."} |
body | string | no | Request body (for POST/PUT/PATCH) |
intervalSec | number | yes | Interval between checks, 30–86400 seconds |
timeoutSec | number | no | Timeout for one attempt, default 10, maximum 30 |
filterMode | string | yes | alert_on_match or alert_on_mismatch (see below) |
filters | string | yes | JSON array of filters (see Response filters); may be [] |
consecutiveFails | number | no | How many consecutive failures before alert, default 1, maximum 20 |
alertMessage | string | yes | Notification text when triggered, 1–2000 characters |
alertTitle | string | no | Notification title |
alertPriority | number | no | Notification priority, 0–10 (recovery is sent with it too) |
recoveryTitle | string | no | Recovery message title |
recoveryMessage | string | no | Text when returning to normal (if empty — no recovery is sent) |
URLs pointing to private, loopback or link-local addresses are rejected (400) —
both on save and in the test request; redirects to such addresses are blocked too.
Redirects to public addresses are followed, and filters apply to the final response.
Response filters
Section titled “Response filters”filters is a JSON array of objects. Each object is one condition; within an
object all specified fields must hold at the same time (AND), and the array as a
whole matches if at least one object matches (OR). Available filter fields:
| Filter field | Type | What it checks |
|---|---|---|
statusCode | number | Exact HTTP code (0 = don’t check) |
statusCodeMin / statusCodeMax | number | Range of codes [min, max] inclusive (0,0 = don’t check; without max — up to 999) |
bodyContains | string | Substring that must be contained in the body |
bodyRegex | string | Regular expression (Go syntax) for the body |
jsonPath | string | Path in a JSON response: $.status, data.0.id; without jsonPathValue — must exist |
jsonPathValue | string | Expected value at jsonPath (string comparison: 200, true, ok) |
maxDurationMs | number | Maximum allowed response time in ms (0 = don’t check) |
For bodyContains, bodyRegex and jsonPath the body is read up to 64 KB. JSONPath
is a simple $.a.b traversal with numeric array indexes $.a.0.b. An invalid
bodyRegex is not rejected on save — such a filter simply never matches.
Filter mode (filterMode)
Section titled “Filter mode (filterMode)”alert_on_mismatch— describe what a normal response looks like. If the actual response does not match the filters — the check fails. This is a whitelist logic and the most common scenario.alert_on_match— describe a problematic response. If the actual response matches the filter — the check fails. Useful to catch specific errors.
A network error or timeout is a failure in either mode.
// filterMode = "alert_on_mismatch":// normal — code 200 and JSON {"status":"ok"}; otherwise alert.[ { "statusCode": 200, "jsonPath": "$.status", "jsonPathValue": "ok" }]
// filterMode = "alert_on_match":// alert if the word "maintenance" appears in the body OR the code is in 5xx.[ { "bodyContains": "maintenance" }, { "statusCodeMin": 500, "statusCodeMax": 599 }]
// normal — responds faster than 800 ms and code 2xx (filterMode = "alert_on_mismatch"):[ { "statusCodeMin": 200, "statusCodeMax": 299, "maxDurationMs": 800 }]States and events
Section titled “States and events”An HTTP monitor uses the same statuses as regular monitors: pending
(created or resumed, no checks yet), up, degraded (there are failures, but the
consecutiveFails threshold has not yet been reached), down and paused.
| Event | When | Text |
|---|---|---|
| Alert | After consecutiveFails failed checks in a row, once per outage. The reason is appended in parentheses: response mismatch: status=… duration=…ms, alert condition matched: … or the network error text | alertTitle + alertMessage |
| Recovery | On the first successful check after down — only if recoveryMessage is set and an alert about the outage was actually sent | recoveryTitle + recoveryMessage |
There is no alert spam: once an alert is sent, the monitor records the moment in
the alertedAt field and sends nothing more while it stays down — checks
continue and only record the status. The exception is re-arm: if you change
check parameters via PUT /http-monitor/:id (method, URL, headers, body,
interval, timeout, filterMode, filters, consecutiveFails), alertedAt is
cleared and the monitor is checked right away; if the response is still bad, a fresh
alert arrives. Editing the name, texts or priority does not shift the schedule and does not re-arm.
What else affects notifications — same as for regular monitors:
- Maintenance windows: during a window checks run and are recorded in history, but the alert is deferred — if the response is still bad after the window, the very first check sends it. Down and back up within the window — neither alert nor recovery is sent.
- Quiet hours suppress escalation to external channels for
messages with priority below
breakthroughPriority(8 by default). - The channel’s status page: going
downopens an auto-incident, recovery closes it. - Each check is one event of the daily quota; when it is exhausted, checks are postponed until the next day.
Besides settings, the monitor record stores status, failCount, lastCheckAt,
lastError, lastStatusCode, lastBodyPreview (first 512 bytes of the response),
nextCheckAt and alertedAt. Check history —
GET /monitor-history/http_monitor/:id (see Active monitors).
Test request
Section titled “Test request”Before creating a monitor you can perform a one-time test request and inspect the
response — nothing is saved. POST /http-monitor/test accepts method, url, headers,
body, timeoutSec (default 10, up to 60) and returns statusCode,
bodyPreview (first 2048 bytes), headers (JSON of response headers), durationMs
and error (if the request failed). The test request does not apply filters.
curl -X POST "$NOTIFLY_URL/http-monitor/test" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <api-token>" \ -d '{ "method": "POST", "url": "https://api.example.com/login", "headers": "{\"Content-Type\": \"application/json\"}", "body": "{\"user\":\"probe\",\"pass\":\"...\"}", "timeoutSec": 10 }'# → {"statusCode":200,"bodyPreview":"{\"status\":\"ok\"}","headers":"{...}","durationMs":134}Creating a monitor
Section titled “Creating a monitor”Via the web UI
Section titled “Via the web UI”- Open app.notifly.ru → Monitors → Create → “Website or API is up” (or the HTTP requests tab → “Create HTTP monitor”).
- Specify the name, channel, method, URL, and optionally — headers and body. Use the “Test request” button to see what comes back.
- Configure the interval, timeout and number of consecutive failures.
- Describe the response filters and choose the filter mode.
Via the REST API
Section titled “Via the REST API”curl -X POST "$NOTIFLY_URL/http-monitor" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <api-token>" \ -d '{ "appid": 12345, "name": "API login health", "method": "POST", "url": "https://api.example.com/login", "headers": "{\"Content-Type\": \"application/json\"}", "body": "{\"user\":\"probe\",\"pass\":\"...\"}", "intervalSec": 60, "timeoutSec": 10, "filterMode": "alert_on_mismatch", "filters": "[{\"statusCode\":200,\"jsonPath\":\"$.status\",\"jsonPathValue\":\"ok\"}]", "consecutiveFails": 2, "alertMessage": "Login endpoint is not responding as expected!", "alertPriority": 9, "recoveryMessage": "Login works again." }'The fields headers, body and filters are passed as strings (JSON inside JSON),
so in the curl examples their contents are escaped. PUT /http-monitor/:id
accepts the same full set of fields (except appid — the channel cannot be changed).
Via MCP (for the AI assistant)
Section titled “Via MCP (for the AI assistant)”If a Notifly MCP server is configured (see MCP), it’s enough to describe the task in words:
Create an HTTP monitor: POST to https://api.example.com/login with a JSON body, check every minute that the code is 200 and the response has status=ok, alert after 2 consecutive failures.
REST API
Section titled “REST API”| Method | Path | Description |
|---|---|---|
GET | /http-monitor | List user’s HTTP monitors |
POST | /http-monitor | Create |
POST | /http-monitor/test | One-time test request (without saving) |
PUT | /http-monitor/:id | Update settings (cannot change appid) |
DELETE | /http-monitor/:id | Delete |
POST | /http-monitor/:id/pause | Pause checks |
POST | /http-monitor/:id/resume | Resume: status pending, checked right away |
Authorization — the X-Notifly-Key header with an API token (or a
device token). Create, update, delete, pause and resume require write access for an
API token; listing and POST /http-monitor/test only need read. A token restricted
to certain channels sees and changes only the monitors of those channels. Channel
share tokens are not allowed on these endpoints (403). The monitor’s channel must be
yours or shared with you with send permission.
Related monitors
Section titled “Related monitors”- Active monitors — protocol checks: HTTP
GET, TCP, DNS, SSL certificates, databases, mail, queues and more. - Content monitors — track changes in page content.
- Workflow monitors — chains of HTTP steps with value extraction.
- Browser-workflow — scenarios in a real browser.