CRO PlatformAI-Native CRO OS
Toggle navigationMenu

API Reference

44 endpoints across 3 categories — every public HTTP endpoint exposed by the platform, with query parameters, response shape, and an example payload. Hand-curated; not auto-generated from route handlers.

Total

44

GET

42

POST

2

Read

35

Export

7

Admin

2

Read APIs

Read-only endpoints powering consoles, dashboards, and listings.

35 endpoints
GET/api/provenanceTry it →

Recent provenance events across the platform, newest first.

Query parameters

NameTypeRequiredDescriptionExample
limitnumberoptionalMax events to return (1-200).50
agentstringoptionalFilter to a single agent id.30-knowledge-rag
studystringoptionalFilter to a single study id.

Response shape

{ events: Array<{ id: string; agent_id: string; action: string; study_id: string | null; created_at: string; provenance_hash: string }>; total: number }

Example response

{
"events": [
{
"id": "pe_01HZX7ABCD",
"agent_id": "30-knowledge-rag",
"action": "draft_protocol_amendment",
"study_id": "STU-204",
"created_at": "2026-06-05T14:22:01.000Z",
"provenance_hash": "sha256:9f1c..."
}
],
"total": 1
}
GET/api/staging/scorecardsAuthTry it →

Per-record review scorecards for the staging queue.

Query parameters

NameTypeRequiredDescriptionExample
studystringoptionalFilter to a study.
status"pending"|"signed"|"rejected"optionalFilter by lifecycle state.pending

Response shape

{ scorecards: Array<{ record_id: string; agent_id: string; risk_score: number; citation_count: number; status: string }> }

Example response

{
"scorecards": [
{
"record_id": "sr_01HZX9",
"agent_id": "04-essential-documents",
"risk_score": 0.18,
"citation_count": 4,
"status": "pending"
}
]
}
GET/api/crons/statusTry it →

Latest run + next-run estimate for every scheduled cron job.

Query parameters

None.

Response shape

{ crons: Array<{ name: string; last_run_at: string | null; next_run_at: string | null; last_status: "ok"|"error"|"running" }> }

Example response

{
"crons": [
{
"name": "rollup-cost-meter",
"last_run_at": "2026-06-05T14:00:00.000Z",
"next_run_at": "2026-06-05T15:00:00.000Z",
"last_status": "ok"
}
]
}
GET/api/cost-meter60 req/min/ipTry it →

Aggregate token + dollar spend across all agents for a window.

Query parameters

NameTypeRequiredDescriptionExample
window"24h"|"7d"|"30d"optionalRolling window for the rollup.24h

Response shape

{ window: string; tokens_in: number; tokens_out: number; usd_total: number; per_model: Record<string, { tokens: number; usd: number }> }

Example response

{
"window": "24h",
"tokens_in": 1284032,
"tokens_out": 318411,
"usd_total": 42.91,
"per_model": {
"claude-sonnet-4-7": { "tokens": 1041000, "usd": 30.12 }
}
}
GET/api/cost-meter/trendTry it →

Hourly cost samples for a sparkline chart.

Query parameters

NameTypeRequiredDescriptionExample
hoursnumberoptionalNumber of hourly buckets (1-168).24

Response shape

{ points: Array<{ bucket_at: string; usd: number; tokens: number }> }

Example response

{
"points": [
{ "bucket_at": "2026-06-05T13:00:00.000Z", "usd": 1.82, "tokens": 51200 },
{ "bucket_at": "2026-06-05T14:00:00.000Z", "usd": 2.04, "tokens": 58110 }
]
}
GET/api/agents/leaderboardTry it →

Top agents by activity, success rate, or cost.

Query parameters

NameTypeRequiredDescriptionExample
sort"activity"|"success"|"cost"optionalSort key.activity
limitnumberoptionalMax rows (1-50).10

Response shape

{ rows: Array<{ agent_id: string; name: string; runs: number; success_rate: number; usd_total: number }> }

Example response

{
"rows": [
{ "agent_id": "30-knowledge-rag", "name": "Knowledge RAG", "runs": 412, "success_rate": 0.97, "usd_total": 12.41 }
]
}
GET/api/agents/[id]/activityTry it →

