API Reference
Back to Stradum

API Reference

Complete REST API documentation for the Stradum behavioral biometrics platform.

Introduction

Stradum uses behavioral biometrics to verify identity. The API accepts behavioral events from the JavaScript SDK, manages sessions and identities, runs analysis, and delivers results via webhooks and a real-time dashboard.

The typical integration flow is:

  1. SDK captures behavioral events during form interaction
  2. Customer server completes the session and links it to an identity
  3. Analysis is triggered, producing match scores and reason codes
  4. Results are delivered via API response, webhooks, and dashboard

Base URL

https://api.stradum.com/api/v1

All endpoints are prefixed with /api/v1.

Error Handling

The API uses standard HTTP status codes. Error responses include a JSON body:

{
  "detail": "Session not found"
}
StatusMeaning
200Success
201Resource created
204Deleted (no content)
401Missing or invalid API key / JWT token
403Key lacks permission for this endpoint (e.g. publishable key on server-only route)
404Resource not found
402Payment required — trial limit reached or trial expired
422Validation error — check request body
429Session quota exceeded (org limit)
500Internal server error

Rate Limits

Default limits to ensure system stability:

  • Event batches: max 5,000 events per request
  • Sessions: max 100,000 events per session
  • Session ID: 1–128 characters

What is a Session?

A session is one meaningful form interaction — from page load through submission or abandonment. Each time a person interacts with a form instrumented with Stradum, that creates a session.

Billable sessions: Only sessions with real behavioral activity (100+ events) count toward your org's quota. Accidental page loads, bots that leave immediately, and sessions with minimal interaction do not consume your trial or plan limit. This threshold ensures you're charged for genuine form-filling activity, not noise.

Trial limits: Self-serve signups get a 30-day trial with up to 1,500 billable sessions. When either limit is reached, the API returns 402 Payment Required on event ingestion until you subscribe.

JavaScript SDK

Installation

Add the SDK script tag to your page. No build step or npm install required.

<script src="https://api.stradum.com/sdk/v1/stradum.min.js"></script>

The SDK exposes a global Stradum namespace. Size: < 25KB gzipped. Current version: 0.1.0

Methods

Stradum.init(config) → string (sessionId)

Initialize the SDK and begin capturing behavioral events. Returns the session ID.

ConfigTypeDefaultDescription
apiUrlstringrequiredBase URL for the Stradum API
apiKeystringrequiredPublishable API key (pk_live_ or pk_test_). Sent as X-Stradum-Key header on all requests.
sessionIdstring?autoPre-generated session ID
captureValuesbooleanfalseCapture field values (test environments only)
autoStartbooleantrueBegin capturing immediately
Stradum.getSessionId() → string | null

Returns the current session ID for post-submission linking. Returns null if not initialized.

Stradum.setMetadata(metadata) → object | null

Merge metadata into the session. Call at any time when candidate_id, report_id, or other keys become available. Sends a POST to the metadata endpoint. Returns the metadata object on success, null if not initialized.

// Associate metadata anytime during the session
Stradum.setMetadata({
  candidate_id: 'c_abc123',
  report_id: 'r_456'
});
Stradum.complete(options?) → { sessionId, summary, eventCount }

Signal form submission. Captures a form_submit event, generates a summary, and flushes all buffered events. Call this in your form's submit handler.

OptionTypeDescription
fieldValuesobjectCollected field values for linking
Stradum.getStats() → { sessionId, eventCount, summary, isActive }

Get current session statistics without stopping capture.

Stradum.stop()

Stop capturing and flush all buffered events via sendBeacon.

Stradum.reset()

Reset the SDK state for a new session. Stops capture and clears all internal state.

Stradum.isActive() → boolean

Check if the SDK is initialized and actively capturing events.

Typical Integration Flow

Complete end-to-end example showing SDK initialization, metadata association, form submission, identity linking, and analysis triggering.

