RegSentry API v1
A JSON API for the sites you monitor, their scans and findings, deploy-time policy checks and signed webhooks. The MCP account tools use the same service layer.
https://regsentry.com/api/v118 operationsMachine-readable: /api/v1/openapi.json (OpenAPI 3.1). This page is generated from that document. Quickstarts for agents and CI are on /agents.
Authentication
Send an API key on every request:
Authorization: Bearer rs_live_...
Create keys in the owner dashboard under API & agents. A token is shown once; RegSentry stores only its hash. The same key authenticates the MCP server at /mcp. GET /openapi.json and GET /plans need no key.
| Scope | Allows |
|---|---|
read | List and fetch sites, scans, findings, evidence reports and webhooks. |
scan | Add and update sites, start scans and run deploy checks. |
manage | Everything, including removing sites and creating, testing and deleting webhooks. |
Write operations also need a plan with API access (Team or Protect); webhook creation needs a plan with webhooks. On Monitor, keys are read-only.
Errors
Every error has the same shape, sometimes with extra fields such as limit, used or resetsAt:
{ "error": { "code": "plan_required", "message": "Your plan (Monitor) does not include apiAccess. ..." } }
| Status | Codes | Meaning |
|---|---|---|
| 400 | invalid_request invalid_domain invalid_policy invalid_url | The request body or parameters are not valid. |
| 401 | missing_token invalid_token | No key, a malformed key, or an unknown or revoked key. |
| 403 | insufficient_scope plan_required authorization_required | The key lacks a scope, the plan lacks the feature, or a check targets a host that is not yours without authorizationAcknowledged: true. |
| 404 | not_found | The site, scan or webhook is not on this account. |
| 409 | limit no_scan | A plan site limit was reached, a scan is already running, or there is no scan to report on yet. |
| 429 | rate_limited run_limit | Too many requests this minute, or the plan's monthly API runs are used. |
| 5xx | internal scan_failed check_unavailable auth_unavailable | Retry with backoff. check_unavailable (503) means the browser pool is busy. |
Rate limits and API runs
Each key may make 300 requests per minute. Past that the API returns 429 rate_limited; retry after a minute. Separately, scans and deploy checks started through the API, MCP or CI count toward the plan's monthly API runs (UTC month). Scheduled monitoring scans do not count.
| Plan | API runs | Webhooks |
|---|---|---|
| Monitor | None (read-only) | No |
| Team | 100 per month | Yes |
| Protect | Unlimited | Yes |
The public MCP endpoint is limited per client IP to 120 requests per minute, and public runtime inspections to 6 per hour.
Endpoints
Paths are relative to https://regsentry.com. In body lists, * marks a required field. Full schemas are in the OpenAPI document.
Account
Who the key belongs to, its plan, features and usage, plus the public plan ladder.
/api/v1/openapi.jsonno keyThis document
responses: 200
/api/v1/plansno keyPlan ladder, policies and webhook events
responses: 200
/api/v1/meKey, plan, features and usage
responses: 200, 401
Sites
Sites on your account. Each has its own policy, monitoring state and optional alert email.
/api/v1/sitesList monitored sites
responses: 200
/api/v1/sitesAdd a site (scope: scan; plan: apiAccess)
body: domain*, policy, monitoring | responses: 201, 400, 403, 409
/api/v1/sites/{id}Get a site
responses: 200, 404
/api/v1/sites/{id}Update policy, monitoring or alert email
body: policy, monitoring, alertEmail | responses: 200, 403
/api/v1/sites/{id}Remove a site (scope: manage)
responses: 200, 409
Scans
Full scans of your own sites: homepage plus up to four high-signal pages, diffed against the last run. Starting a scan returns 202 with the running scan; pass wait: true to block up to 120 seconds, or poll GET /scans/{id}.
/api/v1/sites/{id}/scansScan history for a site
query: limit | responses: 200
/api/v1/sites/{id}/scansRun a full scan now (scope: scan; counts toward apiRunsPerMonth)
body: wait, policy, consentPhases, trigger | responses: 200, 202, 409, 429
/api/v1/scans/{id}Get one scan (poll until status is complete or failed)
responses: 200, 404
Findings
Recorded findings with observation dates, and the evidence export as JSON, CSV or PDF.
/api/v1/sites/{id}/findingsOpen and resolved findings
query: status | responses: 200
/api/v1/sites/{id}/reportEvidence export (dated observations, limitations)
query: format | responses: 200, 409
Checks
Deploy-time policy checks of any public host you are authorized to inspect. Synchronous, up to about 45 seconds. The response carries exitCode 0 pass, 1 fail or 2 inconclusive.
/api/v1/checksDeploy check: observe consent phases on any public host and evaluate a policy
body: url*, policy, authorizationAcknowledged, trigger | responses: 200, 403, 429, 503
Webhooks
Signed delivery endpoints for scan, finding, consent and check events. See Webhooks.
/api/v1/webhooksList webhook endpoints
responses: 200
/api/v1/webhooksCreate a webhook endpoint (scope: manage; plan: webhooks)
body: url*, events, description | responses: 201, 400
/api/v1/webhooks/{id}Delete a webhook endpoint
responses: 200
/api/v1/webhooks/{id}/testSend a signed test delivery now
responses: 200, 502
Policies
A policy turns an observation into pass, fail or inconclusive. Set one per site (PATCH /sites/{id}) or per call (policy on scans and checks). "Flagged" means the tracker is in RegSentry's alert set.
| Policy | Rule |
|---|---|
strict | No tracker of any kind (consent managers excepted) may send a request before consent or after the visitor rejects, no tool may capture typed input before consent, and a consent control must be findable whenever a flagged tracker fires before consent. Needs a runtime snapshot whose before_consent and after_reject phases were observed. |
standarddefault | No flagged tracker (RegSentry's alert set: session replay, chat widgets, ad pixels, AI APIs, and similar) may send a request before consent or after the visitor rejects, and no tool may capture typed input before consent. Non-flagged analytics and consent managers are reported but do not fail. If runtime observation was attempted, both before-consent and after-reject phases must be observed for a pass. A complete crawl alone can support a limited pass but does not test after reject. Unknown timing of a flagged tracker is inconclusive. |
permissive | Report only. Everything that would fail under standard is listed as advisory, and the result is pass whenever any observation exists. |
Webhooks
Create an endpoint with POST /webhooks (https only, public hosts only). Subscribe to specific events or ["*"]. The response includes a whsec_... secret once; store it. Each delivery is a JSON POST of { id, event, createdAt, data }. Failed deliveries are retried up to 5 times with backoff over roughly 14 hours. POST /webhooks/{id}/test sends a signed test delivery.
Check-event change: inconclusive results now use check.inconclusive instead of check.passed. Existing endpoints subscribed to selected events must be recreated with check.inconclusive to receive those results; wildcard subscriptions receive it automatically. Inspect the result in data.policy.
| Event | When |
|---|---|
scan.completed | A scan of one of your sites finished. Carries findings added, returned and cleared, flagged tools, the policy result and any consent regressions. |
scan.failed | A scan could not complete. Carries the error message. |
finding.new | A tracker finding was recorded on a site for the first time. One event per tool. |
finding.returned | A finding that had cleared was observed again. One event per tool. |
finding.cleared | A previously open finding was not observed on the latest scan. One event per tool. |
consent.regression | A flagged tracker newly fired, or fired more often, before consent or after reject compared with the previous consent snapshot. |
check.failed | A deploy check or CI run failed its policy. |
check.passed | A deploy check or CI run passed its policy. |
check.inconclusive | A deploy check or CI run did not gather enough evidence for a pass or failure. Subscribe explicitly if using a selected event list; wildcard subscriptions receive it automatically. |
Headers
| Header | Value |
|---|---|
X-RegSentry-Event | The event name. |
X-RegSentry-Delivery | Unique delivery id. Use it to drop duplicates. |
X-RegSentry-Timestamp | Unix seconds when this attempt was signed. |
X-RegSentry-Signature | v1= followed by the hex HMAC-SHA256 of {timestamp}.{raw body} keyed with your endpoint secret. |
Verify a delivery (Node)
Compute the HMAC over the timestamp, a period and the raw request body, compare in constant time, and reject stale timestamps. Each retry is signed with a fresh timestamp.
import express from "express";
import crypto from "node:crypto";
const app = express();
const SECRET = process.env.REGSENTRY_WEBHOOK_SECRET; // whsec_..., returned once when the endpoint is created
// Verify against the raw body, before any JSON parsing.
app.post("/hooks/regsentry", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.get("X-RegSentry-Timestamp") || "";
const signature = req.get("X-RegSentry-Signature") || "";
const expected = "v1=" + crypto.createHmac("sha256", SECRET).update(`${timestamp}.${req.body}`).digest("hex");
const valid = signature.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
if (!valid || !fresh) return res.sendStatus(401);
const delivery = JSON.parse(req.body.toString("utf8")); // { id, event, createdAt, data }
// delivery.event === "consent.regression", delivery.data.domain, ...
res.sendStatus(204);
});
Exit codes
The exitCode field of POST /checks reports the result:
| Code | Result | Meaning |
|---|---|---|
0 | pass | The observation met the policy. |
1 | fail | The policy failed. Reasons and per-tracker failures are in the result. |
2 | inconclusive | A required phase could not be observed, for example no reject control was found. |
What results mean. Every response describes technical observations from sampled public pages: which known trackers attempted requests, and when, relative to the consent interaction. It is not legal advice, a compliance certification or proof of liability.