Documentation

The QUORUM API provides programmatic access to the full decision stack — behavioral analysis, fraud scoring, forensic case management, and institutional compliance filings. All endpoints require API key authentication and return structured JSON.

Authentication

Every request must include a bearer token in the Authorization header. API keys are issued per organization and scoped to a single tenant namespace. Keys do not expire but can be revoked at any time from the administrative console.

HTTP HEADER
Authorization: Bearer qrm_live_••••••••••••••••••••••••••••••••

Key prefixes

PrefixEnvironmentNotes
qrm_live_ProductionGenerates real forensic cases and SAR filings
qrm_test_SandboxFull scoring, no regulatory reporting or case storage

Requests authenticated with a qrm_test_ key follow identical decision logic but suppress all downstream regulatory actions (SAR/STR auto-filing, evidence package generation). Use sandbox keys during development and integration testing.

Browser SDK

The Quorum Browser SDK passively collects seven behavioral signal channels from authenticated user sessions and attaches them to every API call via request headers. Integration is a two-step process: include the script, then initialize with the current user's identifier.

Include

HTML
<script src="https://kbanalyticalsolutions.ca/quorum-sdk.js"></script>

Initialize

JAVASCRIPT
const sdk = QuorumSDK.init({
userId: 'usr_48f2a9e1',
apiKey: 'qrm_live_••••••••'
});
// SDK auto-attaches headers to every fetch() call after init

Headers injected

HeaderContents
X-Quorum-CIV-SignalsJSON-encoded 7-channel behavioral signal vector (Base64)
X-Quorum-Subject-IdUser identifier passed to init()

Signal channels

ChannelMetric
canvas_hashDevice rendering fingerprint via 2D canvas pixel hash
audio_entropyAudioContext oscillator output distribution entropy (0.0–1.0)
webgl_hashGPU renderer string + vendor hash via WebGL
hardware_profileLogical CPU count, device memory, max touch points
typing_varianceInter-keystroke interval variance from recent input events
mouse_entropyShannon entropy of recent pointer movement deltas
motion_varianceDeviceMotionEvent acceleration variance (mobile) or 0 (desktop)

The SDK operates entirely passively after init(). It does not read DOM content, intercept form values, or make independent network requests. Signal collection runs in a background microtask; call sdk.destroy() on logout to clear the collection interval.

POST /api/v1/analyze

The primary decisioning endpoint. Submits a transaction or event for multi-tier fraud scoring. Returns a verdict with full reasoning, score decomposition, and active flags.

POST /api/v1/analyze Requires: Bearer token + Atomic handshake

Request body

FieldTypeDescription
organizationId string required Your organization identifier
userId string required Subject user identifier
transactionId string optional External transaction reference
amount number optional Transaction amount in base currency units
currency string optional ISO 4217 currency code (default: USD)
merchantCategory string optional MCC or free-form merchant category string
ipAddress string optional IPv4 or IPv6 originating address
deviceFingerprint string optional Client device identifier (SDK-generated or custom)
action string optional Event type: payment, login, withdrawal, transfer, account_change
metadata object optional Arbitrary key/value pairs passed through to forensic records

Example request

HTTP REQUEST
POST /api/v1/analyze HTTP/1.1
Authorization: Bearer qrm_live_••••••••
Content-Type: application/json
X-Quorum-Atomic-QID: 7f3a2b1c-...
X-Quorum-CIV-Signals: eyJjYW52YXNfaGFzaCI6...
X-Quorum-Subject-Id: usr_48f2a9e1

{
  "organizationId": "org_f84e21",
  "userId": "usr_48f2a9e1",
  "amount": 4750.00,
  "currency": "USD",
  "action": "payment",
  "ipAddress": "198.51.100.4",
  "merchantCategory": "ELECTRONICS",
  "deviceFingerprint": "dfp_9c3e..."
}

Response Schema

All responses are JSON. A successful analysis returns HTTP 200 with the following structure.