Recent activity timeline for a single agent.

Query parameters

NameTypeRequiredDescriptionExample
limitnumberoptionalMax items (1-200).20

Response shape

{ agent_id: string; events: Array<{ id: string; action: string; study_id: string | null; created_at: string }> }

Example response

{
"agent_id": "30-knowledge-rag",
"events": [
{ "id": "pe_01HZX7", "action": "draft_protocol_amendment", "study_id": "STU-204", "created_at": "2026-06-05T14:22:01.000Z" }
]
}
GET/api/agents/[id]/dossierTry it →

Credibility dossier: prompt versions, evals, model bindings.

Query parameters

None.

Response shape

{ agent_id: string; current_prompt_version: string; model_id: string; eval_score: number; eval_count: number; last_changed_at: string }

Example response

{
"agent_id": "30-knowledge-rag",
"current_prompt_version": "v17",
"model_id": "claude-sonnet-4-7",
"eval_score": 0.94,
"eval_count": 32,
"last_changed_at": "2026-05-28T09:11:00.000Z"
}
GET/api/agents/[id]/costsTry it →

Token and dollar spend rollup for a single agent.

Query parameters

NameTypeRequiredDescriptionExample
window"24h"|"7d"|"30d"optionalRolling window.7d

Response shape

{ agent_id: string; window: string; tokens: number; usd: number; runs: number }

Example response

{
"agent_id": "30-knowledge-rag",
"window": "7d",
"tokens": 312041,
"usd": 9.42,
"runs": 87
}
GET/api/agents/compareTry it →

Side-by-side comparison of two or more agents.

Query parameters

NameTypeRequiredDescriptionExample
idsstring (comma-separated)requiredAgent ids to compare.30-knowledge-rag,31-evaluation

Response shape

{ agents: Array<{ agent_id: string; name: string; eval_score: number; runs: number; usd_total: number }> }

Example response

{
"agents": [
{ "agent_id": "30-knowledge-rag", "name": "Knowledge RAG", "eval_score": 0.94, "runs": 412, "usd_total": 12.41 },
{ "agent_id": "31-evaluation", "name": "Evaluation", "eval_score": 0.91, "runs": 305, "usd_total": 8.10 }
]
}
GET/api/studies/activityTry it →

Cross-study activity rollup, newest first.

Query parameters

NameTypeRequiredDescriptionExample
limitnumberoptionalMax rows (1-100).25

Response shape

{ studies: Array<{ study_id: string; protocol: string; last_event_at: string; pending_reviews: number }> }

Example response

{
"studies": [
{ "study_id": "STU-204", "protocol": "ACME-PRO-204", "last_event_at": "2026-06-05T14:22:01.000Z", "pending_reviews": 3 }
]
}
GET/api/studies/[id]/snapshotTry it →

Snapshot view of one study: state, agents, pending reviews.

Query parameters

None.

Response shape

{ study_id: string; protocol: string; phase: string; status: string; agents_active: string[]; pending_reviews: number }

Example response

{
"study_id": "STU-204",
"protocol": "ACME-PRO-204",
"phase": "II",
"status": "active",
"agents_active": ["30-knowledge-rag", "27-audit-trail"],
"pending_reviews": 3
}
GET/api/timelineTry it →

Cross-agent activity timeline for the operations console.

Query parameters

NameTypeRequiredDescriptionExample
fromstring (ISO timestamp)optionalStart of window.2026-06-04T00:00:00Z
tostring (ISO timestamp)optionalEnd of window.
limitnumberoptionalMax events (1-500).

Response shape

{ events: Array<{ id: string; agent_id: string; action: string; study_id: string | null; created_at: string }> }

Example response

{
"events": [
{ "id": "pe_01HZX7", "agent_id": "30-knowledge-rag", "action": "draft", "study_id": "STU-204", "created_at": "2026-06-05T14:22:01.000Z" }
]
}
GET/api/heatmapTry it →

Agent x hour activity heatmap data for the last N days.

Query parameters

NameTypeRequiredDescriptionExample
daysnumberoptionalLookback window in days (1-30).7

Response shape

{ cells: Array<{ agent_id: string; hour: number; runs: number }> }

Example response