<!-- 1. Include the SDK -->
<script src="https://api.stradum.com/sdk/v1/stradum.min.js"></script>
<script>
  // 2. Initialize with your publishable key — capture begins automatically
  const sessionId = Stradum.init({
    apiUrl: 'https://api.stradum.com',
    apiKey: 'pk_live_your_publishable_key'
  });

  // 3. Associate metadata when it becomes available
  Stradum.setMetadata({
    candidate_id: 'c_abc123',
    report_id: 'r_456'
  });

  // 4. On form submit — complete the session client-side
  document.querySelector('form').addEventListener('submit', async (e) => {
    e.preventDefault();
    const formData = Object.fromEntries(new FormData(e.target));

    // Signal completion to SDK (flushes events)
    Stradum.complete({ fieldValues: formData });

    // 5. Send to your server with the session ID
    await fetch('/your-server/submit', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ...formData, stm_session_id: sessionId })
    });
  });
</script>

Server-Side (Your Backend)

# Your server receives the form submission with stm_session_id
# All server-side calls use the secret key
headers = {"X-Stradum-Key": "sk_live_your_secret_key"}

# 6. Resolve identity (creates if new)
identity = requests.post("https://api.stradum.com/api/v1/identities/resolve",
  params={"external_id": user.email},
  headers=headers
).json()

# 7. Complete the session
requests.post(f"https://api.stradum.com/api/v1/sessions/{stm_session_id}/complete",
  json={
    "identity_id": identity["identity_id"],
    "field_values": {"first_name": "John", "email": "john@example.com"}
  },
  headers=headers
)

# 8. Link session to identity (with account context)
requests.post("https://api.stradum.com/api/v1/identities/link",
  json={
    "session_id": stm_session_id,
    "identity_id": identity["identity_id"],
    "account_id": "acct_1",
    "account_name": "Acme Corp"
  },
  headers=headers
)

# 9. Trigger analysis
analysis = requests.post("https://api.stradum.com/api/v1/analysis/trigger",
  json={"session_id": stm_session_id},
  headers=headers
).json()

# 10. Use the result
if analysis["match_status"] in ("review", "mismatch"):
    flag_for_review(stm_session_id)

MCP Server

AI Assistant Integration

Stradum provides a Model Context Protocol (MCP) server that lets AI assistants (Cursor, Claude Desktop, and other MCP-compatible tools) query your behavioral biometrics data directly.

Available Tools

ToolDescription
list_sessionsList recent sessions with optional filters
get_sessionGet details for a specific session
get_session_detailGet enriched session data with timeline and metadata
get_analysisRetrieve analysis results for a session
trigger_analysisTrigger analysis for a completed session
get_timelineGet field-level interaction timeline
list_alertsList recent signal alerts
get_overviewGet dashboard overview metrics
list_identitiesList identity records
get_identityGet a specific identity and its sessions
create_webhookRegister a new webhook endpoint

Setup for Cursor

Add the following to .cursor/mcp.json in your project root:

{
  "mcpServers": {
    "stradum": {
      "command": "npx",
      "args": ["@anthropic/stradum-mcp"],
      "env": {
        "STRADUM_API_URL": "https://api.stradum.com",
        "STRADUM_SECRET_KEY": "sk_live_your_secret_key"
      }
    }
  }
}

Example Prompts

"Show me the latest 10 sessions and their match statuses"

"Analyze session stm_abc123 and explain the results"

"What are today's signal alerts?"

"Get the interaction timeline for session stm_abc123"

"Create a webhook for analysis.completed events at https://my-server.com/hooks"

Authentication

Overview

All API requests are authenticated via the X-Stradum-Key header. Dashboard routes use JWT bearer tokens.

API Key Types

Publishable Key (pk_live_*): Safe for client-side code. Used by the browser SDK. Can create sessions, send events, complete sessions, and update metadata.

Secret Key (sk_live_*): Server-side only. Never expose in client code. Can do everything publishable keys can, plus: retrieve analysis results, view session timelines, manage identities, manage webhooks.

Set via the X-Stradum-Key header.

# Client-side (SDK)
Stradum.init({
  apiUrl: 'https://api.stradum.com',
  apiKey: 'pk_live_your_publishable_key'
});

# Server-side
curl -H "X-Stradum-Key: sk_live_your_secret_key" \
  https://api.stradum.com/api/v1/analysis/trigger

Dashboard Authentication (JWT)

Dashboard and user management routes use JWT bearer tokens obtained via POST /api/v1/auth/login. Include the token in the Authorization header.

curl -H "Authorization: Bearer eyJhbGciOi..." \
  https://api.stradum.com/api/v1/dashboard/overview

Key management: Register an organization via POST /api/v1/auth/register to receive your initial publishable and secret key pair. You can generate additional key pairs and manage users from the Auth API.

