REST API and webhooks
Use the versioned API for complete project automation and signed webhooks for event delivery.
The public REST API is a versioned automation surface for Pro organizations. API keys belong to the organization, expose their secret once, and should be stored like production credentials. OpenAPI 3.1 describes projects, scans, scores, reports, evidence, alerts, credits, crawl insights, webhooks, and exports.
Webhooks complement polling by delivering signed, versioned events to a public endpoint. Consumers should verify signatures, handle repeated delivery safely, and retain event and delivery identifiers for troubleshooting. Dashboard-internal routes are not part of the public contract and can change without API compatibility guarantees.
Build API automation around explicit states and idempotent behavior. Store the returned scan identifier, poll with reasonable intervals, handle conflict responses when a scan is already active, and read scores only after success. For webhooks, accept that delivery can be repeated or delayed. Consumers should acknowledge quickly and process events in a way that is safe to run more than once.
Authentication
Create a named API key on Pro. The full wrk_ secret is shown once. Store it securely and pass it as a bearer token.
Create separate keys for distinct systems or environments so access can be revoked without interrupting unrelated automation. Never place a bearer secret in client-side code, screenshots, or shared documentation. Store only the visible prefix for identification and rotate immediately if exposure is suspected.
curl https://YOUR_SIGHT_HOST/api/v1/sites \
-H "Authorization: Bearer wrk_your_secret"Resource coverage
The OpenAPI 3.1 document at /api/v1/openapi.json is the machine-readable contract. Dashboard-internal endpoints remain outside the public API.
Treat the versioned routes as the complete supported surface. Validate organization and site identifiers, handle not-found and conflict responses explicitly, and do not depend on fields from dashboard requests. New capabilities should be added through a documented versioned contract.
| Method and path | Purpose | Response |
|---|---|---|
| Projects and scans | Create, read, update, archive, list, start, cancel, and inspect scans. | Project, scan, and score resources |
| Reports and evidence | Manage reports and prompts; read answers, sources, source gaps, domains, URLs, and actions. | Stable evidence identifiers and pagination |
| Alerts and credits | Read alert history, manage lifecycle, rules, and delivery preferences, and inspect balance and the append-only usage ledger. | Durable operational and usage records |
| Crawl insights | Manage connections, ingest normalized or supported raw logs, and query bot activity. | Freshness, retention, connection, and aggregate data |
| Webhooks | Manage endpoints, event subscriptions, secrets, delivery history, and replay. | Versioned events and delivery identifiers |
| Bulk exports | Create, list, inspect, and download CSV or JSONL exports. | Seven-day, organization-scoped artifacts |
curl -X POST https://YOUR_SIGHT_HOST/api/v1/sites/site_123/scans \
-H "Authorization: Bearer wrk_your_secret"API conventions
Collections use cursor pagination. Responses include request and rate-limit headers. Retried mutations should send the same Idempotency-Key and byte-equivalent request.
curl -X POST https://YOUR_SIGHT_HOST/api/v1/exports \
-H "Authorization: Bearer wrk_your_secret" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: weekly-answers-2026-07-26" \
-d '{"resource":"answers","format":"jsonl","site_id":"site_123"}'Signed webhooks
Starter and Pro organizations can create event subscriptions, send a test delivery, inspect or replay attempts, rotate signing secrets, and explicitly disable or re-enable an endpoint.
Verify every signature against the raw request body before parsing or acting on the event. Store event identifiers, acknowledge quickly, and process asynchronously when work is slow. Repeated delivery must not trigger duplicate downstream scans, notifications, or records.
- Endpoint URLs must use HTTPS, contain no credentials or fragments, and resolve only to public addresses.
- The signing secret is shown once when the webhook is created.
- Delivery is at least once. Consumers must deduplicate on the stable event id.
- Retries use a 1 minute, 5 minute, 30 minute, 2 hour, and 12 hour backoff before dead-lettering.
- Twenty consecutive endpoint failures automatically disable the endpoint and dead-letter pending work.
- Secret rotation is immediate. Pending deliveries use only the new secret.
- A replay preserves the event id and exact body but creates a new delivery id.
| Event | When it is sent | Required data |
|---|---|---|
| scan.finished | A project scan reaches a terminal state. | scanId, siteId, hostname, status; successful scans also include overall and categories |
| score.dropped | The overall score crosses the configured drop threshold. | Current and previous scores, threshold, category maps, and top issue |
| issue.new | One or more tests start failing in a completed scan. | Scan identity, testIds, and count |
| webhook.test | A user requests an endpoint test. | message and webhook_id |
{
"id": "evt_...",
"event": "scan.finished",
"api_version": "2026-07-26",
"created_at": 1785067200000,
"data": {
"scanId": "scan_...",
"siteId": "site_...",
"hostname": "example.com",
"status": "succeeded",
"overall": 87,
"categories": { "seo": 91, "geo": 83 },
"delta": 2
}
}Verify every signature
Read the request as raw bytes before parsing JSON. The webreport-signature header contains t and v1. Compute HMAC-SHA256 over t, a period, and the byte-exact body. Reject timestamps more than five minutes from your clock and compare digests in constant time.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifySightWebhook(rawBody, signatureHeader, secret) {
const values = Object.fromEntries(
signatureHeader.split(",").map((part) => part.trim().split("=", 2)),
);
const timestamp = Number(values.t);
if (!Number.isSafeInteger(timestamp)) return false;
if (Math.abs(Date.now() - timestamp) > 5 * 60_000) return false;
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
if (!/^[0-9a-f]{64}$/.test(values.v1 ?? "")) return false;
return timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(values.v1, "hex"));
}webreport-signature: t=1785067200000,v1=<hex-hmac-sha256>
webreport-event: scan.finished
webreport-event-id: evt_...
webreport-delivery-id: whd_...
webreport-api-version: 2026-07-26Manage delivery lifecycle
Authenticated webhook management exposes the event catalog, endpoint lifecycle, delivery inspection, and replay operations. A caller-supplied Idempotency-Key makes a replay request safe to retry.
| Method and path | Purpose |
|---|---|
| GET /api/v1/webhooks/events | Read the canonical envelope and event JSON schemas. |
| POST /api/v1/webhooks/:id/rotate-secret | Immediately replace the signing secret and return it once. |
| POST /api/v1/webhooks/:id/disable | Disable delivery and dead-letter pending work. |
| POST /api/v1/webhooks/:id/enable | Enable delivery and reset the consecutive-failure counter. |
| GET /api/v1/webhooks/:id/deliveries | List recent deliveries, optionally filtered by status. |
| GET /api/v1/webhooks/:id/deliveries/:deliveryId | Inspect the complete envelope and replay policy. |
| POST /api/v1/webhooks/:id/deliveries/:deliveryId/replay | Replay a terminal delivery with a new delivery id. |
curl -X POST \
https://YOUR_SIGHT_HOST/api/v1/webhooks/wh_123/deliveries/whd_123/replay \
-H "Idempotency-Key: incident-recovery-2026-07-26"