Browser (synthetic) monitors.
A browser monitor loads your URL in real headless Chromium,
executes the page's JavaScript, and evaluates the fully rendered
page. An http or keyword check sees only
the raw HTTP response; a browser check sees what a user's browser
actually paints. Use it for single-page apps, JavaScript-gated content,
and "does the page actually render" checks where a 200 on the raw HTML
tells you nothing.
TL;DR
A browser monitor loads your URL in real headless Chromium,
executes the page's JavaScript, and evaluates the fully rendered
page. An http or keyword check sees only
the raw...
Browser (synthetic) monitors.
A browser monitor loads your URL in real headless Chromium,
executes the page's JavaScript, and evaluates the fully rendered
page. An http or keyword check sees only
the raw HTTP response; a browser check sees what a user's browser
actually paints. Use it for single-page apps, JavaScript-gated content,
and "does the page actually render" checks where a 200 on the raw HTML
tells you nothing.
When to reach for it
- Single-page apps — React / Vue / Svelte shells that ship an
empty
<div id="root">and hydrate client-side. The raw response is a skeleton; the rendered page is the product. - JavaScript-gated content — anything that only appears after the bundle loads, fetches, and renders.
- "Does it actually render" checks — assert on text that only exists post-hydration, so a broken bundle or a failed XHR flips the monitor even when the server returns 200.
Create one — API
A browser monitor is created like any other: POST /api/v1/monitors
with type: "browser". Use a PAT with the
monitors:write scope.
curl -X POST https://api.24observe.com/api/v1/monitors \
-H 'Authorization: Bearer obs_<token>' \
-H "Idempotency-Key: $(uuidgen)" \
-H 'Content-Type: application/json' \
-d '{
"name": "app.example dashboard renders",
"url": "https://app.example.com/dashboard",
"type": "browser",
"intervalSec": 300,
"timeoutMs": 30000,
"expectedStatusCode": 200,
"keyword": "Welcome back",
"keywordMatchType": "contains",
"degradedResponseTimeMs": 4000,
"alertEmail": "alerts@yourco.com"
}'
The keyword above is matched against the
rendered DOM (post-JavaScript), so "Welcome back"
can be text the app only paints once it has hydrated and fetched the
user's session — not something present in the initial HTML.
Create one — dashboard
Open login.24observe.com, click New monitor, and pick "Browser (headless Chromium — renders JS)" from the type dropdown. Fill in the URL, interval, timeout, and any keyword assertion exactly as above.
Fields it honors
url(required) — the fullhttpsURL to load.intervalSec— how often the check runs. The free plan's minimum interval is300s.timeoutMs— how long the load may take before it counts as down (e.g.30000).expectedStatusCode(optional) — assert the document response status.keyword+keywordMatchType(optional) —"contains"or"not_contains", matched against the rendered DOM after JavaScript has run.degradedResponseTimeMs(optional) — render time above this marks a slow-but-up page asdegradedinstead ofup.
Result semantics
up— the page loaded (status< 400) and any keyword assertion passed.degraded— the page loaded, but render time exceededdegradedResponseTimeMs.down— a4xx/5xx, a failed keyword assertion, or a load timeout.
Reported response time is the time to the load event — the
same number you'll see in the dashboard charts and SLO calculations.
Isolation
Browser checks run on a dedicated browser execution pool, kept
separate from the standard check pipeline. Rendering a page is heavier
than a plain HTTP request, so isolating it means a slow or stuck browser
check never delays your http, ping, or
keyword monitors.
Security
Every request the page makes — the initial navigation, every redirect, and every sub-resource it pulls — is checked against an SSRF guard. A browser monitor cannot be pointed at private, loopback, or cloud-metadata addresses, and a page can't be used to reach them indirectly through a redirect or an embedded resource. The same defense that protects alert and webhook targets applies to what the browser is allowed to load.
Alerting, incidents, and status pages
A browser monitor behaves like every other monitor type once it's
running. Configured alert channels (email / webhook / Slack / Discord /
Teams / Telegram / PagerDuty / Opsgenie) fire on the same
alertThreshold rules, incidents open and auto-resolve the
same way, and the monitor can be added to a public status page like any
other. Nothing about the result handling is special — only the check
itself renders the page.
Other resources
- API reference — PATs, scopes, the full monitor request body, and error codes.
- Heartbeat / cron-job monitors — the inverted check pattern.
- Interactive OpenAPI reference — every endpoint and schema in one searchable page.