POST /auth/register

Create a new organization and owner user. Returns the initial API key pair. No authentication required.

Request Body

FieldTypeDescription
org_namestringRequired. Organization display name.
emailstringRequired. Owner's email address.
passwordstringRequired. Owner's password.
curl -X POST https://api.stradum.com/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "org_name": "Acme Corp",
    "email": "admin@acme.com",
    "password": "secure_password_here"
  }'

Response 201

{
  "org_id": "org_a1b2c3d4",
  "user_id": "usr_x1y2z3",
  "email": "admin@acme.com",
  "publishable_key": "pk_live_abc123...",
  "secret_key": "sk_live_xyz789..."
}

Important: The secret_key is only shown once at creation time. Store it securely.

POST /auth/login

Authenticate with email and password to receive a JWT token for dashboard access.

Request Body

FieldTypeDescription
emailstringRequired. User email address.
passwordstringRequired. User password.
curl -X POST https://api.stradum.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{ "email": "admin@acme.com", "password": "secure_password_here" }'

Response 200

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user_id": "usr_x1y2z3",
  "org_id": "org_a1b2c3d4",
  "email": "admin@acme.com",
  "role": "owner"
}
GET /auth/me

Get the currently authenticated user. Requires JWT authentication.

curl https://api.stradum.com/api/v1/auth/me \
  -H "Authorization: Bearer eyJhbGciOi..."
POST /auth/keys

Generate a new API key pair for the organization. Requires JWT authentication with owner or admin role.

Request Body

FieldTypeDescription
labelstringRequired. Human-readable label for the key pair (e.g. "Production", "Staging").
curl -X POST https://api.stradum.com/api/v1/auth/keys \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{ "label": "Production" }'

Important: The secret_key is only returned once in this response. Store it securely — it cannot be retrieved again.

GET /auth/keys

List all API keys for the organization. Requires JWT authentication. Returns key metadata (prefix, label, created date) — secret keys are never returned.

curl https://api.stradum.com/api/v1/auth/keys \
  -H "Authorization: Bearer eyJhbGciOi..."
DELETE /auth/keys/{"{key_id}"}

Revoke an API key pair. Both the publishable and secret keys will immediately stop working. Requires JWT authentication with owner or admin role.

curl -X DELETE https://api.stradum.com/api/v1/auth/keys/key_abc123 \
  -H "Authorization: Bearer eyJhbGciOi..."
POST /auth/users

Invite a new user to the organization. Requires JWT authentication with owner or admin role.

Request Body

FieldTypeDescription
emailstringRequired. New user's email address.
passwordstringRequired. Initial password.
rolestringRequired. One of: owner, admin, viewer.
curl -X POST https://api.stradum.com/api/v1/auth/users \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "analyst@acme.com",
    "password": "initial_password",
    "role": "viewer"
  }'
GET /auth/users

List all users in the organization. Requires JWT authentication.

curl https://api.stradum.com/api/v1/auth/users \
  -H "Authorization: Bearer eyJhbGciOi..."
PATCH /auth/users/{"{user_id}"}

Update a user's role. Requires JWT authentication with owner or admin role.

Request Body

FieldTypeDescription
rolestringRequired. New role: owner, admin, or viewer.
curl -X PATCH https://api.stradum.com/api/v1/auth/users/usr_abc123 \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{ "role": "admin" }'
DELETE /auth/users/{"{user_id}"}

Remove a user from the organization. Requires JWT authentication with owner or admin role. Returns 204 No Content on success.

curl -X DELETE https://api.stradum.com/api/v1/auth/users/usr_abc123 \
  -H "Authorization: Bearer eyJhbGciOi..."

Sessions

POST /sessions

Initialize a new behavioral capture session. The SDK calls this automatically on init(), but you can also create sessions server-side. Requires X-Stradum-Key header with a publishable key (pk_live_) or secret key (sk_live_).

Request Body

FieldTypeDescription
session_idstring?Pre-generated ID. Auto-generated if omitted.
metadataobjectCustom key-value pairs (candidate_id, report_id, etc.)
device_infoobjectDevice fingerprint data from the SDK
curl -X POST https://api.stradum.com/api/v1/sessions \
  -H "Content-Type: application/json" \
  -H "X-Stradum-Key: pk_live_your_publishable_key" \
  -d '{
    "metadata": { "candidate_id": "c_abc123" },
    "device_info": { "platform": "MacIntel" }
  }'

