REST API v1
Run CISO-level compliance assessments and passive website scans from your own tools, CI pipelines, or products. All endpoints return JSON.
Authentication
Create a key in Dashboard → API keys (free account required, max 10 active keys), then send it as a Bearer token. Keys are shown once at creation and stored hashed. Each key has a per-minute rate limit; exceeding it returns 429.
Authorization: Bearer sk_sc_...POST /api/v1/assess
Scope: assess. Without answers, returns the question bank for the requested domains. With answers, returns scores, grades, category breakdowns, expert recommendations and applicable laws.
curl -X POST https://structureclerk.ca/api/v1/assess \
-H "Authorization: Bearer sk_sc_..." \
-H "Content-Type: application/json" \
-d '{
"domains": ["data_protection", "cybersecurity"],
"jurisdictions": ["CA_QC", "EU"],
"answers": {
"data_protection": { "dp_1": true, "dp_2": "partial" }
}
}'{
"overallScore": 62,
"grade": "B-",
"domains": {
"data_protection": {
"score": 62,
"answeredQuestions": 2,
"categoryScores": { "...": { "percentage": 50 } },
"topRecommendations": [
{
"questionId": "dp_2",
"title": "…",
"advice": "…",
"quickWin": "…",
"effort": "medium",
"impact": "high",
"timeline": "30 jours"
}
]
}
},
"applicableLaws": [
{ "jurisdiction": "Québec", "law": "Loi 25", "domain": "data_protection" }
]
}POST /api/v1/scan
Scope: scan. Passive website compliance scan: HTTPS, privacy policy detection, cookie banner, HTTP security headers, contact information. Public pages only — no intrusion, no active testing.
curl -X POST https://structureclerk.ca/api/v1/scan \
-H "Authorization: Bearer sk_sc_..." \
-H "Content-Type: application/json" \
-d '{ "url": "https://www.example.com" }'{
"url": "https://www.example.com",
"overallScore": 75,
"checks": {
"https": { "passed": true, "details": "…" },
"privacyPolicy": { "found": true, "url": "…", "details": "…" },
"cookieBanner": { "detected": false, "details": "…" },
"securityHeaders": { "score": 57, "headers": { "…": {} }, "details": "…" },
"contactInfo": { "found": true, "details": "…" }
},
"recommendations": ["…"]
}Key management
Session-authenticated (browser) endpoints backing the dashboard UI:
GET /api/v1/keys— list your keys (prefixes only)POST /api/v1/keys— create a key ({ "name": "...", "scopes": ["assess","scan","authority"] })DELETE /api/v1/keys/:id— deactivate a key
Free endpoints
Public, no key, no credit. They were shipped and never documented here, which is the same as not shipping them.
GET /api/v1/pricing— the live rate card: credit cost per endpoint, top-up packs, the daily free allowance. Machine-readable, and the source the docs read from.GET /api/v1/authority/verify/:evidence_id— verify a decision's Ed25519 signature. Free and account-free, permanently.GET /api/v1/authority/verify/anchors— published anchors of the chained decision log, for third-party checking.GET /api/v1/authority/stats— aggregate decision counts. No decision content, no identifiers.
Credits and the free allowance
The paid endpoints are metered in prepaid credits, with a daily free allowance consumed first. The refusals below are the ones you will actually receive; the full order of resolution, prices and response headers are on the Billing page.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized / invalid_api_key | Missing, invalid or expired key |
| 403 | forbidden | Key lacks the required scope |
| 429 | rate_limited | Per-key per-minute limit exceeded |
| 403 | insufficient_scope | Valid key, wrong scope. The body names the scope required and the scopes granted. |
| 429 | free_tier_exhausted | Anonymous caller past the daily allowance. Use a key, or top up. |
| 402 | insufficient_credits | Balance too low. The body carries the balance, the amount required and a recharge URL. |
| 503 | metering_unavailable | Usage counter unreachable. Anonymous calls refused; key holders served and billed directly. |
| 413 | Request too large | Body over the endpoint limit, measured rather than declared. |
| 400 | invalid_input | Malformed body — see the message field |