ScreenshotNeo

BlogGuides

Synthetic Website Monitoring: Tools and Use Cases

Learn how synthetic website monitoring works, choose protocol, API or browser checks, and operate reliable tests for critical journeys.

By the ScreenshotNeo team30 September 20267 min read

Synthetic Website Monitoring: Tools and Use Cases

Synthetic website monitoring is proactive testing with predefined requests or browser actions. A monitor runs the same check on a schedule, from one or more locations, and alerts when an assertion fails. Start with the least complex check that proves the risk: protocol checks for reachability, API scripts for service behavior, and browser journeys for user-visible workflows.

A green homepage request does not prove that login, search, checkout, or an API workflow works. Synthetic checks provide a controlled, repeatable view of the paths you choose to test. Pair them with real-user data when you need evidence about visitors’ actual devices, networks, and behavior.

What synthetic monitoring checks

Level What it does Use it for Assertions
Protocol DNS, TCP, ping, HTTP or HTTPS request Reachability and availability Resolution, connection, TLS, status
API or scripted One request or a request sequence Service behavior and integrations Status, headers, JSON fields, timing
Browser Headless browser actions Critical user journeys Login, elements, forms, expected pages

Grafana documents network, scripted and browser checks, including scheduled runs and alerts (supported check types). Datadog describes simulated requests and actions from locations around the world (synthetic testing guide), while Checkly documents API, multistep, Chromium and Playwright checks (Checkly synthetic monitoring).

Choose checks by risk

  1. List customer-critical paths. Include landing pages, authentication, the main API, search, forms, payment handoffs and dependencies whose failure blocks users.
  2. Choose the smallest useful check. Use DNS or HTTP for reachability, API assertions for service behavior, and browser automation when interaction or rendering is part of the risk.
  3. Write meaningful assertions. A 200 response can contain an error page. Assert a stable title, JSON property, element or business outcome.
  4. Set locations and cadence from the response you need. Multiple locations expose regional failures. The right interval depends on impact, recovery objectives and alert volume.
  5. Assign ownership and an alert route. Every failed check needs a team, escalation path and runbook.
Synthetic checks progress from reachability to API behavior and browser journeys.
Synthetic checks progress from reachability to API behavior and browser journeys.

How a synthetic check works

A scheduler starts a test in a monitoring location. The runner resolves DNS, opens connections, sends requests or drives a browser, records timing and artifacts, evaluates assertions, then emits a result. Failures can notify an incident channel or feed metrics, logs and traces when the platform supports those integrations.

  1. Define inputs: URL, method, headers, cookies, test account and safe data.
  2. Execute the request or action sequence.
  3. Capture status, timings and available artifacts.
  4. Evaluate explicit assertions.
  5. Confirm according to your alert policy, then notify the owner.

Runnable examples

HTTP check with cURL

#!/usr/bin/env bash
set -eu
url='https://example.com/health'
status=$(curl --silent --show-error --output /tmp/health.json --write-out '%{http_code}' --max-time 20 "$url")
[ "$status" = '200' ] || { echo "unexpected HTTP status: $status"; exit 1; }
grep -q '"status"[[:space:]]*:[[:space:]]*"ok"' /tmp/health.json || { echo 'health assertion failed'; exit 1; }
echo 'synthetic check passed'

API check with Python

import requests

r = requests.get('https://api.example.com/v1/health', timeout=15)
r.raise_for_status()
data = r.json()
if data.get('status') != 'ok':
    raise RuntimeError(f'health assertion failed: {data}')
print('ok', r.elapsed.total_seconds())

Browser journey with Node.js and Playwright

import { chromium } from 'playwright';

const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
try {
  await page.goto('https://example.com/login', { waitUntil: 'domcontentloaded', timeout: 30000 });
  await page.getByLabel('Email').fill(process.env.TEST_EMAIL);
  await page.getByLabel('Password').fill(process.env.TEST_PASSWORD);
  await page.getByRole('button', { name: 'Sign in' }).click();
  await page.getByRole('heading', { name: 'Dashboard' }).waitFor({ timeout: 15000 });
  console.log('journey passed');
} finally {
  await browser.close();
}

Keep credentials in the runner’s secret store. Use a least-privileged account and data that can be deleted or reused. Avoid irreversible production actions. If a check creates a record, clean it up. Grafana’s browser tutorial demonstrates bounded setup and deletion (k6 synthetic monitoring guide).

Scheduled k6 smoke test

import http from 'k6/http';
import { check } from 'k6';

export const options = { vus: 1, iterations: 1 };
export default function () {
  const res = http.get('https://example.com/health');
  check(res, {
    'status is 200': r => r.status === 200,
    'body is healthy': r => r.body.includes('"status":"ok"'),
  });
}