{
"cells": [
{ "agent_id": "30-knowledge-rag", "hour": 14, "runs": 12 },
{ "agent_id": "30-knowledge-rag", "hour": 15, "runs": 9 }
]
}
GET/api/risksTry it →

Risk register entries with mitigation status.

Query parameters

NameTypeRequiredDescriptionExample
severity"low"|"med"|"high"optionalFilter by severity.high

Response shape

{ risks: Array<{ id: string; title: string; severity: string; mitigation: string; owner: string }> }

Example response

{
"risks": [
{ "id": "RSK-12", "title": "PHI in agent prompt", "severity": "high", "mitigation": "Redaction filter pre-prompt", "owner": "security" }
]
}
GET/api/portalAuthTry it →

Sponsor portal home payload — open requests, recent signatures.

Query parameters

None.

Response shape

{ open_requests: number; recent_signatures: Array<{ id: string; subject: string; signed_at: string }> }

Example response

{
"open_requests": 1,
"recent_signatures": [
{ "id": "sig_01HZ", "subject": "Protocol amendment v2", "signed_at": "2026-06-04T16:00:00.000Z" }
]
}
GET/api/costsTry it →

Top-level cost analytics across agents and models.

Query parameters

NameTypeRequiredDescriptionExample
window"24h"|"7d"|"30d"optionalRolling window.30d

Response shape

{ window: string; usd_total: number; by_agent: Record<string, number>; by_model: Record<string, number> }

Example response

{
"window": "30d",
"usd_total": 1284.41,
"by_agent": { "30-knowledge-rag": 412.10 },
"by_model": { "claude-sonnet-4-7": 1020.30 }
}
GET/api/validationTry it →

CSV/CSA validation reports and qualification evidence summary.

Query parameters

None.

Response shape

{ reports: Array<{ id: string; title: string; status: "passed"|"failed"|"pending"; updated_at: string }> }

Example response

{
"reports": [
{ "id": "VAL-204-IQ", "title": "Installation Qualification", "status": "passed", "updated_at": "2026-06-01T09:00:00.000Z" }
]
}
GET/api/complianceTry it →

Part 11 + ALCOA+ live compliance posture.

Query parameters

None.

Response shape

{ signatures_24h: number; staging_pending: number; alcoa: Record<string, "ok"|"warn"|"fail"> }

Example response

{
"signatures_24h": 18,
"staging_pending": 4,
"alcoa": {
"A": "ok", "L": "ok", "C": "ok", "O": "ok", "A2": "ok",
"Complete": "ok", "Consistent": "ok", "Enduring": "ok", "Available": "ok"
}
}
GET/api/digestTry it →

Daily morning brief — last 24h activity rollup.

Query parameters

NameTypeRequiredDescriptionExample
datestring (YYYY-MM-DD)optionalSpecific day to fetch.2026-06-05

Response shape

{ date: string; sections: Array<{ title: string; bullets: string[] }> }

Example response

{
"date": "2026-06-05",
"sections": [
{ "title": "Signatures", "bullets": ["18 protocol amendments signed", "0 deviations"] }
]
}
GET/api/notificationsAuthTry it →

Unified notifications feed for the current user.

Query parameters

NameTypeRequiredDescriptionExample
unreadbooleanoptionalRestrict to unread items.true
limitnumberoptionalMax items (1-100).

Response shape

{ items: Array<{ id: string; kind: string; title: string; created_at: string; read: boolean }> }

Example response

{
"items": [
{ "id": "n_01HZ", "kind": "review_requested", "title": "Review STU-204 amendment", "created_at": "2026-06-05T14:00:00.000Z", "read": false }
]
}
POST/api/audit/queryAuthTry it →

Run a structured audit query against the provenance spine.

Query parameters

NameTypeRequiredDescriptionExample
format"json"|"sql"optionalReturn matching events or the SQL predicate.json

Response shape

{ sql: string; rows: Array<{ id: string; agent_id: string; action: string; created_at: string }>; total: number }

Example response

{
"sql": "SELECT * FROM cro.provenance_event WHERE agent_id = $1 AND created_at >= $2",
"rows": [
{ "id": "pe_01HZX7", "agent_id": "30-knowledge-rag", "action": "draft", "created_at": "2026-06-05T14:22:01.000Z" }
],
"total": 1
}
GET/api/audit/dailyTry it →

