This file is generated from FastAPI OpenAPI metadata via python scripts/generate_api_docs.py.
Base URL:
http://127.0.0.1:8008
Health
curl http://127.0.0.1:8008/healthReadyz
curl http://127.0.0.1:8008/readyzDiagnostics
curl http://127.0.0.1:8008/api/v1/diagnosticsGet Audit Log
curl "http://127.0.0.1:8008/api/v1/audit?action=api_key_used" ^
-H "X-API-Key: YOUR_READ_OR_WRITE_KEY"Export Audit Log
curl "http://127.0.0.1:8008/api/v1/audit/export?action=api_key_created" ^
-H "X-API-Key: YOUR_WRITE_KEY"Analyze
curl -X POST http://127.0.0.1:8008/api/v1/analyze ^
-H "Content-Type: application/json" ^
-d @docs/demo/sample-project.jsonCalculate
curl -X POST http://127.0.0.1:8008/api/v1/calculate ^
-H "Content-Type: application/json" ^
-d "{\"metric_type\":\"binary\",\"baseline_value\":0.042,\"mde_pct\":5,\"alpha\":0.05,\"power\":0.8,\"expected_daily_traffic\":12000,\"audience_share_in_test\":0.6,\"traffic_split\":[50,50],\"variants_count\":2}"Design
Llm Advice
List Api Keys
curl http://127.0.0.1:8008/api/v1/keys ^
-H "Authorization: Bearer YOUR_AB_ADMIN_TOKEN"Create Api Key
curl -X POST http://127.0.0.1:8008/api/v1/keys ^
-H "Authorization: Bearer YOUR_AB_ADMIN_TOKEN" ^
-H "Content-Type: application/json" ^
-d "{\"name\":\"Partner read key\",\"scope\":\"read\",\"rate_limit_requests\":60,\"rate_limit_window_seconds\":60}"Delete Api Key
curl -X DELETE http://127.0.0.1:8008/api/v1/keys/KEY_ID ^
-H "Authorization: Bearer YOUR_AB_ADMIN_TOKEN"Revoke Api Key
curl -X POST http://127.0.0.1:8008/api/v1/keys/KEY_ID/revoke ^
-H "Authorization: Bearer YOUR_AB_ADMIN_TOKEN"List Projects
curl http://127.0.0.1:8008/api/v1/projectsCreate Project
curl http://127.0.0.1:8008/api/v1/projectsDelete Project
Get Project
Update Project
Record Project Analysis
Record Project Export
Get Project History
curl "http://127.0.0.1:8008/api/v1/projects/PROJECT_ID/history?analysis_limit=5&export_limit=5"Restore Project
curl -X POST http://127.0.0.1:8008/api/v1/projects/PROJECT_ID/restoreGet Project Revisions
curl "http://127.0.0.1:8008/api/v1/projects/PROJECT_ID/revisions?limit=5"Compare Projects
curl "http://127.0.0.1:8008/api/v1/projects/compare?base_id=BASE&candidate_id=CANDIDATE"Compare Multiple Projects
curl "http://127.0.0.1:8008/api/v1/projects/compare?base_id=BASE&candidate_id=CANDIDATE"Export Workspace
curl http://127.0.0.1:8008/api/v1/workspace/exportImport Workspace
curl -X POST http://127.0.0.1:8008/api/v1/workspace/import ^
-H "Content-Type: application/json" ^
-d @workspace-backup.jsonValidate Workspace
curl -X POST http://127.0.0.1:8008/api/v1/workspace/validate ^
-H "Content-Type: application/json" ^
-d @workspace-backup.jsonExport Html
Export Markdown
curl -X POST http://127.0.0.1:8008/api/v1/export/markdown ^
-H "Content-Type: application/json" ^
-d @report.jsonAssignment Preview
Assign Experiment
Ingest Conversions
Get Decision
Decision Readout — one synthesized ship / no-ship / keep-running verdict over the same live-stats signals (SRM, frequentist effect/CI, Bayesian P(B>A), sequential crossing). No new statistics; see services/decision_service.py.
Ingest Exclusions
Ingest manual deny-list exclusions for the bot / fraud filter (P4.4). First-write-wins per user (the first reason sticks); the live-stats rollup drops excluded users — resolved to their canonical id — from every aggregate, alongside the automatic rate-spike heuristic. The raw events are never deleted, so an exclusion is a reversible read-time filter.
Ingest Exposures
Ingest Holdout
Ingest holdout members — users held back from the rollout (F5). Recorded as
variation_index = -1 exposures (first-write-wins per user); the live-stats read compares
the pooled treated arms against this held-back group to measure the rollout's cumulative
effect. Holdout outcomes ride the ordinary conversion stream under the primary metric name.
Ingest Identities
Ingest anonymous → canonical identity links (P4.3). First-write-wins per anonymous id; the live-stats rollup folds each user's exposures and conversions onto their canonical id, so a person exposed while anonymous and re-exposed / converting after login is counted once instead of inflating SRM and the conversion rate. A self-link is a no-op and is skipped.
Get Ingestion Summary
Get Live Stats
Phase D — live SRM / frequentist / Bayesian / sequential read over the current deduplicated exposures and conversions. Recomputed on demand (the dashboard polls); there is no separate scheduler process in the local-first MVP.
Ingest Pre Period Values
Ingest per-user pre-experiment covariate values for CUPED (E5). First-write-wins per user; the covariate enables variance reduction on the continuous live-stats.
Ingest Strata
Ingest one categorical stratum per user for post-stratification (F3b). First-write-wins per user; the stratum lets the live-stats read estimate the effect within each stratum and recombine it, reducing variance when the stratum explains outcome variation.
Export Comparison
Export Html Standalone
Generate Hypotheses
Multiple Testing
Archive Project
Get Project Report Csv
Get Project Report Pdf
Get Project Report Xlsx
Results
Categorical Results
Sensitivity
Simulate Bandit
Slack Status
Srm Check
List Templates
Create Template
Delete Template
Get Template
Use Template
List Webhooks
Create Webhook
Delete Webhook
Get Webhook
Update Webhook
List Webhook Deliveries
Test Webhook
Slack Commands
Slack Events
Slack Install
Slack Interactive
Slack Oauth Callback
- supported variant count is
2..10 - binary baselines must be between
0and1 - continuous metrics require positive
baseline_valueandstd_dev traffic_splitlength must matchvariants_count- malformed request bodies return
422 - domain errors return structured
400 - when
AB_API_TOKEN,AB_READONLY_API_TOKEN, or database-backed API keys are configured, protected runtime routes still acceptAuthorization: BearerorX-API-Key /docs,/redoc, and/openapi.jsonremain public even when auth is enabled; only protected API routes and/readyzrequire a tokenAB_READONLY_API_TOKENis valid only forGET,HEAD, andOPTIONS; mutating routes still requireAB_API_TOKEN/api/v1/keys*requiresAB_ADMIN_TOKEN; without it the key-management endpoints return401- database-backed API keys are stored as SHA-256 hashes, the plaintext secret is returned only once at creation time, and revoked keys are rejected
- per-key rate-limit overrides apply only to requests authenticated with a database API key; legacy shared tokens continue to use the global limiter
- all API responses include
X-Request-IDandX-Process-Time-Msheaders - error responses also include
error_code,status_code,request_id, andX-Error-Code - diagnostics expose in-memory runtime counters plus the active guardrail configuration for security headers, rate limiting, auth throttling, and request-body limits
GET /readyzreturns503when required runtime dependencies are degraded
- TypeScript contracts:
python scripts/generate_frontend_api_types.py - API docs markdown:
python scripts/generate_api_docs.py