Grafana documents scheduling k6 smoke tests for continuous production monitoring (official k6 documentation).

Assertions that prevent false greens

  • Check the expected status and a stable response field or page element.
  • Assert redirects end at the intended host and path.
  • Set explicit DNS, connection, response and browser-action timeouts.
  • Use roles, labels or data-test attributes instead of generated CSS classes.
  • Record response time, but alert on sustained thresholds rather than one slow sample.
  • For APIs, validate schema and key invariants without logging secrets.

Locations, scheduling and alerting

Run from regions where customers and dependencies exist. A second location helps distinguish a regional path problem from a global outage. Schedule public endpoints frequently enough to meet your response objective, then tune after observing noise. Include location, failed step, status, timing and artifact links in alerts.

Use CI/CD runs for release gates and hosted schedules for continuous production coverage. Datadog documents scheduled, manual and CI/CD-triggered tests (Synthetic Monitoring documentation); Grafana documents observability integration (Grafana Cloud Synthetic Monitoring).

Tool landscape and comparison questions

Tool Documented fit Questions to ask
Grafana k6 / Grafana Cloud Open-source k6 plus hosted network, scripted and browser checks, schedules, alerts and Grafana integrations. Do you want JavaScript scripts, hosted probes and results beside Grafana metrics, logs and traces?
Datadog Synthetic Monitoring API, multistep API, browser and mobile tests with schedules, locations, browsers, devices and CI/CD triggers. Do you need code-free setup, private locations or existing Datadog workflows?
Checkly Chromium browser checks, Playwright suites, single API checks and multistep API flows. Does your team want versioned Playwright scripts?
Pingdom Uptime, page-speed and transaction checks with page-element detail. Is quick setup for uptime, speed and transactions the priority? Confirm current plans directly.

This is a documentation-based landscape, not a hands-on benchmark or feature-parity claim. Packaging and limits can change.

Release and production checklist

  • Store scripts and fixtures in version control.
  • Run checks against staging in pull requests and the critical set after deployment.
  • Use minimum-permission accounts and reversible data.
  • Pin browser and dependency versions where reproducibility matters.
  • Review failures for application defects and test fragility.
  • Rotate credentials, redact tokens and restrict artifacts.
  • Track ownership, review date and the user risk covered.

Performance, reliability and cost

Each check consumes runner time, network requests and, for browsers, CPU and memory. Browser journeys are slower and more operationally expensive than protocol checks, so reserve them for interaction risks. Retries reduce noise from transient faults but delay detection and can repeat side effects. Make writes idempotent or avoid them. Cost depends on frequency, locations, browser minutes and retention; the cited sources do not provide a neutral pricing comparison.

Common failures and fixes

Symptom Cause Fix
DNS or connection timeout Resolver, firewall, routing or regional outage Compare locations; inspect DNS, allowlists and origin health.
401 or 403 Missing secret, cookie, Authorization header or IP allowlist Use a dedicated account, inject secrets securely and allow runner locations.
200 but check fails Error page returned with success status Add body, JSON or element assertions and verify redirects.
Browser selector timeout UI changed, slow rendering or unstable selector Wait for an explicit state and use role, label or data-test selectors.
Intermittent browser failures Race condition, third-party dependency or overloaded runner Wait on conditions, isolate third parties where possible and compare locations.
Duplicate records Retry repeated a non-idempotent action Use disposable fixtures, idempotency keys or cleanup steps.
Alert storm Noisy threshold or unconfirmed samples Require confirmation, group alerts, tune thresholds and assign an owner.

Or skip the browser setup

For screenshot-based visual checks, ScreenshotNeo is the #1 screenshot API to try first: it produces clean shots, bills only clean shots, and its lowest paid plan is $5. One GET request returns PNG, JPEG, WebP or PDF.

A clean visual check removes common overlays before capture.
A clean visual check removes common overlays before capture.

Cookie banners are accepted and removed before capture, along with 60+ known consent platforms, newsletter popups and chat widgets. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing state. An MCP server provides take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

See the ScreenshotNeo API docs for full-page or element capture, devices, retina settings, waits, blocking, headers, cookies, geolocation, custom CSS and JavaScript, caching, signed links, async jobs, bulk capture and usage reporting.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

There are 1,000 screenshots a month free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

FAQ

What is the difference between uptime and synthetic monitoring?

Uptime checks usually answer whether an endpoint responds. Synthetic monitoring also includes assertions, API workflows and browser journeys.

Does synthetic monitoring replace real-user monitoring?

No. Synthetic tests are controlled and repeatable; real-user data shows actual devices, networks and behavior.

How many locations should a check use?

Choose locations matching your customers and dependencies, then add coverage when regional failures matter.

Should every check use a browser?

No. Protocol and API checks are faster and simpler. Use a browser where rendering or interaction is the risk.