Browser check reference
The full request schema is in the auto-generated API Reference. Cheat sheet below.
Object: BrowserCheck
Section titled “Object: BrowserCheck”| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Display name; validated as a “friendly name.” |
script | string | required | The Playwright script body. Wrapped in an async IIFE; max ~50KB. |
frequency | enum | required | 5m, 10m, 15m, 30m, or 1h. |
timeout_seconds | int | 60 | Max script runtime, 1–300. The actual user-script budget is timeout - 30s. |
check_regions | string[] | ["aws-us-east-1"] | Locations to run from, any of the supported locations. Unset or empty on create uses aws-us-east-1. More than one needs a paid Synthetic plan. |
min_healthy_regions | int | 1 | Required healthy locations for overall status. At least 1, at most the number of check_regions. Capped at the number of locations reporting; see locations. |
rerun_on_failure | bool | null | null | Rerun a failed run once from the same location before counting it. See rerun and confirmation. The dashboard turns it on for new checks. |
confirmation_threshold | int | null | null | Failed runs in a row needed before the check goes failed and alerts, 1 to 10 (400 outside that range). null or 1 alerts on the first failure. |
group_notification_ids | uuid[] | default group | Notification groups; cap of 10. On create, omitting it (or sending null) attaches your account’s default group; [] notifies no one. |
state | enum | active | active or paused. Paused checks don’t run. |
tags | string[] | [] | Free-form labels for filtering and maintenance windows. |
service_id | uuid | null | null | Optional logical service grouping. |
current_status | enum | derived | success or failed. A legacy pending_failure value exists in the enum but nothing sets it. |
not_checked_reason | string | null | derived | Set only while an active check is not being run. quota: the account’s browser check minutes for this period are used up. current_status then keeps its last value. |
Rerun and confirmation
Section titled “Rerun and confirmation”With rerun_on_failure: true, a failed run is held back and the same script runs once more from the same location, usually within a minute. Only the rerun’s result counts, so a one-off blip never alerts. A rerun uses browser check minutes like any run, so a failing check can use up to twice its usual minutes. A rerun is skipped when the check was paused, and a check already failed is not rerun.
confirmation_threshold counts the failures that stand after any rerun: the check goes failed only after that many in a row (per location, judged against min_healthy_regions). Recovery is immediate.
Supported locations
Section titled “Supported locations”Browser checks run from 20 AWS locations in 18 countries and territories:
| Id | Location |
|---|---|
aws-us-east-1 | Virginia (default) |
aws-us-west-2 | Oregon |
aws-ca-central-1 | Montreal |
aws-sa-east-1 | Sao Paulo |
aws-eu-west-1 | Dublin |
aws-eu-west-2 | London |
aws-eu-west-3 | Paris |
aws-eu-central-1 | Frankfurt |
aws-eu-north-1 | Stockholm |
aws-eu-south-1 | Milan |
aws-eu-south-2 | Aragon |
aws-af-south-1 | Cape Town |
aws-ap-south-1 | Mumbai |
aws-ap-northeast-1 | Tokyo |
aws-ap-northeast-2 | Seoul |
aws-ap-northeast-3 | Osaka |
aws-ap-southeast-1 | Singapore |
aws-ap-east-1 | Hong Kong |
aws-ap-southeast-3 | Jakarta |
aws-ap-southeast-2 | Sydney |
The Google Cloud and Microsoft Azure locations do not run browser checks. GET /check-locations is the live list: a location that runs browser checks lists "browser" in its capabilities. See check locations for the response shape.
How check_regions is validated on create and update:
| You send | Result |
|---|---|
Nothing, or [], on create | Accepted. The check runs from the default location, aws-us-east-1. |
| Locations from the table above | Accepted. |
A retired id: aws-us-east-2 or aws-us-west-1 | Accepted and replaced with its replacement location, today aws-us-east-1. |
A location without "browser" in its capabilities | 400 with Invalid check_regions <id>: location does not run browser checks. |
| An id that does not exist | 400 with Invalid check_regions <value>. |
| More than one location without a paid Synthetic plan | 403 with multi_region_requires_paid_plan (“Multi-region checks require a paid synthetic plan”). An uptime plan does not count. |
Each selected location runs the script on every scheduled run and uses its own browser check minutes. See locations for how the results are combined.
The script API
Section titled “The script API”Two globals are injected: page (Playwright Page) and step (your wrapper).
step(name, fn)
Section titled “step(name, fn)”await step('Open homepage', async () => { await page.goto('https://example.com');});nameis the display label in the result UI.fnis anasync () => Promise<void>.- A step that throws fails. Subsequent steps are skipped.
- A screenshot is captured after every step (pass or fail).
page (Playwright Page)
Section titled “page (Playwright Page)”The full Playwright API is available. Anything documented at https://playwright.dev/docs/api/class-page works.
The browser can only reach public addresses. A navigation, redirect or subresource aimed at a private, loopback or link-local address (10.x, 192.168.x, 127.0.0.1, localhost, 169.254.169.254, or a hostname that resolves only to one) is refused. A refused http:// request answers 403; a refused https:// request fails with net::ERR_TUNNEL_CONNECTION_FAILED, and the check’s error names the address and why. Refused subresources are listed in the console errors.
Common helpers:
await page.goto(url, { waitUntil: 'networkidle' });await page.click('text=Sign in');await page.fill('input[name=email]', 'demo@example.com');await page.waitForSelector('h1:has-text("Welcome")', { timeout: 10000 });const text = await page.textContent('h1');const ok = await page.isVisible('.success-banner');const url = page.url();Common assertion patterns
Section titled “Common assertion patterns”There is no separate assertion DSL: an assertion is JavaScript that throws.
// Wait for an elementawait step('Dashboard loaded', async () => { await page.waitForSelector('h1:has-text("Dashboard")', { timeout: 10000 });});
// Assert text contentawait step('Welcome message correct', async () => { const text = await page.textContent('h1'); if (!text?.includes('Welcome')) { throw new Error(`Expected "Welcome", got "${text}"`); }});
// Assert URLawait step('Redirected to dashboard', async () => { if (!page.url().endsWith('/dashboard')) { throw new Error(`Expected dashboard, got ${page.url()}`); }});
// Assert HTTP responseawait step('Submit form', async () => { const [response] = await Promise.all([ page.waitForResponse(/\/api\/login$/), page.click('button[type="submit"]'), ]); if (response.status() !== 200) { throw new Error(`Expected 200, got ${response.status()}`); }});Captured artifacts
Section titled “Captured artifacts”For every result:
| Artifact | Format | API endpoint |
|---|---|---|
| Step results | JSON | GET / |
| Screenshots | Per-step PNGs | GET / |
| HAR file | Full network capture | GET / |
| Video | 1280×720 WebM of the run | same endpoint with artifact_type=video |
| Web vitals | JSON: {lcp_ms, fcp_ms, cls, ttfb_ms} | GET / |
| Console errors | JSON array | embedded in result |
| Trace IDs | Trace IDs of the traceparent headers added to outgoing requests; they resolve only for backends that send traces to Site Qwality | embedded in result |
The artifact URLs are presigned and expire in 1 hour. Results and artifacts are stored in us-east-1, whichever location ran the script.
Endpoints
Section titled “Endpoints”| Method | Path | Purpose |
|---|---|---|
POST | /browser_check | Create. |
GET | /browser_check | List all. |
GET | /browser_check/ | Detail. |
PUT | /browser_check/ | Update (partial body). |
DELETE | /browser_check/ | Delete. |
POST | /browser_check/ | Trigger an immediate run in every location the check selects. The response’s regions lists them. |
GET | /browser_check/ | List recent results. |
GET | /browser_check/ | A presigned URL for one artifact: artifact_type is har, video or screenshot (with screenshot_index). |
GET | /browser_check/ | Aggregated web vitals over time. |
See also
Section titled “See also”- Browser check overview: concept and trade-offs.
- Quickstart: first-script walkthrough.