API Documentation

Complete guide to integrating ComplianceLayer into your security workflow.

Running Scans

Learn how to scan domains, poll for results, and interpret security findings. ComplianceLayer's scanning engine analyzes 15+ security modules to provide a comprehensive risk assessment.

How Scanning Works

When you submit a scan request, ComplianceLayer:

  1. Queues the job — Returns immediately with a job ID
  2. Validates the domain — Resolves DNS and checks accessibility
  3. Runs 15+ modules in parallel — DNS, SSL, headers, ports, WHOIS, DNSSEC, breaches, etc.
  4. Aggregates results — Calculates weighted score and grade
  5. Maps to compliance — SOC 2, ISO 27001, NIST, PCI-DSS, HIPAA

Scans typically complete in 30-60 seconds. Poll the job status endpoint to check progress.

Basic Scan

Submit a domain for scanning:

curl -X POST "https://api.compliancelayer.net/v1/scan" \
  -H "Authorization: Bearer cl_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com"
  }'

Polling for Results

Poll the job status endpoint every 2-3 seconds until status is completed:

async function waitForCompletion(jobId, maxWait = 120) {
  const startTime = Date.now();

  while (Date.now() - startTime < maxWait * 1000) {
    const response = await fetch(
      `https://api.compliancelayer.net/v1/scan/jobs/${jobId}`,
      {
        headers: {
          'Authorization': `Bearer ${process.env.API_KEY}`
        }
      }
    );

    const status = await response.json();

    switch (status.status) {
      case 'completed':
        return status.result;
      case 'failed':
        throw new Error(`Scan failed: ${status.failure_reason}`);
      case 'queued':
      case 'running':
        await new Promise(r => setTimeout(r, 2000)); // Wait 2s
        break;
    }
  }

  throw new Error('Timeout waiting for scan');
}

Understanding Results

Score & Grade

The overall score is a weighted aggregate of all module scores, aligned with cyber insurance underwriting risk bands:

  • 90-100 (A): Low Risk — Excellent security posture
  • 75-89 (B): Low-Medium Risk — Good, minor improvements needed
  • 55-74 (C): Medium Risk — Material gaps present, several issues to address
  • 35-54 (D): High Risk — Significant vulnerabilities, urgent action required
  • 0-34 (F): Critical Risk — Multiple critical security gaps

Risk Levels

Each scan receives a risk_level classification for underwriting context:

  • low (90-100): Strong security controls, minimal risk exposure
  • low_medium (75-89): Acceptable with minor issues, low-moderate risk
  • medium (55-74): Material gaps present, moderate risk
  • high (35-54): Significant exposure, high risk
  • critical (0-34): Multiple critical issues, very high risk

Module Scores

Each security module has its own score and weight. Weights are based on materiality for cyber insurance underwriting decisions:

Tier 1: Material Controls (85%)

ModuleWeightChecks
SSL/TLS25%Certificate validity, expiry, chain, protocols, cipher suites
HTTP Headers25%HSTS, CSP (including weak directive detection), CORS misconfiguration, X-Frame-Options
DNS/Email20%SPF, DMARC, DKIM (info only), CAA records, MX configuration
Open Ports15%Exposed services, dangerous ports (Telnet, FTP, RDP), attack surface

Tier 2: Secondary Controls (15%)

ModuleWeightChecks
Cookie Security8%Secure, HttpOnly, SameSite flags
DNSSEC5%DNSSEC signing, chain of trust
WAF Detection4%Web Application Firewall presence
JavaScript Audit3%Vulnerable JS libraries (only exploitable CVEs)

Tier 3: Informational Only (0%)

The following modules are included for context but do not affect the score:

ModuleWeightPurpose
Subdomains0%Inventory and attack surface mapping
Blacklists0%Reputation indicators (outcome not control)
Reputation0%Historical reputation data
Breach History0%Historical breach exposure
WHOIS0%Domain registration details
Trackers0%Privacy analysis (not security)
Tech Stack0%Technology fingerprinting for OSINT

Issue Severity

  • Critical: Immediate action required — Catastrophic for operations (expired SSL, no SPF/DMARC, exposed admin ports)
  • High: Urgent fix needed — Important security gaps (weak TLS, missing HSTS on HTTPS sites)
  • Medium: Should address soon — Best practice violations (weak CSP directives, CORS misconfigurations)
  • Low: Minor improvement — Defense-in-depth enhancements (X-Frame-Options, cookie settings)
  • Info: Informational only — No penalty to score (DKIM auto-detection limitations, SSH on port 22 with key auth)

Full Report Structure

The complete report includes:

{
  "domain": "example.com",
  "score": 87,
  "grade": "B",
  "risk_level": "low_medium",  // One of: low, low_medium, medium, high, critical
  "report_id": "cl_rpt_abc123def456",  // Use for PDF generation & public verification
  "scanned_at": "2026-03-07T12:00:00Z",

  // Individual module results
  "modules": {
    "dns_email": {
      "score": 90,
      "grade": "A",
      "weight": 0.20,
      "issues": [...]
    },
    "ssl": {
      "score": 95,
      "grade": "A",
      "weight": 0.25,
      "issues": [...]
    },
    "headers": { ... }
  },

  // All issues sorted by severity
  "issues": [
    {
      "severity": "high",
      "finding": "Missing DMARC record",
      "remediation": "Add _dmarc TXT record",
      "module": "dns_email"
    }
  ],

  // Important caveats about the assessment
  "caveats": [
    "External scanning only - internal controls not assessed",
    "DKIM false negatives possible with custom selectors",
    "Port scan results depend on Shodan data availability"
  ],

  // Compliance framework mappings
  "compliance": {
    "soc2": [...],
    "iso27001": [...],
    "nist": [...],
    "pcidss": [...],
    "hipaa": [...]
  },

  // Prioritized action items
  "recommendations": [
    "Add DMARC record to prevent email spoofing",
    "Enable HSTS to enforce HTTPS"
  ]
}

Best Practices

1. Cache Results

Don't scan the same domain repeatedly. Cache results for at least 1 hour to reduce API usage.

2. Use Webhooks

Instead of polling, configure webhooks to receive results when scans complete. This reduces API calls and improves efficiency.

3. Handle Errors Gracefully

try {
  const jobId = await startScan('example.com');
  const result = await waitForCompletion(jobId);
  console.log(`Score: ${result.score}`);
} catch (error) {
  if (error.status === 429) {
    // Rate limit - wait and retry
    console.log('Rate limited, waiting...');
    await new Promise(r => setTimeout(r, 60000));
  } else if (error.status === 400) {
    // Invalid domain
    console.error('Invalid domain:', error.message);
  } else {
    // Other error
    console.error('Scan error:', error);
  }
}

4. Monitor Historical Trends

Track score changes over time to identify security drift. Set up monitoring for critical domains.