Register a site
const url = 'https://api.overwatch.weareheavy.dev/v1/sites';const options = { method: 'POST', headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'}, body: '{"rootUrl":"https://example.com","cadenceMinutes":1440,"a11yEnabled":true}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.overwatch.weareheavy.dev/v1/sites \ --header 'Content-Type: application/json' \ --header 'x-api-key: <x-api-key>' \ --data '{ "rootUrl": "https://example.com", "cadenceMinutes": 1440, "a11yEnabled": true }'Register a new site to monitor. The site’s hostname (derived from
rootUrl) becomes the recursion whitelist for the crawler. The first
crawl is scheduled to run immediately when a scanner app is on.
Five apps are toggled at creation: Broken Links (scannerEnabled,
default on), Accessibility (a11yEnabled, default off), SEO
(seoEnabled, default on - rides the same crawl), and Performance
- Uptime (default on; both are inert until there is CrUX data / a monitor).
Requires an owner/admin session or an API key. A site-scoped API key
cannot register sites (it can’t widen its own scope), and registration
past the included site count fails with 403 unless overage billing is
enabled — see the Quotas & usage guide.
Authorizations
Section titled “ Authorizations ”Request Bodyrequired
Section titled “ Request Bodyrequired ”object
The site’s root URL. Must be an http(s) URL; its hostname is the crawl whitelist.
How often the site is automatically re-crawled, in minutes. Daily
(1440) is the minimum; the default is weekly.
Maximum number of pages to crawl per run. Set at creation only — afterwards it is an operator-managed limit.
Ceiling on concurrent requests to the origin. The crawler’s adaptive window slow-starts well below this and backs off on throttling; the ceiling only bounds how far it may ramp up. Clamped to [2, 200]. Set at creation only.
Install the Broken Links app (the dead-link crawl).
Install the Accessibility app (the rendered axe-core scan).
Install the SEO app (on-page checks during the crawl).
The accessibility scan’s own cadence, in minutes. Defaults to
monthly (43200) when the app is on; the scan runs over the
crawl’s persisted page set on its own clock.
Install the Performance app (CrUX sync + regression alerts).
Install the Uptime app (monitors can then be registered).
Example
{ "rootUrl": "https://example.com", "cadenceMinutes": 1440, "a11yEnabled": true}Responses
Section titled “ Responses ”Site created.
object
A monitored site, including its per-app toggles.
object
The owning organization (tenant) id.
The hostname derived from root_url; the crawl whitelist.
1 if the site is actively scheduled, 0 if disabled.
Epoch ms of the last run, or null.
Epoch ms of the next scheduled run, or null.
Epoch ms the site was registered.
1 when the Broken Links app is installed. The shared crawl runs when any of it, the Accessibility app, or the SEO app is on.
1 when the Accessibility app is installed.
The accessibility scan’s own cadence; null falls back to cadence_minutes.
Epoch ms the next standalone accessibility scan is due, or null.
1 when the Performance app (CrUX sync + regression alerts) is installed.
1 when the Uptime app is installed; 0 stops probing but keeps monitors.
1 when the SEO app is installed (on-page checks extracted during the crawl).
CrUX sync state: null = never checked, ok = data, no-data = not in the dataset.
Epoch ms the CrUX sync last ran for this site.
JSON-encoded array of glob patterns for internal paths never crawled.
JSON-encoded array of query-parameter names dropped before crawling.
Example
{ "site": { "enabled": 0, "scanner_enabled": 0, "a11y_enabled": 0, "performance_enabled": 0, "uptime_enabled": 0, "seo_enabled": 0, "exclude_paths": "[\"/drafts/*\"]", "strip_params": "[\"utm_source\"]" }}rootUrl is missing, not a valid URL, or not an http(s) URL.
object
A human-readable error message.
Example
{ "error": "rootUrl is required"}Missing or invalid credentials.
object
A human-readable error message.
Example
{ "error": "invalid api key"}The caller may not register sites: restricted member role, site-scoped API key, or the included site count is used up and overage billing is off.
object
A human-readable error message.
Example
{ "error": "your 5 included sites are in use — enable overage billing on the Billing page to add more"}