Response 201

{
  "session_id": "stm_a1b2c3d4",
  "identity_id": null,
  "status": "active",
  "event_count": 0,
  "created_at": "2026-03-07T12:00:00Z",
  "metadata": { "candidate_id": "c_abc123" }
}
POST /sessions/events

Ingest a batch of behavioral events. The SDK sends these automatically — you typically don't call this directly. Requires X-Stradum-Key header with a publishable key.

Request Body

FieldTypeDescription
session_idstringRequired. The session to append events to.
eventsEventPayload[]1–5,000 events per batch
sdk_versionstring?SDK version string
page_urlstring?Page URL where events were captured

EventPayload

FieldTypeDescription
event_typestringEvent type (managed by SDK)
timestampfloatUnix timestamp in seconds with ms precision
field_namestring?Name of the form field (if applicable)
field_typestring?text_input, protected_input, dropdown, checkbox, radio, textarea, date_selector
dataobjectEvent-specific payload data

The SDK captures behavioral signals automatically. No configuration of event types is required.

Response 200

{
  "session_id": "stm_a1b2c3d4",
  "accepted": 45,
  "rejected": 0,
  "total_event_count": 245
}
POST /sessions/{"{session_id}"}/complete

Mark a session as completed. Typically called when the user submits the form. Optionally link to an identity and include field values. Requires X-Stradum-Key header with a publishable key (pk_live_) or secret key (sk_live_).

Request Body

FieldTypeDescription
identity_idstring?Link to identity at completion time
field_valuesobjectField name → submitted value map
metadataobjectAdditional metadata to merge
curl -X POST https://api.stradum.com/api/v1/sessions/ses_a1b2c3d4/complete \
  -H "Content-Type: application/json" \
  -H "X-Stradum-Key: pk_live_your_publishable_key" \
  -d '{
    "identity_id": "id_xyz789",
    "field_values": {
      "first_name": "John",
      "last_name": "Smith",
      "email": "john@example.com"
    }
  }'

Triggers a session.completed webhook if configured.

POST /sessions/{"{session_id}"}/metadata

Merge metadata into an active session at any time. Uses merge semantics — new keys are added, existing keys are overwritten. Call this whenever candidate_id, report_id, or other custom keys become available. Requires X-Stradum-Key header with a publishable key (pk_live_) or secret key (sk_live_).

curl -X POST https://api.stradum.com/api/v1/sessions/ses_a1b2c3d4/metadata \
  -H "Content-Type: application/json" \
  -H "X-Stradum-Key: pk_live_your_publishable_key" \
  -d '{ "metadata": { "candidate_id": "c_abc123", "report_id": "r_456" } }'

Also available via the SDK: Stradum.setMetadata({ candidate_id: 'c_abc123' })

GET /sessions

List sessions with optional filters. Supports filtering by identity, account, status, match status, metadata, and analysis category. Requires Authorization: Bearer <jwt> header.

Query Parameters

ParamTypeDescription
identity_idstringFilter by identity
account_idstringFilter by account
statusstringactive, completed, analyzed, abandoned, expired, rejected
match_statusstringmatch, review, mismatch
metadata_keystringFilter sessions that have this metadata key
metadata_valuestringExact match on metadata value (combine with metadata_key for key=value match)
categorystringFilter by analysis category
category_severitystringFilter by category severity
pageintPage number (default: 1)
page_sizeintResults per page (1–200, default: 50)
# Find sessions for a specific candidate
curl "https://api.stradum.com/api/v1/sessions?metadata_key=candidate_id&metadata_value=c_abc123" \
  -H "Authorization: Bearer eyJhbGciOi..."
GET /sessions/{"{session_id}"}

Retrieve a single session by ID. Returns the full SessionResponse. Requires Authorization: Bearer <jwt> header.

DELETE /sessions/{"{session_id}"}

Delete a session and all associated events. Returns 204 No Content on success. Requires Authorization: Bearer <jwt> header.

Identities

POST /identities

Create a new identity record. Identities represent individuals whose behavioral patterns are tracked across sessions. Requires X-Stradum-Key header with a secret key (sk_live_).

Request Body

