Developer docs

TypeScript SDK

By CertScore.ai

Use the CertScore.ai TypeScript SDK for scan, status, finding, and domain latest workflows with resource clients.

CertScore.ai outputs are automated public-web observations for human and agentic review. They are not legal advice, certification, or a compliance determination.

Package

Install the TypeScript SDK

The TypeScript SDK is published as @certscore/sdk. Use version 0.2.13 or newer for typed privacy workpapers, GPC observations and activity comparisons, and Accept/Reject after-click summaries on Pulse and API v2 scan resources, plus API v2 scan creation in EU-Germany, EU-Ireland, and California. Source and examples live in packages/certscore-sdk.

npm install @certscore/sdk

SDK requests identify themselves with X-CertScore-Client: sdk by default. The optional clientName setting is reserved for trusted integrations that share the SDK runtime with MCP.

Completed with limited coverage

Handle no-go results as usable outcomes

A scan that reached a blocked, placeholder, prelaunch, error, or otherwise unusable page resolves normally withstatus: completed_limited. Inspect the typed noGo object for customer-safe messaging, attribution, retry guidance, and a bounded evidence excerpt.

const scan = await certscore.scans.wait(created);

if (scan.resultDisposition === "no_go" && scan.noGo) {
  console.log(scan.noGo.title);
  console.log(scan.noGo.explanation);
  console.log(scan.noGo.limitationKind);
  console.log(scan.noGo.recommendedNextAction);
  console.log(scan.noGo.evidenceExcerpt ?? "No excerpt retained");
}

Resource clients

Create a scan and wait for completion

import { CertScoreClient } from "@certscore/sdk";

const certscore = new CertScoreClient({
  apiKey: process.env.CERTSCORE_API_KEY
});

const created = await certscore.scans.create("https://ergoveritas.com/.well-known/certscore-canary/sentinels/broad-baseline.html", {
  freshness: "latest",
  scanFrom: "eu_ie"
});

const completed = await certscore.scans.wait(created);
const scanId = completed.scanId;

console.log(
  completed.gpcResponse?.observation?.status, // capture completion
  completed.gpcResponse?.status, // paired response
  completed.postAcceptObservation?.execution, // path completion, separate from confirmation
  completed.postAcceptObservation?.afterAction,
  completed.postRefusalObservation?.execution,
  completed.postRefusalObservation?.afterAction,
  completed.postAcceptObservation?.verdict,
  completed.postRefusalObservation?.verdict
);

const status = await certscore.scans.status(scanId);
const findings = await certscore.findings.list(scanId);
const preConsentTable = await certscore.scans.preConsentCookiesTrackers(scanId);
const latest = await certscore.domains.latest("ergoveritas.com");
const latestPreConsentTable = await certscore.domains.latestPreConsentCookiesTrackers("ergoveritas.com");

console.log(status.status, findings.findings.length, preConsentTable.summary.rowCount, latest.scan?.scanId, latestPreConsentTable.summary.rowCount);

Existing scans

Read privacy evidence and download the tracking workpaper

Read a completed scan without creating another. Use the observation fields even when the paired GPC comparison is indeterminate; keep the matched duration with activity counts.

const scan = await certscore.scans.get(scanId);
console.log(scan.privacyAuditEvidence?.controls);
console.log(scan.privacyAuditEvidence?.notices);
console.log(scan.gpcResponse?.observation);
console.log(scan.gpcResponse?.activityComparison);

// Request this follow-up when inventory or downloads are needed.
const page = await certscore.getReportEvidencePage(scanId, {
  workpaper: "tracking"
});
console.log(page.download?.url);    // JSON workpaper
console.log(page.download?.csvUrl); // inventory CSV

// Preserve the selector when continuing a paginated export.
if (page.pagination.nextCursor) {
  const nextPage = await certscore.getReportEvidencePage(scanId, {
    workpaper: "tracking",
    cursor: page.pagination.nextCursor
  });
  console.log(nextPage.entries);
}

Workpapers cover the starting page. Download links use the existing report access rules; private links expire after five minutes. Keep those links confidential. Old records can omit newer evidence fields. Control presence and notice passages are observations; use canonical findings for score effects.

npm install @certscore/[email protected]

Path outcomes

Count completed Accept and Reject paths

Count both succeeded and succeeded_with_confirmation from execution.status. A completed click and bounded observation establish success; confirmation is a separate subset. Registered paths may omit afterAction. Missing historical execution means unavailable.

Timing

Read scan runtime fields

API v2 scan resources and status responses include startedAt, completedAt, and scanTimeSeconds when timing evidence is available. Treat null as unavailable rather than zero.

const scan = await certscore.scans.get(scanId);
const status = await certscore.scans.status(scanId);

console.log(scan.startedAt, scan.completedAt, scan.scanTimeSeconds);
console.log(status.startedAt, status.completedAt, status.scanTimeSeconds);

Available clients

SDK surface

certscore.scans.create()certscore.scans.get()certscore.scans.preConsentCookiesTrackers()certscore.scans.status()certscore.scans.wait()certscore.findings.list()certscore.findings.get()certscore.findings.explain()certscore.domains.latest()certscore.domains.latestPreConsentCookiesTrackers()

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.