Skip to content

Developer portal

POST /pqc/scan

Run Q-Day scan: inventory, Mosca risk, remediation backlog, handshake proof, report.

POST /pqc/scanAuth: API key required

Summary

Run Q-Day scan: inventory, Mosca risk, remediation backlog, handshake proof, report.

Example

Response

{
  "status": "success",
  "scanId": "scan-84623480-dc42-430d-881a-d0e5cbaab4ed",
  "scenario": {
    "id": "bank-tls-inventory",
    "title": "Regional bank TLS inventory",
    "summary": "Board mandate to inventory RSA/ECDSA exposure across customer-facing TLS before 2030 NIST deadlines.",
    "target": {
      "domain": "api.regionalbank.example",
      "ports": [
        443,
        8443
      ],
      "persona": "CISO, regional bank",
      "organization": "Regional Bank Holdings",
      "mandate": "NSM-10 / NIST IR 8547 PQC migration program"
    },
    "manualBaseline": {
      "inventoryWeeks": 8,
      "assetsFound": 42,
      "quantumVulnerable": 38,
      "readinessScore": 18,
      "summary": "Spreadsheet inventory from Q1 is already stale; shadow APIs were missed."
    },
    "fixtureAssetIds": [
      "tls-api-bank",
      "tls-auth-bank",
      "jwks-oidc",
      "ssh-bastion",
      "email-mx",
      "code-sign-legacy",
      "discovery-ct-api"
    ]
  },
  "scoreboard": {
    "manual": {
      "inventoryWeeks": 8,
      "assetsFound": 42,
      "quantumVulnerable": 38,
      "readinessScore": 18,
      "readinessBand": "critical",
      "summary": "Spreadsheet inventory from Q1 is already stale; shadow APIs were missed."
    },
    "qtangl": {
      "inventoryWeeks": 0,
      "assetsFound": 7,
      "quantumVulnerable": 7,
      "readinessScore": 24,
      "readinessBand": "critical",
      "summary": "Fixture replay completed in seconds with signed evidence bundle."
    }
  },
  "assets": [
    {
      "id": "tls-api-bank",
      "kind": "tls",
      "host": "api.regionalbank.example",
      "port": 443,
      "label": "API gateway TLS",
      "algorithm": "RSA",
      "keySize": 2048,
      "validityDays": 180,
      "sanDomains": [
        "api.regionalbank.example",
        "www.regionalbank.example"
      ],
      "negotiatedCipher": "TLS_AES_256_GCM_SHA384",
      "negotiatedGroup": "x25519",
      "tlsVersion": "TLSv1.3",
      "vulnerability": {
        "algorithm": "RSA-2048",
        "keySize": 2048,
        "shorLogicalQubits": 4098,
        "classicalSecurityBits": 2048,
        "status": "at-risk",
        "hndlExposed": true,
        "pqcReplacement": "ML-KEM-768 + ML-DSA-65 (hybrid TLS 1.3)",
        "severity": "high",
        "summary": "RSA-2048 key exchange/signing is harvest-now-decrypt-later exposed."
      },
      "pqcReady": false
    },
    {
      "id": "tls-auth-bank",
      "kind": "tls",
      "host": "auth.regionalbank.example",
      "port": 443,
      "label": "Customer auth TLS",
      "algorithm": "ECDSA",
      "keySize": 256,
      "validityDays": 90,
      "sanDomains": [
        "auth.regionalbank.example"
      ],
      "negotiatedCipher": "TLS_AES_128_GCM_SHA256",
      "negotiatedGroup": "secp256r1",
      "tlsVersion": "TLSv1.3",
      "vulnerability": {
        "algorithm": "ECDSA-P256",
        "keySize": 256,
        "shorLogicalQubits": 2330,
        "status": "at-risk",
        "hndlExposed": true,
        "pqcReplacement": "ML-DSA-65 (FIPS 204)",
        "severity": "high",
        "summary": "P-256 certificate is quantum-vulnerable under Shor."
      },
      "pqcReady": false
    }
  ],
  "handshakeProof": {
    "mode": "replayed",
    "kemAlgorithm": "ML-KEM-768",
    "hybridGroup": "X25519MLKEM768",
    "summary": "Captured TLS 1.3 ClientHello negotiating hybrid X25519MLKEM768 key exchange via Open Quantum Safe test server."
  },
  "mosca": {
    "dataLifetimeYears": 10,
    "quantumTimelineYears": 8,
    "hndlRisk": "elevated",
    "inequalityHolds": true,
    "summary": "X + Y > Z under default assumptions — migration window is tight."
  },
  "remediationBacklog": [
    {
      "id": "remediation-code-sign-legacy",
      "assetId": "code-sign-legacy",
      "priority": 1,
      "title": "Migrate Release artifact code signing",
      "action": "Migrate code/document signing to SLH-DSA (FIPS 205) per SP 800-208",
      "deadline": "2030",
      "effortDays": 90
    }
  ]
}

Try it live

Paste your tenant API key to call the live API with your credentials. Leave blank to use the public sandbox key when configured, or click “Show example response” for the static fixture below.

Request body

FieldTypeRequiredDescription
scenarioIdstringNo (bank-tls-inventory)

Scenario

useFixturebooleanNo (true)

Fixture replay

targetstringNo

Override domain

bundleSessionIdstringNo

Upload session

Response

FieldTypeRequiredDescription
scoreboardRiskScoreboardYes

Manual vs Qtangl

assetsCryptoAsset[]Yes

Discovered assets

handshakeProofHandshakeProofYes

PQ TLS proof

Errors

CodeMeaningTypical causeSuggested fix
400Bad requestMalformed JSON or missing required headers.Validate Content-Type and JSON syntax before retrying.
401UnauthorizedMissing or invalid API key in Authorization, x-api-key, or query param.Send Bearer <key> or x-api-key with a valid tenant token.
402Payment requiredFeature not included in current entitlements (e.g. Monitor schedules, remediation automate).Upgrade via billing portal or contact sales for enterprise tier.
403ForbiddenValid key but insufficient role (viewer attempting write) or wrong admin key.Use operator or admin role key; check RBAC matrix.
404Not foundScan, schedule, share link, or resource id does not exist or expired.Verify id and tenant scope; share links expire per expiresHours.
413Payload too largeCBOM ingest or upload exceeds size limit.Split large CBOM documents or use cloud pull integration.
422Unprocessable entityInvalid payload shape, unsupported scenario, or infeasible constraints.Fix field errors in response detail; relax constraints and retry.
429Too many requestsPer-key rate limit exceeded (default 300 requests per minute) or public endpoint limit.Backoff with jitter; cache results; request higher limit for production.
500Internal server errorUnexpected backend failure; includes requestId in response.Retry with exponential backoff; contact support with requestId if persistent.
503Service unavailablePersistence disabled, auth DB unreachable, or admin API not configured.Retry shortly; schedules require Postgres persistence enabled.
501Not implementedProblem type not yet supported on live solver path (routing, allocation).Use type schedule for live jobs, or follow Labs roadmap.

See the full errors reference.