Per-day rollup of audit events for a window.

Query parameters

NameTypeRequiredDescriptionExample
daysnumberoptionalLookback in days (1-90).14

Response shape

{ days: Array<{ date: string; event_count: number; signature_count: number }> }

Example response

{
"days": [
{ "date": "2026-06-04", "event_count": 412, "signature_count": 18 },
{ "date": "2026-06-05", "event_count": 380, "signature_count": 22 }
]
}
GET/api/audit/sankeyTry it →

Sankey-diagram-shaped flow data: agent then action then study.

Query parameters

NameTypeRequiredDescriptionExample
daysnumberoptionalWindow length in days.7

Response shape

{ nodes: Array<{ id: string; label: string }>; links: Array<{ source: string; target: string; value: number }> }

Example response

{
"nodes": [
{ "id": "agent:30-knowledge-rag", "label": "Knowledge RAG" },
{ "id": "action:draft", "label": "draft" }
],
"links": [
{ "source": "agent:30-knowledge-rag", "target": "action:draft", "value": 87 }
]
}
GET/api/ops-healthTry it →

Operational health: crons, endpoints, Supabase, SLO posture.

Query parameters

None.

Response shape

{ supabase: "ok"|"degraded"|"down"; crons_ok: number; crons_failing: number; slo_compliance: number }

Example response

{
"supabase": "ok",
"crons_ok": 12,
"crons_failing": 0,
"slo_compliance": 0.998
}
GET/api/status120 req/min/ipTry it →

Lightweight health check used by uptime monitors.

Query parameters

None.

Response shape

{ status: "ok"; version: string; ts: string }

Example response

{
"status": "ok",
"version": "1.42.0",
"ts": "2026-06-05T14:30:00.000Z"
}
GET/api/flagsTry it →

Current feature-flag state catalog.

Query parameters

None.

Response shape

{ flags: Array<{ id: string; enabled: boolean; owner: string; last_toggled_at: string }> }

Example response

{
"flags": [
{ "id": "agent-04-essential-documents", "enabled": true, "owner": "platform", "last_toggled_at": "2026-05-12T10:00:00.000Z" }
]
}
GET/api/dependenciesTry it →

Software bill of materials in JSON.

Query parameters

NameTypeRequiredDescriptionExample
categorystringoptionalFilter by dependency category.framework

Response shape

{ dependencies: Array<{ id: string; name: string; version: string; license: string; risk_class: string }> }

Example response

{
"dependencies": [
{ "id": "nextjs", "name": "Next.js", "version": "15.0.0", "license": "MIT", "risk_class": "low" }
]
}
GET/api/modelsTry it →

Model registry: pinned model IDs and per-agent assignments.

Query parameters

None.

Response shape

{ models: Array<{ model_id: string; provider: string; pinned_at: string; bound_agents: string[] }> }

Example response

{
"models": [
{ "model_id": "claude-sonnet-4-7", "provider": "anthropic", "pinned_at": "2026-05-01T00:00:00.000Z", "bound_agents": ["30-knowledge-rag", "27-audit-trail"] }
]
}
GET/api/meAuthTry it →

Current authenticated user identity and preferences.

Query parameters

None.

Response shape

{ user_id: string; email: string; role: string; mfa_enrolled: boolean; preferences: Record<string, unknown> }

Example response

{
"user_id": "user_77",
"email": "qa.lead@example.com",
"role": "qa_lead",
"mfa_enrolled": true,
"preferences": { "theme": "light" }
}
GET/api/reports/[study]AuthTry it →

Generated report bundle for a single study.

Query parameters

NameTypeRequiredDescriptionExample
kind"summary"|"safety"|"deviation"optionalWhich report flavor to return.summary

Response shape

{ study_id: string; kind: string; generated_at: string; sections: Array<{ title: string; body: string }> }

Example response

{
"study_id": "STU-204",
"kind": "summary",
"generated_at": "2026-06-05T14:30:00.000Z",
"sections": [
{ "title": "Enrollment", "body": "42 subjects screened, 28 randomized." }
]
}

