Référence de l'API
Accès programmatique aux données de posture, d'utilisation et de conformité de votre organisation via une API JSON.
Programmatic API access is included on the Business and Enterprise plans.
Voir les forfaitsAuthentication
Most endpoints authenticate either with an API key (for scripts, CI/CD and SIEM) or with your signed-in browser session. Create a key in Settings → API Keys and send it as an HTTP Bearer token: `Authorization: Bearer 8200_ak_…`. Endpoints marked “Session” are reachable only from a signed-in browser; “Partner” endpoints require a partner account.
- API key — send `Authorization: Bearer <key>`. Keys look like `8200_ak_` followed by 40 hex characters, so they are easy to spot in secret scanners. The request is treated as the key’s organization and the role of the user who created it.
- The full key is shown only once, at creation. We store only its SHA-256 hash and a short display prefix — we can never show or recover the key again. If a key is lost, revoke it and create a new one.
- Creating keys is OWNER-only; ADMINs can list them; revoking is OWNER-only. Listing never exposes the full key or hash, only the prefix.
- Session — signed-in browser requests on the same origin send the session cookie automatically. Org-scoped endpoints require a member role; unauthenticated calls return 401.
- API access (and creating keys) is included on the Business and Enterprise plans. On lower tiers the endpoints still authenticate, but key creation and programmatic use return 402 with an upgrade hint.
- Store keys in a secret manager (never in source control), give each integration its own named key, set an expiry where you can, and revoke immediately if a key is exposed.
Base URL
All endpoints are relative to the base URL. Every response is JSON unless noted as a download.
https://8200.dev/apiRate limits
A global rate limit protects the API. Limits are per IP and per minute; exceeding one returns 429 Too Many Requests with a Retry-After header.
| Signed-in / API-key requests | 60 / minute |
| Anonymous requests | 20 / minute |
| Credential sign-in attempts | 10 / minute |
| Manual scans (POST /sync) | Per-plan daily ceiling |
| GET /api/health | Exempt (never limited) |
Pagination
List endpoints paginate in one of two ways. Page-based endpoints (e.g. GET /api/audit) take `page` and `limit` and return `page`, `limit`, `total`, `totalPages`. Cursor-based endpoints (e.g. GET /api/timeline) take `limit` and an opaque `before` cursor and return `nextCursor` (null at the end).
Errors
All responses are JSON. Errors return `{ "error": "<code>" }` with an appropriate HTTP status.
| 400 | Invalid input (failed validation). |
| 401 | Unauthenticated, or no access to the organization. |
| 402 | Your plan does not include this capability — upgrade. |
| 403 | Authenticated but not permitted (role too low). |
| 404 | Resource not found (or not in your organization). |
| 429 | Rate limited — retry after the Retry-After header. |
Versioning
The API is currently v1 and unversioned in the path (the base is https://8200.dev/api). We add fields and endpoints without notice; we treat removing a field or endpoint, or changing a response type, as a breaking change and will announce it in the changelog with advance notice. Pin to the fields you use and ignore unknown fields.
Health
Liveness and dependency health. Public and unauthenticated.
/api/healthPublicLiveness + database health check. Public, never rate-limited.
Request
curl https://8200.dev/api/healthResponse
200 with the service status and per-dependency checks. Returns a non-ok status when a dependency is unhealthy.
{
"status": "ok",
"time": "2026-06-27T12:00:00.000Z",
"checks": {
"app": "ok",
"db": "ok"
}
}Posture
Your organization’s plan, connected sources, score and trend.
/api/usageAPI keyCurrent plan, usage against limits, and unlocked features.
Request
curl https://8200.dev/api/usage \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
Plan id, grace window, source and scan usage, and the capability flags. `max: null` means unlimited.
{
"plan": "business",
"inGrace": false,
"graceEndsAt": null,
"sources": {
"used": 3,
"max": 25
},
"scans": {
"usedToday": 4,
"maxPerDay": 100
},
"features": {
"apiAccess": true,
"flowGuard": true,
"agentGuard": true,
"ueba": true
}
}/api/connectorsAPI keyList the connected sources with their status and health.
Request
curl https://8200.dev/api/connectors \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of connectors with status, health and counts.
{
"connectors": [
{
"id": "cmqmqnq8s000bs4",
"type": "google_workspace",
"displayName": "Acme Workspace",
"mode": "real",
"status": "CONNECTED",
"healthStatus": "healthy",
"resourceCount": 42,
"findingCount": 22
}
]
}/api/posture/historySessionThe posture-score trend over time (one datapoint per completed scan).
Request
curl https://8200.dev/api/posture/history \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
An array of { score, at } datapoints, oldest first.
{
"history": [
{
"score": 61,
"at": "2026-06-20T08:00:00.000Z"
},
{
"score": 68,
"at": "2026-06-27T08:00:00.000Z"
}
]
}/api/posture/breakdownSessionThe posture score decomposed by category and rule, with the biggest improvements.
Request
curl https://8200.dev/api/posture/breakdown \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
The score, grade, per-category deductions, top improvements and quick wins.
{
"score": 68,
"grade": "C",
"categories": [
{
"category": "public_exposure",
"deductionPoints": 18,
"findingCount": 6
}
],
"topImprovements": [
{
"findingId": "f_abc",
"scoreDelta": 9
}
]
}Findings
The current posture findings for your organization.
/api/findingsAPI keyList the current findings (most severe first).
Request
curl https://8200.dev/api/findings \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of findings with severity, title, resource and status.
{
"findings": [
{
"id": "f_abc123",
"severity": "CRITICAL",
"title": "Public link: FY26 Budget",
"resourceName": "FY26 Budget",
"connectorType": "google_workspace",
"status": "OPEN",
"detectedAt": "2026-06-27T08:00:00.000Z"
}
]
}/api/findings/{id}/ticketAPI keybusiness+Create a tracker ticket (Jira/Linear/GitHub/Asana) for a finding. Requires a configured ticketing integration.
Parameters
id(path, required) — The finding id.
Request
curl -X POST https://8200.dev/api/findings/k1/ticket \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
The created ticket link. 402 without the ticketing entitlement; 409 if a ticket already exists.
{
"ticket": {
"provider": "jira",
"externalId": "SEC-142",
"url": "https://acme.atlassian.net/browse/SEC-142",
"status": "open"
}
}Scans
Trigger and inspect scans of a connected source.
/api/connectors/{id}SessionDisconnect a source — removes the connector and its findings. ADMIN+.
Parameters
id(path, required) — The connector id.
Request
curl -X DELETE https://8200.dev/api/connectors/k1 \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
Confirmation that the connector (and its findings) was removed.
{
"disconnected": true
}/api/connectors/{id}/syncSessionTrigger a scan of a connected source. Rate-limited per plan (the manual-scan ceiling).
Parameters
id(path, required) — The connector id.
Request
curl -X POST https://8200.dev/api/connectors/k1/sync \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
The scan result summary. 429 over the daily manual-scan limit for your plan.
{
"scanId": "s_100",
"status": "COMPLETE",
"resources": 42,
"findingsNew": 1,
"findingsResolved": 0,
"postureScore": 69
}Inventory
The positive “what do I have” view — users, files and Shared Drives.
/api/inventorySessionSearchable, paginated asset inventory (users / files / shared-drives).
Parameters
type(query, optional) — 'users' | 'files' | 'shared-drives' (default 'users').search(query, optional) — Filter by name/email/owner.limit(query, optional) — Page size (default 50, max 200).offset(query, optional) — Page offset.
Request
curl https://8200.dev/api/inventory \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
A paginated page of asset rows plus inventory metrics. ADMIN+.
{
"type": "shared-drives",
"rows": [
{
"id": "d1",
"name": "Finance",
"memberCount": 4,
"externalMemberCount": 1,
"restrictionStatus": "open",
"filesCount": 120,
"securityStatus": "critical"
}
],
"total": 5,
"limit": 50,
"offset": 0
}Flow Guard
The external data-flow graph (who shares what with whom outside your org).
/api/flow-guard/graphSessionbusiness+The data-flow graph: nodes (users / external domains / files / public links / shared drives) and exposure edges. ADMIN+.
Parameters
limit(query, optional) — Max nodes (default 200, max 500).offset(query, optional) — Node offset for pagination.
Request
curl https://8200.dev/api/flow-guard/graph \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
A graph { nodes, edges, summary } plus pagination metadata.
{
"nodes": [
{
"id": "user:U1",
"type": "user",
"label": "[email protected]",
"riskScore": 70
},
{
"id": "external:vendor.io",
"type": "external",
"label": "vendor.io"
}
],
"edges": [
{
"id": "e1",
"source": "file:R1",
"target": "external:vendor.io",
"scope": "external",
"severity": "HIGH"
}
],
"summary": {
"externalFiles": 12,
"publicLinks": 3,
"sharedDrivesExposed": 1,
"riskScore": 41
}
}Agent Guard
AI-agent and service-account inventory and risk matrix.
/api/agent-guard/inventorySessionteam+Every detected AI agent / service account with its risk band and reach. ADMIN+.
Request
curl https://8200.dev/api/agent-guard/inventory \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
Agent cards plus governance metrics.
{
"agents": [
{
"id": "a1",
"label": "[email protected]",
"kind": "ai_agent",
"riskBand": "high",
"resourceCount": 18,
"isKnownPublisher": false
}
],
"metrics": {
"total": 4,
"unvettedBroad": 1
}
}/api/agent-guard/risk-matrixSessionteam+Agents projected onto a scope-breadth × publisher-trust risk matrix. ADMIN+.
Request
curl https://8200.dev/api/agent-guard/risk-matrix \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
Matrix points and per-quadrant counts.
{
"points": [
{
"id": "a1",
"label": "jarvis-agent",
"quadrant": "unknown_broad",
"riskScore": 82
}
],
"quadrantCounts": {
"trusted_limited": 2,
"unknown_broad": 1
}
}/api/agent-guard/timeline/{agentId}Sessionteam+Recent activity for one agent (honest: live usage telemetry requires the Reports scope). ADMIN+.
Parameters
agentId(path, required) — The detected-agent id.
Request
curl https://8200.dev/api/agent-guard/timeline/a1 \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
The agent’s timeline; activityAvailable=false when telemetry is not in scope.
{
"agentId": "a1",
"activityAvailable": false,
"events": []
}Timeline
One chronological feed of findings, scans, audit events and OAuth grants.
/api/timelineAPI keyThe unified security timeline, newest first, cursor-paginated.
Parameters
limit(query, optional) — Page size (default 50, max 100).before(query, optional) — ISO cursor — return events older than this.significant(query, optional) — 'true' to return only significant events.
Request
curl https://8200.dev/api/timeline \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of timeline events plus the next cursor.
{
"items": [
{
"id": "t1",
"kind": "finding",
"severity": "CRITICAL",
"title": "Public link: FY26 Budget",
"at": "2026-06-27T08:00:00.000Z"
}
],
"nextCursor": "2026-06-27T07:00:00.000Z"
}Incidents
Security incident records and their response lifecycle.
/api/incidentsAPI keybusiness+List incidents (Open → Investigating → Contained → Resolved → Closed).
Parameters
status(query, optional) — Filter by status.priority(query, optional) — Filter by priority P1–P4.
Request
curl https://8200.dev/api/incidents \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of incident summaries.
{
"incidents": [
{
"id": "inc_1",
"title": "Exposed credentials in Drive",
"status": "INVESTIGATING",
"priority": "P2",
"assignee": "[email protected]",
"openedAt": "2026-06-26T10:00:00.000Z"
}
]
}/api/incidents/{id}API keybusiness+One incident with its investigation log, linked findings and post-mortem.
Parameters
id(path, required) — The incident id.
Request
curl https://8200.dev/api/incidents/k1 \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
The full incident record.
{
"id": "inc_1",
"title": "Exposed credentials in Drive",
"status": "INVESTIGATING",
"priority": "P2",
"linkedFindings": [
"f_abc123"
],
"log": [
{
"at": "2026-06-26T10:05:00.000Z",
"note": "Scoped blast radius"
}
]
}/api/incidents/suggestionsAPI keybusiness+Findings clustered into suggested incidents (never auto-created).
Request
curl https://8200.dev/api/incidents/suggestions \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of suggested incident groupings.
{
"suggestions": [
{
"theme": "Public exposure spike",
"findingIds": [
"f_abc123",
"f_def456",
"f_ghi789"
],
"severity": "CRITICAL"
}
]
}/api/incidents/{id}/exportAPI keybusiness+Download the incident response report as a PDF (SOC 2 CC7.3 / ISO A.16 evidence).
Parameters
id(path, required) — The incident id.
Request
curl -L https://8200.dev/api/incidents/k1/export \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY" \
-o download.pdfResponse
application/pdf attachment.
Behavior analytics (UEBA)
Per-user behavioral baselines and detected anomalies.
/api/behavior/anomaliesAPI keybusiness+Detected behavioral anomalies (sharing spike, bulk access, dormant reactivation, OAuth burst…).
Request
curl https://8200.dev/api/behavior/anomalies \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of anomalies with type, severity and confidence.
{
"anomalies": [
{
"id": "an1",
"principal": "[email protected]",
"type": "sharing_spike",
"severity": "HIGH",
"confidence": 0.82,
"at": "2026-06-27T03:00:00.000Z"
}
]
}/api/behavior/heatmapAPI keybusiness+Per-user behavioral activity heatmap over the analysis window.
Request
curl https://8200.dev/api/behavior/heatmap \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
A matrix of users × periods with activity intensity.
{
"users": [
"[email protected]",
"[email protected]"
],
"periods": [
"2026-W25",
"2026-W26"
],
"cells": [
[
2,
5
],
[
0,
9
]
]
}/api/behavior/baseline/{userId}API keybusiness+One user’s learned behavioral baseline (the “normal” the engine compares against).
Parameters
userId(path, required) — The principal id.
Request
curl https://8200.dev/api/behavior/baseline/p_bob \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
The user’s baseline metrics and the periods learned from.
{
"userId": "p_bob",
"periodsLearned": 4,
"baseline": {
"externalShareCount": 1.5,
"resourceAccessCount": 40,
"oauthGrantCount": 0
}
}Security awareness
Per-user security-awareness scores.
/api/awareness/scoresAPI keybusiness+The per-user security-awareness leaderboard. ADMIN+.
Request
curl https://8200.dev/api/awareness/scores \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of users with score, rank and badges.
{
"scores": [
{
"userId": "p_alice",
"email": "[email protected]",
"score": 92,
"rank": 1,
"badges": [
"clean_sharer",
"mfa_on"
]
}
]
}/api/awareness/meAPI keyThe calling user’s own awareness score, factors and nudges.
Request
curl https://8200.dev/api/awareness/me \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
The caller’s score, contributing factors and recommended actions.
{
"score": 92,
"rank": 1,
"factors": [
{
"key": "mfa_on",
"delta": 10
}
],
"nudges": [
"Review 2 stale external shares"
]
}Audit log
The organization’s append-only security audit trail.
/api/auditAPI keyWho did what, and when. Reverse-chronological, paginated. OWNER/ADMIN only.
Parameters
page(query, optional) — Page number (default 1).limit(query, optional) — Entries per page (default 50, max 100).action(query, optional) — Filter by action, e.g. SCAN_TRIGGERED.
Request
curl https://8200.dev/api/audit \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
A paginated page of audit entries.
{
"entries": [
{
"id": "au1",
"action": "CONNECTOR_CONNECTED",
"target": "cmqmqnq8s000bs4",
"userEmail": "[email protected]",
"createdAt": "2026-06-27T08:00:00.000Z"
}
],
"page": 1,
"limit": 50,
"total": 137,
"totalPages": 3
}Compliance
Multi-framework compliance reporting and audit evidence.
/api/compliance/reportsAPI keyGenerate an access-control evidence report (SOC 2 / ISO 27001 / GDPR oriented).
Parameters
period(body, optional) — Look-back window in days (e.g. 30, 90).
Request
curl -X POST https://8200.dev/api/compliance/reports \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{"period":30}'Response
A run id and the structured report.
{
"runId": "rr_1",
"report": {
"framework": "soc2",
"satisfied": 9,
"partial": 2,
"gap": 1,
"controls": [
{
"id": "CC6.6",
"status": "PARTIAL"
}
]
}
}/api/compliance/dashboardAPI keybusiness+The multi-framework posture (SOC 2 / ISO 27001 / GDPR / HIPAA / NIST CSF) with cross-framework gaps.
Request
curl https://8200.dev/api/compliance/dashboard \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
Per-framework status percentages and a cross-framework gap matrix.
{
"frameworks": [
{
"id": "soc2",
"satisfiedPct": 75,
"partial": 2,
"gap": 1
},
{
"id": "iso27001",
"satisfiedPct": 70
}
],
"crossGaps": [
{
"theme": "External sharing",
"frameworks": [
"soc2",
"iso27001",
"gdpr"
]
}
]
}/api/compliance/gap-reportAPI keybusiness+Download the cross-framework gap-analysis report as a PDF.
Request
curl -L https://8200.dev/api/compliance/gap-report \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY" \
-o download.pdfResponse
application/pdf attachment.
/api/compliance/evidence/generateAPI keybusiness+Kick off an audit-ready evidence ZIP package (async). Returns a job id to poll.
Parameters
framework(body, required) — 'soc2' | 'iso27001' | 'gdpr'.
Request
curl -X POST https://8200.dev/api/compliance/evidence/generate \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{"framework":"soc2"}'Response
202 Accepted with a job id. Poll GET /api/compliance/evidence/{jobId} for the download.
{
"jobId": "ej_1",
"status": "PENDING"
}/api/compliance/evidence/{jobId}API keybusiness+Poll an evidence job; when READY the body is the ZIP download.
Parameters
jobId(path, required) — The evidence job id.
Request
curl https://8200.dev/api/compliance/evidence/ej_1 \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
While PENDING: JSON status. When READY: application/zip attachment.
{
"jobId": "ej_1",
"status": "READY",
"fileCount": 41,
"controlCount": 18,
"sizeBytes": 284512
}/api/reports/complianceSessionbusiness+Download a period-windowed Security Posture Report PDF. Admin + complianceExport (Starter+). Rate-limited 5/hour.
Parameters
period(query, optional) — Look-back window in days: 30 (default), 60, 90.
Request
curl -L https://8200.dev/api/reports/compliance \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE" \
-o download.pdfResponse
application/pdf attachment.
Partner API
MSP/MSSP portfolio reporting across managed organizations. Requires a partner account.
/api/partner/settingsPartnerenterprise+Update partner account settings — name, report cadence, unhealthy-client alerts, and (white-label tier) logo + accent colour.
Parameters
name(body, optional) — Partner display name.reportSchedule(body, optional) — Report cadence: 'NONE' | 'WEEKLY' | 'MONTHLY'.notifyUnhealthy(body, optional) — Alert when a managed client becomes unhealthy.
Request
curl -X PATCH https://8200.dev/api/partner/settings \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{"name":"CI Pipeline","reportSchedule":"value","notifyUnhealthy":"value"}'Response
The updated partner settings. The managed-org list is read via the portfolio report.
{
"name": "Acme MSP",
"reportSchedule": "WEEKLY",
"notifyUnhealthy": true,
"logoUrl": null,
"accentColor": null
}/api/partner/reports/portfolioPartnerenterprise+A roll-up across every managed organization (posture, findings, at-risk clients).
Request
curl https://8200.dev/api/partner/reports/portfolio \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
Portfolio totals plus a per-client breakdown.
{
"totals": {
"clients": 12,
"openCritical": 7,
"avgScore": 74
},
"clients": [
{
"orgId": "o_1",
"name": "Client A",
"postureScore": 71,
"openCritical": 2
}
]
}/api/partner/reports/client/{orgId}Partnerenterprise+A detailed report for one managed organization.
Parameters
orgId(path, required) — The managed organization id.
Request
curl https://8200.dev/api/partner/reports/client/o_1 \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
The client’s posture, findings breakdown and trend.
{
"orgId": "o_1",
"name": "Client A",
"postureScore": 71,
"findings": {
"CRITICAL": 2,
"HIGH": 5,
"MEDIUM": 8
},
"trend": [
{
"score": 64,
"at": "2026-06-20"
},
{
"score": 71,
"at": "2026-06-27"
}
]
}API keys
Create, list and revoke the API keys that authenticate the Developer API.
/api/keysAPI keybusiness+List your API keys (never the full key or hash — only the prefix). ADMIN+.
Request
curl https://8200.dev/api/keys \
-H "Authorization: Bearer 8200_ak_YOUR_API_KEY"Response
An array of key metadata.
{
"keys": [
{
"id": "k1",
"name": "CI Pipeline",
"keyPrefix": "8200_ak_abc12345",
"createdAt": "2026-06-01T00:00:00.000Z",
"lastUsedAt": "2026-06-27T08:00:00.000Z",
"expiresAt": "2026-09-01T00:00:00.000Z",
"revokedAt": null,
"status": "active"
}
]
}/api/keysSessionbusiness+Create a key. OWNER only. The full key is returned ONCE and never again.
Parameters
name(body, required) — A label, e.g. "CI Pipeline" (1–80 chars).expiresInDays(body, optional) — Optional expiry in days; omit for no expiry.
Request
curl -X POST https://8200.dev/api/keys \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE" \
-H "content-type: application/json" \
-d '{"name":"CI Pipeline","expiresInDays":90}'Response
The new key (shown once) plus its metadata. 402 without apiAccess; 403 for non-OWNER.
{
"key": "8200_ak_abc123def456...shown_once",
"id": "k2",
"name": "CI Pipeline",
"keyPrefix": "8200_ak_abc12345",
"expiresAt": "2026-09-25T00:00:00.000Z",
"createdAt": "2026-06-27T12:00:00.000Z"
}/api/keys/{id}Sessionbusiness+Revoke a key (soft delete, immediate and permanent). OWNER only.
Parameters
id(path, required) — The key id (not the key itself).
Request
curl -X DELETE https://8200.dev/api/keys/k1 \
--cookie "authjs.session-token=YOUR_SESSION_COOKIE"Response
{ revoked: true }. 403 for non-OWNER; 404 if the key is not in your org.
{
"revoked": true
}Webhooks
Subscribe to events in Settings → Integrations. Each delivery POSTs a JSON body and is signed with HMAC-SHA256 over the raw body in the X-8200-Signature header (sha256=<hex>). Always verify the signature before trusting a payload.
scan.completedA scan finished. Carries the run summary and posture score.
{
"event": "scan.completed",
"data": {
"connectorId": "cmqmqnq8s000bs4",
"connectorName": "Acme Workspace",
"score": 68,
"findingsTotal": 22,
"findingsNew": 2,
"link": "https://8200.dev/app"
}
}finding.newA new finding was created on the latest scan.
{
"event": "finding.new",
"data": {
"findingId": "f_abc123",
"severity": "CRITICAL",
"title": "Public link: FY26 Budget",
"resource": "FY26 Budget",
"link": "https://8200.dev/app/findings"
}
}finding.resolvedA finding was resolved (fixed at the source or by an action).
{
"event": "finding.resolved",
"data": {
"findingId": "f_abc123",
"title": "Public link: FY26 Budget",
"link": "https://8200.dev/app/findings"
}
}policy.violationNew findings matched one of your security policies.
{
"event": "policy.violation",
"data": {
"ruleId": "public_writable",
"severity": "CRITICAL",
"count": 3
}
}prevention.triggeredA prevention rule matched a new finding and acted.
{
"event": "prevention.triggered",
"data": {
"ruleId": "pr_1",
"action": "ALERT_ONLY",
"count": 1,
"severity": "HIGH"
}
}alert.groupedA grouped smart alert (one per category per scan).
{
"event": "alert.grouped",
"data": {
"category": "public_exposure",
"severity": "CRITICAL",
"count": 20,
"title": "20 new public exposure findings",
"link": "https://8200.dev/app/alerts"
}
}Verify the signature
Node.js
import crypto from "node:crypto";
// 8200.dev signs each webhook with HMAC-SHA256 over the raw request body.
// The signature arrives in the "X-8200-Signature" header as "sha256=<hex>".
export function verify(rawBody, signatureHeader, secret) {
const expected =
"sha256=" + crypto.createHmac("sha256", secret).update(rawBody, "utf8").digest("hex");
const a = Buffer.from(signatureHeader);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Python
import hmac, hashlib
# 8200.dev signs each webhook with HMAC-SHA256 over the raw request body.
# The signature arrives in the "X-8200-Signature" header as "sha256=<hex>".
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header)SDK snippets
Copy these tiny clients into your project — there is nothing to install beyond your language’s HTTP library. Authenticate with an API key from Settings → API Keys.
TypeScript
// 8200.dev TypeScript client — copy into your project, no dependency.
// Authenticate with an API key created in Settings → API Keys.
export class Client8200 {
constructor(
private readonly apiKey: string,
private readonly baseUrl = "https://8200.dev",
) {}
private async get<T>(path: string): Promise<T> {
const res = await fetch(this.baseUrl + path, {
headers: { Authorization: `Bearer ${this.apiKey}` },
});
if (!res.ok) throw new Error(`8200 API ${res.status}: ${await res.text()}`);
return res.json() as Promise<T>;
}
usage() { return this.get<{ plan: string; features: Record<string, boolean> }>("/api/usage"); }
connectors() { return this.get<{ connectors: unknown[] }>("/api/connectors"); }
findings() { return this.get<{ findings: unknown[] }>("/api/findings"); }
timeline(limit = 50) { return this.get<{ items: unknown[]; nextCursor: string | null }>(`/api/timeline?limit=${limit}`); }
incidents() { return this.get<{ incidents: unknown[] }>("/api/incidents"); }
auditLog(page = 1) { return this.get<{ entries: unknown[]; totalPages: number }>(`/api/audit?page=${page}`); }
}
// const client = new Client8200("8200_ak_...");
// const { findings } = await client.findings();Python
# 8200.dev Python client — copy into your project, only needs `requests`.
# Authenticate with an API key created in Settings → API Keys.
from dataclasses import dataclass
import requests
@dataclass
class Client8200:
api_key: str
base_url: str = "https://8200.dev"
def _get(self, path: str):
resp = requests.get(
self.base_url + path,
headers={"Authorization": f"Bearer {self.api_key}"},
)
resp.raise_for_status()
return resp.json()
def usage(self):
return self._get("/api/usage")
def connectors(self):
return self._get("/api/connectors")
def findings(self):
return self._get("/api/findings")
def timeline(self, limit: int = 50):
return self._get(f"/api/timeline?limit={limit}")
def incidents(self):
return self._get("/api/incidents")
def audit_log(self, page: int = 1):
return self._get(f"/api/audit?page={page}")
# client = Client8200("8200_ak_...")
# findings = client.findings()["findings"]Changelog
2026-06-27
- Documented the full Developer API: Posture, Findings, Scans, Compliance, Inventory, Flow Guard, Agent Guard, Timeline, Incidents, Sharing, Behavior, Awareness, Audit, Partner and Keys.
- Added the alert.grouped webhook event.
2026-06-20
- Added the multi-framework compliance dashboard and cross-framework gap report.
- Added the Partner API (portfolio + per-client reports) for MSP/MSSP accounts.
2026-06-01
- Introduced API keys (Authorization: Bearer 8200_ak_…) for programmatic access on Business and Enterprise plans.