Developers
The ConfigCheckup API.
Pull scores and findings into your PSA, dashboards or data warehouse, queue assessments from your own automation, and get signed webhooks when assessments finish or a tenant drifts. Included from the Growth plan.
Basics
Authentication
Create a key in Settings → API and webhooks and send it on every request:
curl https://configcheckup.com/api/v1/tenants -H "Authorization: Bearer ccu_…"
Keys belong to the workspace and see every tenant in it. They are shown once, stored only as a hash, and can expire or be revoked at any time. Responses are JSON: { "data": … } on success and { "error": { "code", "message" } } otherwise, with the usual HTTP status. Each key may make 120 requests a minute; beyond that you get 429 with a Retry-After header.
Reference
Endpoints
| Request | Scope | Returns |
|---|---|---|
| GET /api/v1/tenants | read | Every tenant in the workspace. Filter with ?tag=managed. |
| GET /api/v1/tenants/{id} | read | One tenant, with its latest completed assessment. |
| GET /api/v1/tenants/{id}/findings | read | Findings from the latest assessment. ?status=FAIL,WARN (default) or all. |
| GET /api/v1/tenants/{id}/assessments | read | Assessments for a tenant, newest first. ?limit= up to 100. |
| POST /api/v1/tenants/{id}/assessments | assessments:run | Queue an assessment. Returns it with status QUEUED; poll it until COMPLETED. |
| GET /api/v1/assessments/{id} | read | Status, score, grade, severity counts and category scores. |
| GET /api/v1/assessments/{id}/findings | read | Findings from one assessment. Same ?status filter. |
| GET /api/v1/reports | read | Reports, newest first. ?tenantId= and ?limit=. |
| GET /api/v1/reports/{id}/download | read | The report file (PDF or HTML). |
Events
Webhooks
Add an HTTPS endpoint and choose its events. Each delivery is a POST with a JSON body { id, event, createdAt, data } and these headers: ConfigCheckup-Event, ConfigCheckup-Delivery and ConfigCheckup-Signature: t=…,v1=…. Answer with any 2xx within ten seconds. Failures are retried with backoff; an endpoint that fails twenty times in a row is paused.
- assessment.completedassessmentId, tenantId, tenantName, score, grade, counts
- assessment.failedassessmentId, tenantId, tenantName, error
- drift.detectedtenantId, tenantName, regressions: [{ ruleId, title, summary, from, to }]
- report.readyreportId, tenantId, assessmentId, type, format, title
Verify every delivery. v1 is HMAC-SHA256 of t.rawBody under the endpoint's signing secret:
import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody: the request body exactly as received, before JSON parsing.
export function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const age = Math.abs(Date.now() / 1000 - Number(parts.t));
if (!parts.t || !parts.v1 || age > 300) return false; // reject replays older than 5 minutes
const expected = createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');
return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}Questions or something missing? Email [support email].