FieldTypeDescription
external_idstring?Your internal user/person ID
account_idstring?Customer/employer account ID
account_namestring?Human-readable account name
account_uristring?Account URL or URI
metadataobjectCustom metadata
POST /identities/resolve?external_id={"{id}"}

Find or create an identity by your external ID. Idempotent — returns the existing identity if found, creates a new one if not. Use this when you know your internal user ID and want to ensure a Stradum identity exists for linking. Requires X-Stradum-Key header with a secret key (sk_live_).

curl -X POST "https://api.stradum.com/api/v1/identities/resolve?external_id=person_123" \
  -H "X-Stradum-Key: sk_live_your_secret_key"
GET /identities

List identities. Optionally filter by account_id. Supports pagination via page and page_size. Requires Authorization: Bearer <jwt> header.

GET /identities/{"{identity_id}"}

Retrieve a single identity by ID. Returns the full IdentityResponse. Requires Authorization: Bearer <jwt> header.

Accounts

GET /accounts

List all customer accounts. Each account includes session and identity counts. Requires Authorization: Bearer <jwt> header.

Response 200

{
  "accounts": [
    {
      "account_id": "acct_1",
      "account_name": "Acme Corp",
      "session_count": 342,
      "identity_count": 87
    }
  ],
  "total": 1
}

Analysis

POST /analysis/trigger

Trigger behavioral analysis for a completed session. The session must be completed and linked to an identity. Analysis runs synchronously and returns the score, match status, confidence, and reason codes. Requires X-Stradum-Key header with a secret key (sk_live_).

Prerequisites: Session must be in completed status and linked to an identity via /identities/link or the identity_id param on /sessions/{'{id}'}/complete.

Request Body

FieldTypeDescription
session_idstringRequired. The completed session to analyze.
identity_idstring?Override the session's linked identity
curl -X POST https://api.stradum.com/api/v1/analysis/trigger \
  -H "Content-Type: application/json" \
  -H "X-Stradum-Key: sk_live_your_secret_key" \
  -d '{ "session_id": "stm_a1b2c3d4" }'

Returns a ScoreResponse. Triggers analysis.completed and optionally signal.alert webhooks.

GET /analysis/session/{"{session_id}"}

Retrieve the stored analysis result for a session. Returns 404 if analysis hasn't been triggered yet. Requires X-Stradum-Key header with a secret key or Authorization: Bearer <jwt> header.

GET /analysis/identity/{"{identity_id}"}

Retrieve all analysis results for an identity. Returns an array of ScoreResponse objects. Requires X-Stradum-Key header with a secret key or Authorization: Bearer <jwt> header.

GET /analysis/session/{"{session_id}"}/score

Retrieve the public score for a previously analyzed session. Returns the score, match status, confidence, contributing signals, and human-readable reasons. Requires X-Stradum-Key header with a secret key (sk_live_) or Authorization: Bearer <jwt> header.

Response 200

{
  "session_id": "stm_a1b2c3d4",
  "identity_id": "id_xyz789",
  "analyzed_at": "2026-03-07T14:30:00Z",
  "result": {
    "score": 84.2,
    "match_status": "match",
    "confidence": 0.92
  },
  "signals": ["typing", "mouse", "navigation"],
  "reasons": [
    {
      "code": "typing_rhythm_match",
      "category": "typing",
      "severity": "none",
      "description": "Typing rhythm consistent with baseline"
    }
  ],
  "context": {
    "baseline_sessions": 5,
    "summary": "Behavioral patterns are consistent with the identity's established profile."
  }
}

See ScoreResponse schema for full field reference.

GET /sessions/{"{session_id}"}/timeline

Returns an abstracted field-level interaction timeline for a session. Provides a high-level view of how the user interacted with form fields, without exposing raw event data. Requires X-Stradum-Key header with a secret key (sk_live_) or Authorization: Bearer <jwt> header.

Response 200

{
  "session_id": "stm_a1b2c3d4",
  "duration_ms": 45230,
  "field_count": 4,
  "timeline": [
    {
      "field_name": "first_name",
      "field_type": "text_input",
      "focus_time_ms": 3200,
      "keystroke_count": 12,
      "paste_detected": false,
      "revisits": 0
    },
    {
      "field_name": "email",
      "field_type": "text_input",
      "focus_time_ms": 5100,
      "keystroke_count": 22,
      "paste_detected": false,
      "revisits": 1
    }
  ]
}

