API reference
By CertScore.ai
Reference for the CertScore.ai API v2 resource model, OpenAPI contract, status lifecycle, public-safe evidence summaries, errors, throttling, and legal posture.
CertScore.ai outputs are automated public-web observations for human and agentic review. They are not legal advice, certification, or a compliance determination.
Report evidence
Forms, fields and snapshot links
Retrieve the completed report with GET /api/v2/scans/{scanId}/report-evidence. Follow its cursor for all entries, or request ?format=download for report-display JSON. Retained forms include field metadata, evidence references, capture status and snapshot links. Resolve reportContentRef pointers within the document; images are separate downloads.
Add workpaper=tracking for the starting-page tracking inventory, observed privacy choices, notice passages and GPC evidence. The response includes JSON and CSV download links; preserve the workpaper selector on cursor continuation. Workspace access and existing read quotas apply. Scan resources expose privacyAuditEvidence and gpcResponse.activityComparison when retained.
Public reports and workspace reports keep their existing access boundaries. Full-site exports include retained additional-page forms only after the crawl completes. Missing or withheld snapshots remain unavailable. Inventory review labels do not establish a finding or consent validity.
Reports provide verified, masked form crops when screenshot capture succeeds; not every detected form has a screenshot. A declared/configured destination is the form action, not evidence that CertScore.ai submitted the form or observed a transfer.
Forms coverage and review guideRoutes
API v2 resources
| Method | Route | Purpose |
|---|---|---|
| POST | /api/v2/keys/request | Issue a self-serve read-only + MCP key for a signed-in verified user. |
| GET | /api/v2/auth/check | Validate a bearer credential and return its granted scopes without creating a scan. |
| POST | /api/v2/scans | Create or reuse a public scan; authentication is optional for 20 new anonymous scans per requester IP per UTC day. |
| GET | /api/v2/scans/{scanId} | Retrieve the public-safe scan resource. |
| GET | /api/v2/scans/{scanId}/diagnostics | Retrieve bounded scan timing and collection diagnostics. |
| GET | /api/v2/scans/{scanId}/status | Check scan or job status without inferring from partial evidence. |
| GET | /api/v2/scans/{scanId}/findings | List already-projected public findings for a scan. |
| GET | /api/v2/scans/{scanId}/findings/{findingId} | Retrieve one public-safe finding and capped evidence summary. |
| GET | /api/v2/scans/{scanId}/pulse | Retrieve the Pulse projection wrapper for a completed public scan. |
| GET | /api/v2/scans/{scanId}/report-evidence | Retrieve retained report evidence with pagination or a tracking workpaper. |
| GET | /api/v2/scans/{scanId}/pre-consent-cookies-trackers | Retrieve Pre-consent Cookies & Trackers report table data as public-safe JSON. |
| GET | /api/v2/domains/{domain}/latest | Find the latest eligible public scan for a domain. |
| GET | /api/v2/domains/{domain}/latest/pre-consent-cookies-trackers | Retrieve the latest-domain Pre-consent Cookies & Trackers table projection. |
| GET | /api/v2/health | Check API v2 discovery health. |
Contract
OpenAPI and operation IDs
GET https://certscore.ai/api/v2/openapi.jsonThe OpenAPI contract uses stable operation IDs, explicit status examples, error examples, retry guidance, and public-safe evidence language for generic AI agents and developer tools.
Projection
What is Pulse?
Pulse is CertScore.ai's compact public projection for agents and developer workflows. It packages the scan summary, top findings, evidence highlights, caveats, links, and disclaimer text derived from the same already-projected public scan resources and findings. API v2 exposes the scan resource as the durable object, while the Pulse wrapper is useful when an agent needs the report-style projection in one response. Response types such as certscore_pulse and certscore_pulse_evidence refer to that projection.
Examples
Small response shapes
Scan creation
{
"type": "certscore_scan_job",
"jobId": "job_123",
"scanId": "00000000-0000-4000-8000-000000000123",
"domain": "ergoveritas.com",
"status": "queued",
"retryAfterSeconds": 1
}Pending or running status
{
"type": "certscore_scan_job",
"jobId": "job_123",
"scanId": "00000000-0000-4000-8000-000000000123",
"status": "running",
"phase": "runtime_observation",
"retryAfterSeconds": 2
}Completed scan
{
"type": "certscore_scan",
"scanId": "00000000-0000-4000-8000-000000000123",
"domain": "ergoveritas.com",
"status": "completed",
"score": 72,
"postAcceptObservation": {
"status": "confirmed_observation",
"verdict": "eligible_nonessential_activity_observed_after_confirmed_acceptance",
"productionProjectable": true
},
"postRefusalObservation": {
"status": "confirmed_observation",
"verdict": "eligible_nonessential_activity_observed_after_confirmed_refusal",
"productionProjectable": true
},
"gpcResponse": {
"status": "indeterminate",
"scoreEffect": "none",
"legalInterpretation": "not_assessed"
},
"links": {
"findings": "https://certscore.ai/api/v2/scans/00000000-0000-4000-8000-000000000123/findings",
"preConsentCookiesTrackers": "https://certscore.ai/api/v2/scans/00000000-0000-4000-8000-000000000123/pre-consent-cookies-trackers",
"report": "https://certscore.ai/scan/00000000-0000-4000-8000-000000000123"
}
}Partial or failed scan
{
"type": "certscore_scan",
"scanId": "00000000-0000-4000-8000-000000000123",
"status": "completed_limited",
"coverage": {
"status": "partial",
"summary": "Automated public-web scan completed with coverage limitations."
}
}Findings
{
"type": "certscore_finding_list",
"scanId": "00000000-0000-4000-8000-000000000123",
"findings": [
{
"id": "pre_consent_tracking_detected",
"label": "Third-party tracking observed before recorded consent",
"criticality": "high",
"evidence": {
"basis": "public_report_projection",
"exampleCount": 3,
"examplesShown": 2
}
}
]
}Pre-consent cookies/trackers
{
"type": "certscore_pre_consent_cookies_trackers",
"summary": {
"rowCount": 28,
"trackerCount": 24,
"cookieCount": 4,
"requestCount": 14
},
"rows": [
{
"kind": "tracker",
"vendor": "LinkedIn Insight Tag",
"host": "snap.licdn.com",
"purpose": "Advertising",
"evidenceBasis": "public_report_projection"
}
]
}Typed observations
Accept, Reject, and GPC result fields
postAcceptObservation is present on eligible completed scans where acceptance was attempted. It is a score-neutral comparison baseline: ordinary activity after confirmed acceptance is expected and never projects a negative finding.
postRefusalObservation describes an eligible refusal or necessary-only-equivalent attempt. Registered post-refusal verdicts require confirmed refusal and eligible retained activity. The separately approved Reject-click tracking policy may yield a canonical review finding after a completed Reject click with independently verified tracking evidence, without confirming refusal. Consume returned findings; do not infer a deduction from request counts.
gpcResponse is a jurisdiction-neutral comparison with and without a Global Privacy Control signal. Its scoreEffect is none and legalInterpretation is not_assessed.
Use execution.status for path completion: both succeeded and succeeded_with_confirmation count as successful. Confirmation is a separate subset. Registered paths can omit afterAction; a completed click alone does not prove completed capture. Missing historical execution stays unavailable. An independent verified action can be reported even when the passive session did not observe that control.
Both action results may include afterAction: retained click status, capture stop reason, request and storage-write counts, dropped-request count, and storage-snapshot availability. These facts remain useful with unconfirmed registration. The legacy status, verdict, and productionProjectable describe registered-decision evidence; they do not erase separately retained after-click observations. Missing fields in historical records do not establish failure or absence.
Version 3 adds gpcResponse.observation with bounded observation status, actual main-document delivery, current CMP-recorded sale/sharing state, acknowledgment coverage, and directly classified request and collection counts. Browser attempts conclusively blocked before transmission are counted separately and never treated as GPC delivery. A complete observation can coexist with an indeterminate paired comparison or unknown opt-out state; it does not mean GPC was honored. Historical v1/v2 records retain their original conclusions.
| Field | How to interpret it |
|---|---|
| status | confirmed_observation and confirmed_clean are results. unconfirmed describes registration, and can coexist with a successful execution. Use execution.status for operational completion; these status values do not establish consent honoring. |
| verdict | The registered-decision outcome; afterAction separately describes retained after-click facts. Do not reconstruct a verdict by counting evidence rows; confirmation, temporal anchoring, and in-flight exclusion are applied server-side. |
| coverageLimitations | Names behavior or persistence that was not measured. It bounds the observation; it does not describe the site. |
| termination | kind=evidence_satisfied with intentional=true means the observer stopped after retaining qualifying evidence. Counts are not comparable as volume across scans. |
| productionProjectable | Whether an observation may project a public finding. Non-projectable evidence can still be valid for review. |
None of these fields expresses a legal conclusion. They are automated observations with retained evidence for human and agentic review.
Runtime inventory
Pre-consent Cookies & Trackers JSON
GET /api/v2/scans/{scanId}/pre-consent-cookies-trackers
GET /api/v2/domains/{domain}/latest/pre-consent-cookies-trackers
{
"type": "certscore_pre_consent_cookies_trackers",
"summary": {
"rowCount": 12,
"trackerCount": 6,
"cookieCount": 8,
"requestCount": 10
},
"rows": [
{
"kind": "cookie",
"vendor": "Google",
"host": "doubleclick.net",
"purpose": "Advertising",
"phase": "pre_consent",
"evidenceBasis": "public_report_projection"
}
]
}This endpoint exposes the public report projection used for the Pre-consent Cookies & Trackers table. It strips cookie values, raw request bodies, full request URLs, sensitive query strings, internal artifacts, and scanner-only details. The initial version returns the complete table; server-side filters are deferred while integrations validate usage. Clients can group or filter rows by kind, priority, party, vendor, purpose, and host.
Auth
API keys, scopes, and rate limits
Authorization: Bearer <token>
Current scopes:
- scan:read
- scan:create
- mcpAuthentication is optional for low-volume scan creation: unauthenticated POST /api/v2/scanspermits up to 20 new scans per requester IP per UTC day, and eligible recent-result reuse is free. Contact [email protected] for a higher-volume allowance. Scoped integrations use bearer API keys. Read-only + MCP keys are self-serve for signed-in verified users through POST /api/v2/keys/request. Scan creation keys remain developer-preview; request those at [email protected] with your organization, integration type, expected volume, and requested scopes. Self-serve keys expire after 90 days, are prefixed cs_ro_, and are capped at 60 requests/minute and 500 scan reads/day. HTTP 202 pending responses and HTTP 429 throttled responses may include Retry-After; agents and SDKs should honor that value rather than tight polling.
Read protection
Weighted scan-resource limits
Completed scan and domain resources use weighted, rolling limits. These protections apply in addition to account, API-key, and scan-creation quotas. Policy version 2026-09-12.
| Terminal-read scope | Rolling 10 minutes | Rolling 24 hours |
|---|---|---|
| Caller + scan/resource | 120 units | 1200 units |
| Scan/resource across callers | 4000 units | — |
| Caller across scans/resources | 480 units | — |
Read weights
- Bounded report-evidence export page (up to 64 KB of entries): 1 unit. Follow its cursor; repeated pages still consume quota.
- Ordinary scan, finding, inventory, or domain read: 1 unit.
- Evidence, full report, diagnostics, findings export, or composite bundle: 4 units.
- That permits 30 direct heavy reads per caller and resource in 10 minutes, and 300 in a rolling 24 hours.
Status polling
- Caller + scan: 120 units per rolling 10 minutes.
- Scan across callers: 10000 units per rolling 10 minutes.
- Caller across scans: 600 units per rolling 10 minutes.
HTTP 429 and MCP rate-limit errors include Retry-After when a retry time is available, plus machine-readable policy version, profile, scope, window, limit, usage, and requested-unit fields. Wait for that delay. Poll only active status resources and stop polling when a scan becomes terminal.
Errors
Public-safe error envelope
{
"type": "certscore_api_error",
"error": {
"code": "not_found",
"message": "Scan not found."
},
"links": {
"docs": "https://certscore.ai/developers/reference"
}
}HTTP 401
{
"type": "certscore_api_error",
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key."
}
}HTTP 429
Retry-After: 60
{
"type": "certscore_api_error",
"error": {
"code": "rate_limited",
"message": "Retry later.",
"retryAfterSeconds": 60
}
}HTTP 500
{
"type": "certscore_api_error",
"error": {
"code": "internal_error",
"message": "CertScore.ai API v2 is temporarily unavailable."
}
}Status
Polling and retry behavior
completed
The scan resource and public-safe projections are ready.
pending/running/finalizing
Poll the status resource and honor Retry-After when present.
failed/not_found/throttled
Use the public error envelope and do not infer missing findings from failed work.
Evidence discipline
What API v2 exposes
API v2 exposes scan resources, status, already-projected findings, public-safe evidence summaries, latest-domain lookup, and report-ready review context. It does not expose raw DOM, raw request bodies, internal scanner artifacts, internal reasoning, or display-only findings. Failed or partial scans should be surfaced as incomplete evidence, not compliance failures. Do not infer legal conclusions from scan output.
Developer support
Need an API key, endpoint, SDK helper, MCP tool, or docs fix?
Contact [email protected] for preview API keys, feature requests, broken examples, schema questions, integration issues, or missing API coverage. Include the route, SDK method, MCP tool, scan ID, requested scopes, expected volume, or page URL when useful.