JSON RESPONSE — 200 OK
{
  "success": true,
  "verdict": "FLAG",
  "totalScore": 61,
  "finalAction": "review",
  "flags": [
    "HIGH_VELOCITY",
    "CROSS_BORDER_MISMATCH"
  ],
  "reasoning": "Transaction velocity elevated (4 in 60min). IP geolocation (DE) inconsistent with account registration (CA).",
  "scoreBreakdown": {
    "velocityScore": 25,
    "geolocationScore": 20,
    "behavioralScore": 16,
    "deviceScore": 0
  },
  "caseId": null,
  "evidencePackagePath": null,
  "processingMs": 43
}
FieldTypeDescription
verdictstringPASS / FLAG / BLOCK
totalScoreintegerComposite risk score 0–100
finalActionstringallow / review / block
flagsstring[]Active risk flag codes (see Flag Reference)
reasoningstringHuman-readable decision rationale from the AI arbitration tier
scoreBreakdownobjectPer-signal-category score contributions
caseIdinteger | nullForensic case ID if a case was opened (BLOCK verdicts only)
evidencePackagePathstring | nullPath to generated evidence package (BLOCK verdicts only)
processingMsintegerTotal server processing time in milliseconds

Verdict Codes

The decision engine maps total risk score to a three-tier verdict. Thresholds are configurable per organization; the defaults below apply to all accounts at provisioning.

VerdictScore RangefinalActionDownstream
PASS 0 – 34 allow None. Session continues.
FLAG 35 – 74 review Event queued for analyst review. No automatic block.
BLOCK 75 – 100 block Session terminated. Forensic case opened. SAR/STR auto-filed if score ≥ 85.

BLOCK verdicts at score ≥ 85 automatically trigger SAR filings under FinCEN Form 111 (US jurisdiction) and FINTRAC STR (Canadian jurisdiction) when SAR_AUTO_SUBMIT is enabled for the organization.

Flag Reference

Flags are human-readable identifiers for individual risk signals. A response may carry zero or more flags. Flags from multiple signal categories (behavioral, velocity, geographic, device) are combined into the total score.

Behavioral flags

FlagScoreCondition
NO_DEVICE_MOTION+15DeviceMotionEvent variance = 0 on a claimed mobile device
AUDIO_CONTEXT_ANOMALY+20AudioContext entropy < 0.1 (consistent with headless browser)
HIGH_TYPING_VARIANCE+10Inter-keystroke interval variance > 2σ above session baseline
LOW_MOUSE_ENTROPY+12Pointer movement entropy < 0.3 (scripted/automated movement pattern)
CIV_DRIFT+25Continuous identity Z-score > 82 (session takeover indicator)
CIV_WARN+10Continuous identity Z-score 55–81 (elevated drift)
CANVAS_MISMATCH+18Canvas fingerprint changed within authenticated session

Velocity flags

FlagScoreCondition
HIGH_VELOCITY+25> 5 transactions in a 60-minute window
AMOUNT_THRESHOLD+20Single transaction > $5,000 USD equivalent
RAPID_ESCALATION+15Transaction amount 3× or more above 30-day average

Geographic / network flags

FlagScoreCondition
CROSS_BORDER_MISMATCH+20IP geolocation country differs from account registration country
TOR_EXIT_NODE+35Source IP is a known Tor exit node
HIGH_RISK_ASN+25Source IP belongs to a high-risk autonomous system (AbuseIPDB score > 75)
VPN_PROXY_DETECTED+15IP reputation service reports VPN or datacenter hosting
IMPOSSIBLE_TRAVEL+40Two events from geolocations that require faster-than-possible travel between them

Device flags

FlagScoreCondition
NEW_DEVICE_HIGH_VALUE+22First-seen device fingerprint + transaction > $1,000
DEVICE_FINGERPRINT_ABSENT+8No device fingerprint provided for an authenticated request
EMULATION_DETECTED+30WebGL renderer or canvas output consistent with headless Chrome or Puppeteer

Institutional API