Dashboard

GET /dashboard/auth-check

Check whether dashboard authentication is required. No auth needed for this endpoint itself. Used by the frontend to determine whether to show the login gate.

Response 200

{ "auth_required": true }
GET /dashboard/overview

Dashboard landing page metrics. Returns total counts, today's activity, risk distribution, and recent sessions. Requires Authorization: Bearer <jwt> header.

Response 200

{
  "total_sessions": 1247,
  "total_identities": 342,
  "total_accounts": 5,
  "sessions_today": 47,
  "alerts_today": 3,
  "risk_distribution": { "match": 892, "review": 308, "mismatch": 47 },
  "recent_sessions": [ /* SessionResponse[] */ ]
}
GET /dashboard/identity/{"{identity_id}"}/profile

Retrieve the behavioral profile for an identity. Returns the profile summary and session history. Requires Authorization: Bearer <jwt> header.

GET /dashboard/alerts

List sessions that triggered a review or mismatch alert. Enriched with session and account context. Supports filtering by account_id and pagination. Requires Authorization: Bearer <jwt> header.

Webhooks

Webhook Events

session.completed Fired when a session is marked as completed. Payload includes the full session object.
analysis.completed Fired when analysis finishes for a session. Payload includes the full analysis result.
signal.alert Fired when analysis produces a match score below the match threshold. Replaces analysis.completed for that webhook.

If a secret is configured, payloads include an X-Stradum-Signature header with an HMAC-SHA256 signature for verification.

POST /webhooks

Register a new webhook endpoint. Requires X-Stradum-Key header with a secret key (sk_live_).

Request Body

FieldTypeDescription
urlstringRequired. HTTPS endpoint URL to receive events.
eventsstring[]Required. Array of event types to subscribe to.
secretstring?Shared secret for HMAC-SHA256 signing
curl -X POST https://api.stradum.com/api/v1/webhooks \
  -H "Content-Type: application/json" \
  -H "X-Stradum-Key: sk_live_your_secret_key" \
  -d '{
    "url": "https://your-server.com/webhooks/stradum",
    "events": ["session.completed", "analysis.completed", "signal.alert"],
    "secret": "whsec_your_signing_secret"
  }'
GET /webhooks

List all configured webhooks. Returns webhook IDs, URLs, subscribed events, and active status. Requires X-Stradum-Key header with a secret key (sk_live_).

DELETE /webhooks/{"{webhook_id}"}

Delete a webhook configuration. Returns 204 No Content on success. Requires X-Stradum-Key header with a secret key (sk_live_).

Schema Reference

SessionResponse

FieldTypeDescription
session_idstringUnique session identifier
identity_idstring?Linked identity ID (null if unlinked)
account_idstring?Associated account ID
account_namestring?Human-readable account name
statusstringactive, completed, analyzed, abandoned, expired, rejected
match_statusstring?match, review, mismatch
match_scorefloat?Similarity score 0–100 (higher = more similar)
created_atdatetimeSession creation timestamp
updated_atdatetimeLast update timestamp
completed_atdatetime?Completion timestamp
event_countintTotal ingested events
metadataobjectCustom key-value metadata
device_infoobjectDevice fingerprint data
field_valuesobjectSubmitted field name → value map

IdentityResponse

FieldTypeDescription
identity_idstringStradum identity ID
external_idstring?Your internal user/person ID
account_idsstring[]Associated account IDs
created_atdatetimeIdentity creation timestamp
session_countintNumber of linked sessions
metadataobjectCustom metadata

ScoreResponse

Returned by GET /analysis/session/{session_id}/score and POST /analysis/trigger.

FieldTypeDescription
session_idstringAnalyzed session
identity_idstringIdentity used for baseline
analyzed_atdatetimeAnalysis timestamp
result.scorefloatSimilarity score 0–100 (72+ = match, 40–72 = review, <40 = mismatch)
result.match_statusstringmatch, review, or mismatch
result.confidencefloatConfidence level 0.0–1.0 (grows with more baseline sessions)
signalsstring[]High-level behavioral signal categories that contributed to the score
reasonsReason[]Human-readable explanations for the score
context.baseline_sessionsintNumber of prior sessions in the baseline
context.summarystringHuman-readable analysis summary

Reason