Export APIs

Bulk evidence downloads (CSV / JSON) for inspector handoff.

7 endpoints
GET/api/exports/agents.csvTry it →

CSV download of the full agent catalog.

Query parameters

None.

Response shape

text/csv stream — header row + one row per agent

Example response

agent_id,name,layer,model_id,eval_score
30-knowledge-rag,Knowledge RAG,L3,claude-sonnet-4-7,0.94
GET/api/exports/audit.jsonTry it →

Audit trail JSON bundle for a window.

Query parameters

NameTypeRequiredDescriptionExample
fromstring (ISO timestamp)optionalStart of export window.
tostring (ISO timestamp)optionalEnd of export window.

Response shape

{ exported_at: string; events: Array<{ id: string; agent_id: string; action: string; created_at: string; provenance_hash: string }> }

Example response

{
"exported_at": "2026-06-05T14:30:00.000Z",
"events": [
{ "id": "pe_01HZX7", "agent_id": "30-knowledge-rag", "action": "draft", "created_at": "2026-06-05T14:22:01.000Z", "provenance_hash": "sha256:9f1c..." }
]
}
GET/api/exports/cron-history.csvTry it →

CSV history of every scheduled cron run.

Query parameters

NameTypeRequiredDescriptionExample
daysnumberoptionalLookback window in days.30

Response shape

text/csv stream — header row + one row per run

Example response

name,started_at,finished_at,status
rollup-cost-meter,2026-06-05T14:00:00Z,2026-06-05T14:00:03Z,ok
GET/api/exports/models.csvTry it →

CSV of the model registry — pinned model ids and assignments.

Query parameters

None.

Response shape

text/csv stream — header row + one row per model registry version

Example response

model_id,provider,bound_agents,pinned_at
claude-sonnet-4-7,anthropic,30-knowledge-rag,2026-05-01
GET/api/exports/provenance.csvTry it →

CSV of the provenance event spine for a window.

Query parameters

NameTypeRequiredDescriptionExample
fromstring (ISO timestamp)optionalStart of window.
tostring (ISO timestamp)optionalEnd of window.

Response shape

text/csv stream — header row + one row per event

Example response

id,agent_id,action,study_id,created_at,provenance_hash
pe_01HZX7,30-knowledge-rag,draft,STU-204,2026-06-05T14:22:01Z,sha256:9f1c
GET/api/exports/signatures.csvAuthTry it →

CSV of every Part 11 e-signature row in the window.

Query parameters

NameTypeRequiredDescriptionExample
fromstring (ISO timestamp)optionalStart of window.
tostring (ISO timestamp)optionalEnd of window.

Response shape

text/csv stream — header row + one row per signature

Example response

id,user_id,record_id,intent,signed_at
sig_01HZ,user_77,sr_01HZX9,Approve protocol amendment,2026-06-05T14:25:00Z
GET/api/exports/sponsor-requests.csvAuthTry it →

CSV of sponsor portal requests for an audit handoff.

Query parameters

None.

Response shape

text/csv stream — header row + one row per request

Example response

id,sponsor,subject,status,created_at
req_01HZX8,Acme Therapeutics,Protocol amendment v3,in_review,2026-06-05T11:02:00Z

Admin APIs

Operator-only endpoints — gated behind admin role + MFA.

2 endpoints
POST/api/admin/seedAuth1 req/min/userTry it →

Seed the database with demo fixtures (admin only).

Query parameters

NameTypeRequiredDescriptionExample
resetbooleanoptionalTruncate demo rows first.false

Response shape

{ inserted: number; skipped: number; duration_ms: number }

Example response

{
"inserted": 412,
"skipped": 0,
"duration_ms": 1842
}
GET/api/admin/envAuthTry it →

Redacted environment variable catalog (admin only).

Query parameters

None.

Response shape

{ vars: Array<{ name: string; present: boolean; preview: string | null }> }

Example response

{
"vars": [
{ "name": "ANTHROPIC_API_KEY", "present": true, "preview": "sk-...cd12" },
{ "name": "SUPABASE_URL", "present": true, "preview": "https://clkifpedvomnpgajdsid..." }
]
}