Monitorion covers every layer of your infrastructure — from basic HTTP uptime to Core Web Vitals, DNS integrity, email server health, and cryptographic certificate validity.
Full-stack HTTP availability and response validation
The HTTP monitor performs a real HTTP/HTTPS request to your URL at a configured interval and validates the response against a set of assertions — status code, body keywords, CSS selector presence, DOM element count, content size, and response-time anomaly thresholds. It is the foundation of uptime monitoring and works for any publicly reachable web endpoint.
| Field | Type | Required | Description |
|---|---|---|---|
| url | string |
| Yes |
| Full URL to request (https://example.com or http://...). HTTPS is strongly recommended. |
| method | enum | No | HTTP method to use. Default GET. Only GET, POST, PUT, DELETE, and HEAD are supported (not PATCH/OPTIONS). |
| expectedStatusCode | number | No | Expected HTTP status code. Defaults to accepting any 2xx/3xx. Set to a specific code (e.g., 200) to require an exact match — any deviation triggers an alert. |
| keyword | string | No | A text string that must appear (substring contains match) in the response body. Case-sensitive. |
| headers | object | No | Key/value pairs sent as request headers (e.g., Authorization, Accept-Language). |
| body | string | No | Request body for POST/PUT/DELETE requests. Typically JSON or form-encoded. |
| timeout | number | No | Maximum time in milliseconds to wait for a response. Default 30 000. Max 120 000. |
| retryCount | number | No | Automatic retries on failure before marking down. Default 2, capped at 3. Uses exponential backoff. |
| selectorChecks | array | No | Array of {selector, description} objects. Each CSS selector must exist in the DOM; a missing element marks the check down. |
| minDomElements | number | No | Alert (white-screen detection) if the page contains fewer than N DOM elements. |
| contentSizeThreshold | number | No | Alert if the page content shrinks by more than N% compared to its stored baseline (0–100). Baseline auto-captured on first success. |
| responseTimeAnomalyFactor | number | No | Alert when response time exceeds N × the rolling average. Default 2. |
| Status | Meaning |
|---|---|
| up | Request succeeded, all assertions passed, response within timeout. |
| down | Status code mismatch, keyword not found, selector/DOM/content-size anomaly, or connection refused. |
| degraded | Request succeeded but response time triggered a response-time anomaly warning (warning only, no incident). |
| timeout | No response within the configured timeout. |
{
"type": "http",
"name": "Marketing Homepage",
"url": "https://example.com",
"method": "GET",
"expectedStatusCode": 200,
"keyword": "Welcome to Acme",
"headers": {
"Accept-Language": "en-US"
},
"selectorChecks": [
{ "selector": "#add-to-cart", "description": "Add to Cart button" }
],
"timeout": 30000,
"retryCount": 2
}Network-layer reachability using ICMP echo requests
The Ping monitor sends ICMP echo request packets to a hostname or IP address and measures round-trip latency and packet loss. Unlike HTTP monitoring, Ping operates at the network layer — useful for bare-metal servers, VMs, and devices that do not expose an HTTP endpoint. Note that some hosting providers and firewalls block ICMP; in such cases the monitor will report the host as down even if it is functional.
| Field | Type | Required | Description |
|---|---|---|---|
| host | string | Yes | Hostname (db.example.com) or IPv4/IPv6 address to ping. |
| count | number | No | Number of ICMP packets to send per check. Default 4. Cap 10. |
| timeout | number | No | Per-packet timeout in milliseconds (derived from the monitor timeout). Internally clamped to 1–10 s. No form field — defaults to the monitor timeout. |
| Status | Meaning |
|---|---|
| up | Host is reachable and responding to ICMP echo requests. |
| down | Host is unreachable or no ICMP reply received within the timeout. |
{
"type": "ping",
"name": "Primary Database Server",
"host": "db.internal.example.com",
"count": 4,
"timeout": 5
}Track certificate validity, expiry, and chain integrity
The SSL Certificate monitor connects to a domain over TLS, retrieves the certificate chain, and reports on expiry date, issuer, and chain validity. It alerts you before your certificate expires so you never serve a browser security warning to your visitors. Supports wildcard certificates.
| Field | Type | Required | Description |
|---|---|---|---|
| domain | string | Yes | Domain name to check (e.g., example.com). Do not include https:// or a path. |
| port | number | No | Port to connect on. Default 443. Use 8443 or custom ports for non-standard HTTPS. |
| daysBeforeExpiry | number | No | Trigger an expiring warning alert this many days before expiry. Default 30. |
| criticalDays | number | No | Trigger a critical alert this many days before expiry. Default 7. |
| timeout | number | No | Connection + TLS handshake timeout in milliseconds. Default 10 000. |
| Status | Meaning |
|---|---|
| up | Certificate is valid, chain is intact, and expiry is beyond the warning threshold. |
| down | Certificate chain is broken, domain mismatch, expired certificate, or connection could not be established. |
| expiring | Certificate expires within daysBeforeExpiry days. Take action to renew. |
| critical | Certificate expires within criticalDays days. Immediate renewal required. |
{
"type": "ssl_cert",
"name": "Production HTTPS Certificate",
"domain": "example.com",
"port": 443,
"daysBeforeExpiry": 30,
"criticalDays": 7
}WHOIS-based tracking of domain registration expiry
The Domain Expiry monitor performs a WHOIS lookup for your domain name and extracts the expiration date reported by the registry. It alerts you before the domain lapses so you never lose a domain to accidental non-renewal. The monitor also surfaces the registrar, registration, and updated dates for quick reference.
| Field | Type | Required | Description |
|---|---|---|---|
| domain | string | Yes | Fully qualified domain name (e.g., example.com, mycompany.io). TLDs with WHOIS restrictions may have limited data. |
| daysBeforeExpiry | number | No | Warn this many days before registration expiry. Default 30. |
| criticalDays | number | No | Critical alert this many days before expiry. Default 7. |
In addition to status, the monitor dashboard card shows: Registrar name, Registration date (from WHOIS), Updated date, and Days remaining until expiry.
| Status | Meaning |
|---|---|
| ok | Domain is registered and expiry is beyond the warning threshold. |
| warning | Domain expires within daysBeforeExpiry days. |
| critical | Domain expires within criticalDays days — renew immediately. |
| down | Domain registration has lapsed. It may be in redemption period or available for registration. |
| error | WHOIS lookup failed (registry throttle, unsupported TLD, or network error). |
{
"type": "domain_expiry",
"name": "Company Primary Domain",
"domain": "example.com",
"daysBeforeExpiry": 30,
"criticalDays": 7
}TCP / UDP connectivity checks for any host:port combination
The Port monitor attempts to open a TCP or UDP connection to a specified host and port number. It verifies that the service is accepting connections within the configured timeout, without regard to application-layer protocol. Ideal for databases, SSH servers, game servers, custom daemons, and any service not reachable over HTTP.
| Field | Type | Required | Description |
|---|---|---|---|
| host | string | Yes | Hostname or IP address of the server to check. |
| port | number | Yes | TCP or UDP port number (1–65 535). Common: 22 (SSH), 3306 (MySQL), 5432 (Postgres), 6379 (Redis), 27017 (MongoDB). |
| protocol | enum | No | "tcp" (default) or "udp". UDP checks send a probe packet and listen for a response. |
| timeout | number | No | Connection timeout in milliseconds. Default 10 000. |
| Status | Meaning |
|---|---|
| up | Connection established successfully within the timeout. |
| down | Connection refused (port actively rejecting connections) or no response received (firewall drop, overloaded host, wrong address). |
| timeout | No response received within the configured timeout. |
{
"type": "port",
"name": "Production PostgreSQL",
"host": "db.prod.example.com",
"port": 5432,
"protocol": "tcp",
"timeout": 10000
}Alert on unexpected changes to A, AAAA, CNAME, MX, TXT, NS, SOA, PTR, SRV, and CAA records
The DNS Records monitor performs authoritative DNS lookups at regular intervals and compares the returned records against a known-good baseline. Any deviation — new records, removed records, or changed values — triggers an immediate alert. This protects against DNS hijacking, accidental zone edits, propagation failures, and forgotten TTL-cached stale values.
| Field | Type | Required | Description |
|---|---|---|---|
| domain | string | Yes | Domain or subdomain to query (e.g., example.com, mail.example.com). |
| recordType | string | Yes | DNS record type to monitor: A, AAAA, CNAME, MX, TXT, NS, SOA, PTR, SRV, or CAA. |
| expectedValue | string | No | Expected value(s) as a single string. Matched case-insensitively as a substring of the resolved records. Leave empty to auto-capture a baseline on first successful check. |
| nameserver | string | No | Custom resolver IP or hostname. If unset, the system resolver is used. Useful for checking authoritative servers directly. |
| Status | Meaning |
|---|---|
| up | DNS query succeeded and the resolved records are unchanged (or match the expected value). |
| changed | Resolved records differ from the stored baseline or the expected value. Alert fired. |
| down | Domain does not exist (NXDOMAIN), the query timed out, or a resolver error occurred. |
{
"type": "dns",
"name": "Root A Record – example.com",
"domain": "example.com",
"recordType": "A",
"expectedValue": "203.0.113.42"
}{
"type": "dns",
"name": "MX Records – example.com",
"domain": "example.com",
"recordType": "MX",
"expectedValue": "mail.example.com"
}Reverse monitoring — your job pings Monitorion; we alert if it stops
Unlike all other monitor types, the Heartbeat monitor works in reverse: instead of Monitorion reaching out to your system, your system (a cron job, backup script, CI pipeline, or any scheduled task) makes a simple HTTP POST request to a unique Monitorion URL after each successful run. If Monitorion does not receive a ping within the configured period plus grace time, it fires an alert. This catches silent cron failures, missed backups, and stuck ETL pipelines.
After creating the monitor, you receive a unique ping URL like:
# Ping URL format (POST only)
{NEXT_PUBLIC_APP_URL}/api/heartbeat/{monitorId}?token=...
# Add to your cron job (curl POST)
0 3 * * * /usr/local/bin/backup.sh && \
curl -s -X POST "{NEXT_PUBLIC_APP_URL}/api/heartbeat/{monitorId}?token=..."| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Human-readable name for the job (e.g., "Nightly DB Backup"). |
| expectedIntervalSeconds | number | Yes | How often you expect a ping. Set in minutes via the UI (60 = hourly, 1 440 = daily); stored in seconds. |
| gracePeriodSeconds | number | No | Extra time to wait before alerting after the interval elapses. Set in minutes via the UI; stored in seconds. Accounts for job duration variance. Default 5 minutes. |
| Status | Meaning |
|---|---|
| up | A ping was received within the expected period (the UI shows this as healthy/on time). |
| down | No ping received after period + grace period. Alert has fired (the UI shows this as late/missed). |
Grade your HTTP response headers from A to F
The Security Headers monitor fetches a URL and analyses the HTTP response headers against security best practices. It awards a letter grade (A to F) and flags each missing or misconfigured header individually. Headers are checked against the OWASP Secure Headers Project recommendations and Mozilla Observatory criteria.
| Header | Impact | What it prevents |
|---|---|---|
| Content-Security-Policy | Critical | XSS and data injection attacks |
| Strict-Transport-Security | Critical | Protocol downgrade and cookie hijacking |
| X-Frame-Options | High | Clickjacking via iframes |
| X-Content-Type-Options | Medium | MIME-sniffing attacks |
| Referrer-Policy | Medium | Sensitive URL leakage to third parties |
| Permissions-Policy | Medium | Unauthorised access to browser APIs (camera, mic, GPS) |
| Cross-Origin-Opener-Policy | Medium | Cross-origin info leaks via window.opener |
| X-XSS-Protection | Medium | Legacy XSS filter (largely obsolete in modern browsers) |
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL to fetch and analyse. Should be the canonical HTTPS root of your site. |
| timeout | number | No | Request timeout in milliseconds. Default 10 000. |
| fail_on_missing | string[] | No | Header names that must be present. If any listed header is missing the check is marked down. Leave empty to grade only (missing critical headers become a warning, not an incident). |
| Status | Meaning |
|---|---|
| up | All checked headers are present and a grade was awarded. |
| warning | One or more critical headers are missing — a quality issue, not an outage. No incident is created. |
| down | A header listed in fail_on_missing is absent, or the target could not be fetched. |
The letter grade is a 0–100 score normalised from the presence of each header, weighted by severity (critical 15, important 10, optional 5). There is no A+: A = 80+, B = 60+, C = 40+, D = 20+, F < 20.
Check your IP or domain against DNSBL spam blacklists
The Blacklist monitor queries your IP address or domain against a curated set of DNS-based block lists (DNSBLs). Being listed on a blacklist can silently destroy your email deliverability, cause your website to be blocked by corporate firewalls, and reduce SEO visibility. By default findings are informational (the check stays up and no incident fires); enable fail_on_blacklist to be alerted the moment any listing is detected.
IP addresses are queried against IP-based DNSBLs; domains are queried against SURBL. Public DNSBLs are best-effort and can yield false results for datacenter IPs — treat results as informational unless fail_on_blacklist is enabled.
| Field | Type | Required | Description |
|---|---|---|---|
| target | string | Yes | IPv4 address or domain name to check against the blacklists. IPv6 is not supported. |
| timeout | number | No | Overall DNSBL query timeout in milliseconds. Default 10 000. |
| fail_on_blacklist | boolean | No | When false (default) a listing is informational only — status stays up and no incident fires. Set true to alert (down) on any listing. |
| Status | Meaning |
|---|---|
| up | Not listed on any checked blacklist, or listed but fail_on_blacklist is disabled (informational). |
| down | Found on one or more blacklists with fail_on_blacklist enabled, or a query error occurred. |
Detect changes in page content or targeted CSS selector elements
The Content Change monitor fetches a URL and detects changes. In the default hash mode it hashes the page content and compares it against a stored snapshot, alerting with a diff when content changes. Text modes can watch for the presence or absence of a specific string. Useful for price tracking, legal policy monitoring, competitor analysis, or detecting unauthorised site modifications.
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL of the page to monitor for changes. |
| check_type | enum | No | Detection mode: "hash" (default, whole-page hash diff), "text_contains" (alert when expected_text appears), or "text_absent" (alert when expected_text disappears). |
| expected_text | string | No | Text string used by text_contains / text_absent modes. |
| ignore_scripts | boolean | No | Strip <script> blocks (and their contents) from the page before hashing. Default false. |
| ignore_styles | boolean | No | Strip <style> blocks (and their contents) from the page before hashing. Default false. |
| timeout | number | No | Request timeout in milliseconds. Default 10 000. |
| Status | Meaning |
|---|---|
| up | Content matches the stored baseline (hash mode) or the text condition is not met (text modes). |
| changed | Content differs from the stored baseline, or expected_text appeared/disappeared. Alert fired with a diff preview. |
| down | Page could not be fetched. |
{
"type": "content_change",
"name": "Competitor Pricing Page",
"url": "https://competitor.com/pricing",
"check_type": "hash",
"ignore_scripts": true,
"ignore_styles": true,
"timeout": 10000
}Verify email server connectivity, EHLO handshake, and STARTTLS support
The SMTP monitor opens a TCP connection to your mail server and performs an SMTP EHLO/HELO handshake (the EHLO domain is hardcoded), then reports the server capabilities and response time. It does not send an actual email — it only verifies that the mail server is reachable and responding correctly.
| Field | Type | Required | Description |
|---|---|---|---|
| host | string | Yes | Hostname of the SMTP server (e.g., smtp.example.com, mail.example.com). |
| port | number | No | SMTP port. Default 25. Common: 25 (MTA), 465 (SMTPS), 587 (submission). |
| use_tls | boolean | No | Use implicit TLS from the start. Defaults to true only on port 465; otherwise the connection is plaintext. |
| timeout | number | No | Connection + handshake timeout in milliseconds. Default 10 000. |
| Status | Meaning |
|---|---|
| up | SMTP server is reachable and the EHLO handshake succeeded. |
| down | Connection refused, timeout, or SMTP protocol error during the handshake. |
{
"type": "smtp",
"name": "Postfix Submission Port",
"host": "smtp.example.com",
"port": 587,
"timeout": 10000
}Verify WebSocket upgrade, connection stability, and optional message round-trip
The WebSocket monitor opens a connection to a WS or WSS endpoint, performs the HTTP Upgrade handshake, and optionally sends a message and validates the server's response. This ensures your real-time infrastructure — live dashboards, chat backends, financial data feeds, multiplayer game servers — is actually accepting and processing WebSocket connections end-to-end.
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | WebSocket endpoint URL. Must start with ws:// or wss:// (e.g., wss://realtime.example.com/socket). |
| send_message | string | No | Message to send after successful connection. Can be JSON, a heartbeat ping, or any protocol-specific payload. |
| expected_response | string | No | Substring that must appear in the server's response message. Alert if absent or no response received. |
| timeout | number | No | Total check timeout including connection + message round-trip in milliseconds. Default 10 000. |
| Status | Meaning |
|---|---|
| up | WebSocket upgrade succeeded. If send_message is set, a response was received and matched expected_response. |
| down | WebSocket upgrade rejected, connection refused, TLS handshake failed, response mismatch, or timeout. |
{
"type": "websocket",
"name": "Realtime Dashboard Feed",
"url": "wss://realtime.example.com/socket",
"send_message": "{"type":"ping"}",
"expected_response": "pong",
"timeout": 10000
}Crawl a page and surface all 4xx / 5xx links automatically
The Broken Links monitor fetches an HTML page, extracts every href anchor URL, and performs a HEAD request against each one (falling back to GET when the server rejects HEAD). Any link returning a 4xx or 5xx status code is reported as broken. Non-HTTP schemes (mailto, javascript, tel, data) are always skipped.
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL of the page to crawl (not a full-site crawl — single page only per monitor). |
| check_external | boolean | No | Also check links pointing to external domains. Default false — external links are skipped unless enabled. |
| max_links | number | No | Maximum number of links to check per run. Default 50. Clamped to 5–200. |
| timeout | number | No | Overall budget for the whole run (page fetch + all link checks) in milliseconds. Default 60 000. |
| Status | Meaning |
|---|---|
| up | Every checked link returned a non-4xx/5xx response. |
| down | One or more links returned 4xx/5xx, or the base page could not be fetched. Alert lists each broken URL and its status code. |
Send a query to your GraphQL endpoint and assert the response
The GraphQL monitor sends a configurable GraphQL query (or mutation) to an endpoint and validates that the response does not contain errors and optionally matches an expected value at a dot-path within the data. This enables deep health-checking of your GraphQL API beyond a basic HTTP 200 check — verifying that resolvers are functioning correctly end-to-end.
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | GraphQL endpoint URL (e.g., https://api.example.com/graphql). Must accept POST requests. |
| query | string | Yes | GraphQL query or mutation string. Use introspection-safe queries for health checks. |
| variables | object | No | GraphQL variables object passed alongside the query. |
| headers | object | No | HTTP headers (e.g., Authorization for authenticated endpoints). |
| expected_field | string | No | Dot-path to a data field to assert on (e.g., data.users.0.id — no JSONPath $ prefix). |
| expected_value | string | No | Expected string value at expected_field. Alert if the value does not match. |
| timeout | number | No | Request timeout in milliseconds. Default 10 000. |
| Status | Meaning |
|---|---|
| up | HTTP 200, no "errors" in the response, and any expected_field/value assertion passed. |
| down | Non-200 HTTP status, response contains an "errors" array, expected_field/value mismatch, or request timed out. |
{
"type": "graphql",
"name": "Users API Health",
"url": "https://api.example.com/graphql",
"query": "query HealthCheck { users(limit: 1) { id } }",
"headers": {
"Authorization": "Bearer health-token-readonly"
},
"expected_field": "data.users.0.id",
"expected_value": "1",
"timeout": 10000
}Fetch sitemap.xml and verify all listed URLs are reachable
The Sitemap monitor fetches your sitemap.xml (or a sitemap index, fetching up to 50 child sitemaps), parses all listed URLs, deduplicates them, and performs a HEAD request against each one (in batches of 10) until it hitsmax_urls. Any URL returning 4xx, 5xx, or a network error is reported as broken. This catches pages that have been deleted, redirected incorrectly, or accidentally set to noindex without being removed from the sitemap — all of which harm SEO.
URLs to probe are capped by your plan: Pro: 100, Business / Agency: 500. The number of URLs actually HEAD-checked in a run is also bounded by the overall check timeout (default 60 s) — URLs that respond quickly all get checked within the budget; slower targets mean fewer URLs are probed per run. Only the first max_urlsURLs are checked (they are not sampled across a larger set).
| Field | Type | Required | Description |
|---|---|---|---|
| sitemap_url | string | Yes | URL of your sitemap (e.g., https://example.com/sitemap.xml or a sitemap index file). |
| max_urls | number | No | Maximum number of URLs to HEAD-check per run. Default 100. Capped by plan (Pro: 100, Business/Agency: 500). |
| timeout | number | No | Overall budget for the whole run in ms (fetching the sitemap(s) + URL checks). Default 60 000. |
| Status | Meaning |
|---|---|
| up | Sitemap parsed and all HEAD-checked URLs returned 2xx/3xx. |
| down | The sitemap could not be fetched/parsed, or one or more checked URLs returned 4xx/5xx or a network error. The broken URLs are shown in the result. |
PageSpeed Insights scores for Performance, Accessibility, SEO, and Best Practices
The Lighthouse monitor calls the Google PageSpeed Insights API to run a full Lighthouse audit against your URL and records the four category scores (0–100) plus Core Web Vital and lab metrics (LCP, INP, CLS, FCP, TBT, SI, TTI). Scores are tracked over time so you can correlate deployment events with performance regressions. Alerts fire when the Performance score drops below your configured threshold (min_score); the other categories are recorded but not alert-thresholded.
| Metric | Type | Good threshold | What it measures |
|---|---|---|---|
| Performance | Score 0–100 | ≥ 90 | Overall page load speed composite score (the only alert-thresholded category) |
| Accessibility | Score 0–100 | ≥ 90 | ARIA, colour contrast, keyboard navigation |
| Best Practices | Score 0–100 | ≥ 90 | HTTPS, modern APIs, console errors |
| SEO | Score 0–100 | ≥ 90 | Meta tags, crawlability, structured data |
| LCP | Time (ms) | ≤ 2 500 ms | Largest Contentful Paint — main content load |
| INP | Time (ms) | ≤ 200 ms | Interaction to Next Paint — input responsiveness |
| CLS | Score | ≤ 0.1 | Cumulative Layout Shift — visual stability |
| FCP | Time (ms) | ≤ 1 800 ms | First Contentful Paint — first content render |
| TBT | Time (ms) | ≤ 200 ms | Total Blocking Time — main-thread blocking between FCP and TTI |
| SI | Time (ms) | ≤ 3 400 ms | Speed Index — how quickly content is visually displayed |
| TTI | Time (ms) | ≤ 3 800 ms | Time to Interactive — when the page is fully interactive |
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | URL to audit. Must be publicly accessible (PageSpeed API fetches from Google servers). |
| strategy | enum | No | "mobile" (default) or "desktop". Mobile strategy simulates throttled 4G connection. |
| categories | string[] | No | Lighthouse categories to request. Default: performance, accessibility, best-practices, seo. |
| min_score | number | No | Alert (down) if the Performance score drops below this value (0–100). Default 0 (never alert on score). |
| Status | Meaning |
|---|---|
| up | PageSpeed audit completed and the Performance score meets or exceeds min_score. |
| down | Performance score dropped below min_score, or the PageSpeed API returned an error. |
Detect HTTP resources loaded on HTTPS pages that trigger browser warnings
The Mixed Content monitor fetches an HTTPS page and inspects all resource references (images, scripts, stylesheets, iframes, fonts, media) for any that use an insecure http:// URL. Browsers block or warn about mixed content because HTTP resources on HTTPS pages can be intercepted and modified by an attacker. This silently breaks images, fonts, and scripts — degrading user experience and trust indicators.
| Resource Type | Severity | Browser behaviour |
|---|---|---|
| Scripts (JS) | Critical | Blocked by default in all modern browsers |
| Stylesheets (CSS) | Critical | Blocked by default in all modern browsers |
| iframes | Critical | Blocked by default |
| Images | Warning | Shown but browser displays lock icon warning |
| Audio / Video | Warning | Shown but triggers security warning |
| Fonts | Warning | May be shown with warning or blocked in strict mode |
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | HTTPS URL to scan. Must use https:// — the check is only meaningful on secure pages. |
| timeout | number | No | Fetch timeout in milliseconds. Default 10 000. |
| Status | Meaning |
|---|---|
| up | No HTTP resources found on the HTTPS page. A non-HTTPS URL also returns up with a note that scanning was skipped. |
| down | One or more http:// resources (script, stylesheet, image, iframe, media, object, or CSS url()) were found on the page. |
{
"type": "mixed_content",
"name": "Homepage Mixed Content",
"url": "https://example.com",
"timeout": 10000
}Validate JSONPath assertions against any JSON API response
The JSON API monitor fetches a URL and validates JSONPath assertions against the JSON response body. It catches the common case where an API returns HTTP 200 but the response body contains an error — something a plain HTTP monitor misses entirely.
| Field | Type | Default | Description |
|---|---|---|---|
| url | string | Required | Endpoint URL to check |
| method | string | GET | HTTP method: GET, POST, PUT |
| headers | object | {} | Request headers as key/value pairs |
| body | string | Request body (JSON string) sent with POST/PUT requests | |
| timeout | number | 10000 | Request timeout in milliseconds |
| assertions | array | [] | List of JSONPath assertions to evaluate |
| Op | Meaning | Example |
|---|---|---|
| eq | Equals (loose) | $.status eq "ok" |
| ne | Not equals | $.status ne "error" |
| gt | Greater than | $.users.count gt 0 |
| lt | Less than | $.latency_ms lt 500 |
| contains | String/array contains | $.tags contains "prod" |
| exists | Field exists (not null) | $.data exists |
| not_exists | Field is null/missing | $.error not_exists |
$.data.user.email, array index: $[0].name, and nested arrays: $.items[2].price.Status values
Track redirect hops and alert when chains change
Monitors the full redirect chain from a starting URL. The first check stores the chain as a baseline. Subsequent checks alert if the chain changes — useful for detecting broken redirects, SEO redirect changes, or hijacked URLs.
| Field | Type | Default | Description |
|---|---|---|---|
| url | string | Required | Starting URL to follow redirects from |
| max_redirects | number | 10 | Maximum hops before reporting too many redirects |
| expected_count | number | Optional expected number of redirect hops. A mismatch marks the check down. | |
| expected_final_url | string | Optional override of the expected destination URL. When set, a final URL that differs marks the check down. | |
| baseline_chain | array | Auto-stored | Stored automatically after first successful check |
| timeout | number | 30000 | Overall check timeout in milliseconds |
Status values
Detect registrar, nameserver, and status flag changes
Monitors WHOIS records for unexpected changes to registrar, nameservers, or domain status flags. Unlike the Domain Expiry monitor (which tracks the expiry date), this monitor alerts on any structural change — catching domain hijacking, accidental transfers, or unauthorised registrar changes.
| Field | Type | Default | Description |
|---|---|---|---|
| domain | string | Required | Domain name to monitor (no https://, no www.) |
| baseline | object | Auto-stored | Registrar, nameservers, and status flags stored after first check |
Status values
Check FTP and FTPS server connectivity and authentication
Checks FTP and FTPS server availability by connecting on the specified port and optionally authenticating. Supports anonymous FTP, authenticated FTP, and FTPS (FTP over TLS).
| Field | Type | Default | Description |
|---|---|---|---|
| host | string | Required | FTP server hostname or IP address |
| port | number | 21 | FTP port (21 = plain, 990 = implicit FTPS) |
| use_ftps | boolean | false | Enable FTPS (FTP over TLS) |
| username | string | anonymous | FTP username — leave blank for anonymous |
| password | string | anonymous@ | FTP password — leave blank for anonymous |
| timeout | number | 10000 | Connection timeout in milliseconds |
Status values
Verify IMAP email receiving server availability
Checks IMAP email server availability and authentication. Complements the existing SMTP monitor — use both to confirm your email stack can send and receive.
| Field | Type | Default | Description |
|---|---|---|---|
| host | string | Required | IMAP server hostname |
| port | number | 993 | 993 = IMAPS (SSL), 143 = plaintext (no STARTTLS upgrade) |
| username | string | Required | Email account username |
| password | string | Required | Email account password |
| use_ssl | boolean | true | Enable SSL/TLS. Defaults to true only on port 993. |
| timeout | number | 10000 | Connection timeout in milliseconds |
Status values
Lightweight POP3 email server banner check
Lightweight check that connects to a POP3 server and verifies the +OK banner. Confirms the server is accepting connections on port 110 (plaintext, the default) or 995 (SSL).
| Field | Type | Default | Description |
|---|---|---|---|
| host | string | Required | POP3 server hostname |
| port | number | 110 | 110 = plaintext (default), 995 = POP3S (SSL) |
| use_ssl | boolean | false | Enable SSL/TLS. Defaults to true only when port 995 is selected. |
| username | string | Optional username. When provided with password, enables USER/PASS authentication after the banner. | |
| password | string | Optional password for USER/PASS authentication. | |
| timeout | number | 10000 | Connection timeout in milliseconds |
Status values
Simulate login flows, checkouts, and API workflows
Simulates a real user workflow by executing a sequence of HTTP requests — login, browse, checkout, API call. Each step can validate the response before proceeding. Alerts if any step fails. This is the most powerful monitor type for catching broken user flows.
| Field | Type | Default | Description |
|---|---|---|---|
| steps | array | Required | Ordered list of HTTP steps to execute |
| use_cookies | boolean | false | Carry cookies between steps (for session-based flows) |
| timeout | number | 10000 | Per-step timeout in milliseconds |
| Field | Description |
|---|---|
| name | Step label shown in results (e.g. "Login", "View Dashboard") |
| url | URL for this step — supports {{variable}} substitution from previous steps |
| method | GET / POST / PUT / DELETE |
| headers | Request headers as JSON object |
| body | Request body (for POST/PUT) — supports {{variable}} substitution |
| assertions | Array of: status_code, body_contains, body_not_contains, json_path_eq, json_path_exists, header_contains |
| extract | Extract values for later steps: [{var: "token", json_path: "$.token"}] |
{{variable}} in URL/headers/body to reference values extracted in earlier steps.Status values
Detect visual changes with pixel-by-pixel comparison
Takes a Puppeteer screenshot of a webpage and compares it pixel-by-pixel against a stored baseline. Alerts when the page changes beyond the configured threshold. Useful for detecting visual regressions, defacements, or unexpected layout changes. No external API needed — runs entirely on your server.
| Field | Type | Default | Description |
|---|---|---|---|
| url | string | Required | URL to screenshot |
| threshold | number | 10 | Percentage change (1–50%) that triggers an alert |
| selector | string | Optional | CSS selector to screenshot a specific element instead of the full page |
| viewport_width | number | 1280 | Browser viewport width in pixels |
| viewport_height | number | 720 | Browser viewport height in pixels |
| full_page | boolean | false | Screenshot the full scrollable page (Business+ plans only, viewport-only on Pro) |
| wait_after_load_ms | number | 1500 | Extra settle time (ms) to wait after page load before capturing |
puppeteer installed on the server (npm install after deploying).Status values
Record and replay real user journeys in a headless browser
Runs a sequence of real browser interactions (navigate, click, type, select, wait, assert) in headless Chrome on a schedule. Use the built-in browser recorder to capture your steps by interacting with your website naturally, or define steps manually. Captures screenshots on failure and at the end of every check for debugging.
| Field | Type | Default | Description |
|---|---|---|---|
| startUrl | string | Required | URL to navigate to first |
| steps | SyntheticStep[] | Required | Array of 1-20 browser action steps (see below) |
| timeout | number | 60000 | Overall check timeout in milliseconds (default 60 000, max 120 000). Multi-step browser flows take real time (an 8-step login flow runs ~25-30s on a healthy box) — set the timeout to roughly 2-3x the flow's healthy runtime so transient load spikes don't cause false "Overall timeout exceeded" incidents |
| viewport.width | number | 1280 | Browser viewport width |
| viewport.height | number | 720 | Browser viewport height |
Step action types:
navigate — go to a URLclick — click an element by CSS selectortype — type text into an input fieldkeypress — press a keyboard key (e.g. Enter) on the focused elementselect — choose an option in a dropdownwait — wait for selector, navigation, or timeoutassert — verify element_exists, element_visible, text_contains, url_equals, title_contains, regex_match, response_time, cookie_exists, element_countscreenshot — capture a screenshot at this pointevaluate — run custom JavaScript in the page contextextract — read text from an element for data extractionStatus values
Embed a live uptime badge in your GitHub README, documentation, or website. Each monitor has its own badge endpoint that returns an SVG image showing the current status and uptime percentage.
The badge URL supports query parameters: ?label=My+Service to customize the label text, and ?style=flat for a flat badge style. The badge updates in real time — no caching needed on your end.
Private workers let you monitor internal services, private APIs, and infrastructure behind firewalls. Install a lightweight worker agent in your network and it will check your internal targets and report results back to Monitorion.
docker run -d --name monitorion-worker \
-e MONITORION_PLATFORM_URL=https://app.monitorion.com \
-e MONITORION_API_KEY=wkr_your_key_here \
--restart unless-stopped \
--cap-add=NET_RAW \
ghcr.io/monitorion/monitorion-worker:latestOpen source (MIT) — the worker is on GitHub with a public image on GHCR and setup guides on Discussions.
Security note: Private workers intentionally bypass SSRF protection so they can reach private IP ranges. Only install workers in trusted networks and restrict the API key carefully.
Migrate your existing monitors from another monitoring service or bulk-create monitors from a spreadsheet. Available on Business plans and above.
Upload a CSV file with columns for the monitor name, URL, type, and check interval. The importer validates each row and shows any errors before creating the monitors.
Download a template CSV from the import page to see the expected format.
Start with the free plan — 15 monitors, no credit card required. Upgrade to Pro for all 26 types.