FieldTypeDescription
codestringMachine-readable reason code
categorystringBehavioral category (e.g. typing, mouse, navigation)
severitystringnone, mild, moderate, severe
descriptionstringHuman-readable explanation

AlertItem

FieldTypeDescription
analysis_idstringAnalysis that triggered the alert
session_idstringFlagged session
identity_idstringIdentity involved
account_idstring?Associated account
account_namestring?Account name
analyzed_atdatetimeWhen analysis ran
match_scorefloatSimilarity score
match_statusstringreview or mismatch
confidencefloatConfidence level
summarystringHuman-readable alert summary
reasonsReason[]What triggered the alert
session_created_atdatetime?When the session started
event_countintSession event count

WebhookResponse

FieldTypeDescription
webhook_idstringUnique webhook ID
urlstringDelivery endpoint URL
eventsstring[]Subscribed event types
activebooleanWhether the webhook is active
created_atdatetimeRegistration timestamp

Changelog

A running log of new features, improvements, and fixes shipped to the Stradum platform.

March 9, 2026 Latest
  • +Scoring engine calibration — variance floor, dynamic z-score thresholds, baseline-aware match status classification, and volatile signal downweighting eliminate false positives during early baseline building
  • +Absolute red-flag detection — paste into identity fields, automation signals, and window-switching patterns override lenient early-session thresholds
  • +Match statuses simplified to three: match, review, mismatch
  • +New /score and /detail endpoints with five signal categories and plain-language reason codes
  • +Session Timeline replaces raw event replay — abstracted, server-rendered visualization
  • +Four-tier authentication model — Public, SDK Key (pk_live_), Server Key (sk_live_), Superadmin JWT
  • +IP protection overhaul — raw events, feature vectors, and internal data removed from all customer-facing endpoints
  • +MCP Server section added to API documentation with setup instructions
  • +Downloadable OpenAPI 3.0.3 spec and Postman collection
  • +Graduated usage-based pricing with volume discounts, interactive cost calculator, and optional add-ons
  • +30-day free pilot with all features unlocked (up to 1,500 sessions)
  • ~API header renamed from X-BS-Key to X-Stradum-Key
  • ~Environment variable prefix changed from BS_ to STM_
  • ~Entity IDs now prefixed with stm_ (sessions, identities, analyses)
  • ~Confidence score now honestly reflects baseline depth (0.30 at baseline 0 → 0.90 at baseline 6+)
  • !Removed unauthenticated "open mode" fallback — all endpoints now require at minimum a publishable key
  • !Removed raw event replay endpoint from customer-facing API
March 7, 2026
  • +Quick Start integration guide on the Settings page with auto-populated API keys
  • +Publishable API keys are now fully visible and copyable in the dashboard
  • +Background session auto-expiry — stale active sessions are automatically expired after 30 min idle or 60 min total
  • +Match score now displayed inline next to the match status badge across all views
  • +Changelog section added to API documentation
March 5, 2026
  • +Multi-tenant architecture with organization-scoped data isolation
  • +Publishable & secret API key pairs for SDK and server-to-server auth
  • +JWT-based dashboard authentication replacing legacy admin key
  • +10 new /api/v1/auth/* endpoints — register, login, key management, team management
  • +Settings page with API key management and team member controls
  • ~SDK updated to send X-Stradum-Key header — SDK v1.1.0
  • +Migration script for existing single-tenant deployments
March 3, 2026
  • +Marketing landing page and comprehensive API documentation site
  • +Dashboard deployed as standalone Railway service
  • +Dashboard admin key gate and session-based logout
  • +Fixed sidebar layout — non-scrolling, persistent navigation
  • ~CORS configuration updated for multi-service architecture
  • ~OPTIONS preflight requests now bypass auth middleware
  • !Fixed SDK bundle blocked by dashboard auth middleware
February 2026
  • +Initial release — API v1, SDK v1.0.0
  • +Session lifecycle — create, ingest events, complete
  • +Identity resolution and cross-session linking
  • +Behavioral analysis engine with scoring and behavioral assessment
  • +Real-time webhook delivery for analysis events
  • +JavaScript SDK with automatic form instrumentation
  • +React dashboard with session explorer, alerts, and identity profiles
  • +PostgreSQL and in-memory storage backends
+ New feature ~ Improvement ! Bug fix