Institutional-tier endpoints are scoped to /api/institutional/v1/ and require an Operational or Sovereign access tier. All institutional endpoints apply the Atomic Handshake protocol — each request must carry a valid X-Quorum-Atomic-QID header obtained from the handshake sequence below.

Atomic Handshake

The Atomic Handshake is a two-step challenge/response protocol that binds each institutional API call to a single-use quantum-inspired state token. Tokens expire after 30 seconds.

STEP 1 — INIT STATE
POST /api/v1/atomic/init
Authorization: Bearer qrm_live_••••••••

→ { "qid": "7f3a2b1c-...", "ttl": 30 }
STEP 2 — MEASURE STATE
GET /api/v1/atomic/verify/:qid
Authorization: Bearer qrm_live_••••••••

→ { "challenge": "a3f8..." }

// Include challenge in subsequent request:
X-Quorum-Atomic-QID: 7f3a2b1c-...
X-Quorum-Atomic-Challenge: a3f8...

Key institutional endpoints

MethodPathDescription
POST /api/institutional/v1/analyze Full deep analysis with AI arbitration and evidence packaging
GET /api/institutional/v1/cases List open forensic cases for the organization
GET /api/institutional/v1/cases/:id Retrieve a forensic case with full evidence manifest
POST /api/institutional/v1/cases/:id/export Generate a signed PDF evidence package for a case
GET /api/institutional/v1/sar-filings List SAR/STR filings for the organization with submission status
GET /api/institutional/v1/audit-ledger Access the cryptographic Merkle audit ledger (append-only)
POST /api/institutional/v1/audit-ledger/verify Submit a Merkle proof for record inclusion verification

Error Codes

All errors return a structured JSON body with a machine-readable error code and a human-readable message.

ERROR RESPONSE
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests. Retry after 12 seconds.",
    "status": 429,
    "retryAfter": 12
  }
}
HTTP StatusCodeDescription
400INVALID_REQUESTMissing required fields or malformed JSON
401UNAUTHORIZEDMissing or invalid bearer token
403TENANT_MISMATCHOrganization ID does not match the authenticated API key's tenant
403DECEPTION_SANDBOXRequest was identified as a scanner or probe; routed to isolated sandbox
410STATE_COLLAPSEDAtomic handshake QID has expired or already been consumed
429RATE_LIMIT_EXCEEDEDRequest rate exceeded; Retry-After header included
503ATOMIC_STATE_UNAVAILABLERedis state backend temporarily unavailable
503CIRCUIT_OPENDownstream service circuit breaker is open; system in degraded mode

Webhooks

QUORUM can POST event payloads to a configured HTTPS endpoint for real-time notification of significant decisions. Webhooks are configured per organization in the administrative console.

Signed delivery

Every webhook request includes an X-Quorum-Signature-256 header containing an HMAC-SHA256 signature of the raw request body, computed using your webhook secret. Verify the signature before processing the payload.

VERIFICATION — NODE.JS
import crypto from 'node:crypto';

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature.replace('sha256=', ''))
  );
}

Event types

EventTrigger
verdict.blockAny BLOCK verdict issued
verdict.flagAny FLAG verdict issued
sar.filedSAR/STR filing created (pending or submitted)
case.openedNew forensic case created
case.updatedCase status changed by analyst
civ.driftContinuous identity Z-score exceeded block threshold during a live session

Rate Limits

Rate limits are applied per API key (not per IP). Limits are enforced at the Redis layer and reset on a rolling window.

TierLimitWindow
Analytical (default)300 requests15 minutes
Operational1,200 requests15 minutes
SovereignUnlimitedContractual SLA applies

When a rate limit is exceeded, the response includes a Retry-After header with the number of seconds until the window resets. Requests beyond the limit return HTTP 429 with code RATE_LIMIT_EXCEEDED.

Need higher limits or custom integration support?

Operational and Sovereign access tiers include dedicated integration engineering and custom SLA agreements.

Contact Institutional Sales