A UI-first API contract visualization tool that reconciles what your frontend intends, what your backend implements, and what actually happens at runtime.
Cohesion shows the truth at your system boundaries — not what your docs claim, but what your code and traffic actually do.
- What This Project Does
- Repository Map
- Architecture
- Schema IR
- Static Analysis
- Diff Engine
- Live Capture
- Dual Sources & Reverse Proxy
- Live Diff
- Live Handshake
- GitHub App Integration
- Frontend UI
- API Reference
- Local Development
- Extending the System
Cohesion is a schema aggregation and analysis engine. It collects API contract information from three independent sources and surfaces every mismatch between them:
| Source | How it works | What it represents |
|---|---|---|
| Backend Static | AST / AI analysis of server code | What the backend serves and expects |
| Frontend Static | AST / AI analysis of client code | What the frontend sends and expects |
| Runtime Observed | Live traffic capture + inference | What actually happens at runtime |
Every source produces the same language-agnostic Schema IR. The diff engine compares them field-by-field and the UI renders the results as interactive visualizations.
cohesion-app/
├── cohesion_backend/ Go control plane, diff engine, live capture, reverse proxy
│ ├── cmd/server/ Entry point
│ ├── internal/
│ │ ├── controlplane/ Chi router + HTTP handlers (incl. GitHub App webhooks)
│ │ ├── crypto/ AES-256-GCM encryption for stored secrets
│ │ ├── services/ Live service, diff service, schema service, GitHub installation service
│ │ ├── repository/ PostgreSQL repositories
│ │ └── models/ Database models
│ ├── pkg/
│ │ ├── diff/ Diff engine (compare, severity, confidence)
│ │ ├── github/ GitHub API fetcher + GitHub App authentication
│ │ ├── sourcefile/ Language detection, test file filtering, skip directories
│ │ └── analyzer/ Gemini-powered static analysis
│ └── migrations/ PostgreSQL schema migrations
├── cohesion_fe_analyzer/ TypeScript analyzer (ts-morph) for frontend codebases
├── cohesion_frontend/ Next.js 16 App Router UI
│ └── src/
│ ├── app/ Pages: dashboard, project, endpoint, live, docs, settings
│ ├── components/ UI kit, visualizations, live components
│ ├── lib/ API client, types, auth, utilities
│ └── stores/ Zustand state management
└── PRD.md Product requirements
flowchart TD
subgraph UI["Next.js UI"]
Dash["Dashboard"]
Project["Project Detail"]
Endpoint["Endpoint Detail + Handshake"]
Live["Live Capture (Unified / Dual / Diff / Handshake)"]
Docs["Documentation"]
Settings["Settings + GitHub App"]
end
subgraph CP["Control Plane (Go + Chi)"]
Projects["Project & Endpoint CRUD"]
SchemaStore["Schema Ingestion & Storage"]
DiffEngine["Diff Engine"]
LiveService["Live Service + SSE"]
Proxy["Reverse Proxy"]
GitHubApp["GitHub App Integration"]
Crypto["Encrypted Secret Storage"]
end
subgraph Analyzers["Analyzers"]
BE["Go / Python / Java Static Analyzer"]
FE["Next.js / React FE Analyzer"]
AI["AI-Powered Scan (Gemini)"]
RT["Runtime Inference"]
end
subgraph Storage["PostgreSQL"]
SchemaIR[("Schema IR (JSONB)")]
UserData[("Projects, Endpoints, Settings")]
Installations[("GitHub Installations")]
end
Dash --> Projects
Endpoint --> DiffEngine
Live --> LiveService
Live --> Proxy
Settings --> GitHubApp
BE --> SchemaStore
FE --> SchemaStore
AI --> SchemaStore
RT --> SchemaStore
SchemaStore --> SchemaIR
Projects --> UserData
DiffEngine --> SchemaIR
LiveService --> RT
GitHubApp --> Installations
Crypto --> UserData
sequenceDiagram
participant Dev as Developer
participant Analyzer as Static Analyzer
participant App as Your Application
participant CP as Control Plane API
participant DB as Schema Store
participant UI as Next.js UI
Note over Dev,UI: Static Analysis Path
Dev->>Analyzer: Scan codebase (or upload files)
Analyzer-->>CP: POST /api/analyze/{backend,frontend}
CP-->>DB: Normalize + persist Schema IR
Note over Dev,UI: Runtime Observation Path
App->>CP: POST /api/live/ingest (captured traffic)
CP->>CP: Buffer requests, broadcast via SSE
Dev->>CP: POST /api/live/infer
CP-->>DB: Inferred Schema IR (runtime-observed)
Note over Dev,UI: Visualization
UI->>CP: GET /api/endpoints, GET /api/diff/{id}
CP-->>UI: Schemas + diff results
UI->>UI: Render handshake graph, diff panel
The Schema Intermediate Representation is the backbone of Cohesion. Every analyzer, every inference engine, and every upload produces this format. It is JSON-serializable, deterministic, and language-agnostic.
{
"endpoint": "/api/users",
"method": "POST",
"source": "backend-static",
"request": {
"type": "object",
"fields": {
"email": { "type": "string", "required": true },
"name": { "type": "string", "required": true },
"role": { "type": "string", "required": false }
}
},
"response": {
"201": {
"type": "object",
"fields": {
"id": { "type": "string", "required": true },
"email": { "type": "string", "required": true }
}
}
}
}Key properties:
source— one ofbackend-static,frontend-static,runtime-observedrequest— the expected request body schemaresponse— map of HTTP status code to response body schemafields— each field has atype,requiredflag, optionalnestedobject, and optionalconfidence(0.0–1.0) for runtime-inferred fields
Cohesion can analyze codebases in two ways:
Upload files or point to a GitHub repo. Cohesion sends the code to the Gemini API, which extracts endpoint definitions and produces Schema IR.
POST /api/analyze/scan — scan local files
POST /api/analyze/github — scan a GitHub repository
Supported languages: Go, Python, TypeScript, JavaScript, Java, Ruby, Rust, PHP, C#, Kotlin, Elixir, Scala, Swift
The sourcefile package handles language detection, test file filtering, and automatically skips non-source directories (vendor, node_modules, .git, __pycache__, dist, build, target, .next, etc.).
If you already have schemas (from OpenAPI, from your own tooling, etc.), upload them directly:
POST /api/analyze/backend — backend schemas
POST /api/analyze/frontend — frontend schemas
POST /api/analyze/runtime — runtime-observed schemas
The cohesion_fe_analyzer package uses ts-morph to statically analyze Next.js/React codebases. It discovers fetch() and axios calls, extracts URL patterns, HTTP methods, and payload shapes, and outputs Schema IR.
flowchart LR
Code["TypeScript Source"] --> TSMorph["ts-morph AST"]
TSMorph --> Extract["Extract fetch/axios calls"]
Extract --> IR["Schema IR"]
IR -->|POST| CP["/api/analyze/frontend"]
The diff engine is the core IP of Cohesion. It compares Schema IR from multiple sources for the same endpoint and produces a detailed mismatch report.
flowchart TD
BE["Backend Schema"] --> Normalize["Field Normalization"]
FE["Frontend Schema"] --> Normalize
RT["Runtime Schema"] --> Normalize
Normalize --> CompareReq["Compare Request Fields"]
Normalize --> CompareRes["Compare Response Fields"]
CompareReq --> Mismatches["Mismatch List"]
CompareRes --> Mismatches
Mismatches --> Severity["Assign Severity"]
Severity --> Confidence["Compute Confidence Score"]
Confidence --> Result["DiffResult"]
Before comparing, the engine normalizes field names and types to avoid false positives:
- Names:
camelCase,PascalCase, andkebab-caseare all converted tosnake_case - Types: equivalent types are grouped —
int/integer/number/float→number,bool/boolean→boolean,object/map→object,array/list→array
| Type | Meaning | Example |
|---|---|---|
missing |
Field exists in some sources but not others | Backend returns avatar_url, frontend doesn't expect it |
type_mismatch |
Same field, different types | Backend says string, frontend says number |
optionality_mismatch |
Required in one source, optional in another | Backend requires role, frontend sends it optionally |
extra_field |
Field only present in one side | Frontend sends debug_mode, backend ignores it |
The engine assigns severity based on the direction of data flow:
| Severity | When | Impact |
|---|---|---|
| Critical | Type mismatches; frontend expects a response field the backend doesn't return | Will break at runtime |
| Warning | Backend expects a request field the frontend doesn't send; optionality mismatches | May cause validation failures |
| Info | Extra fields the other side ignores | Harmless but worth knowing |
Each diff result includes a confidence score (0–100) reflecting how trustworthy the comparison is:
- +20 for each source type present (backend, frontend, runtime)
- +20 bonus when all three sources are present (triple verification)
- -10 per critical mismatch
- -3 per warning
- Clamped to 0–100
| Status | Meaning |
|---|---|
match |
No mismatches found — all sources agree |
partial |
Only warnings or info-level issues |
violation |
At least one critical mismatch |
Live Capture lets you observe real HTTP traffic flowing through your application, then infer runtime schemas from it. This gives you a third source of truth alongside static analysis.
flowchart LR
subgraph Sources["Traffic Sources"]
Self["Self-Capture Middleware"]
Proxy["Reverse Proxy"]
Ingest["POST /api/live/ingest"]
end
subgraph Service["Live Service"]
Buffer["Circular Buffer (200/project)"]
SSE["SSE Broadcaster"]
Infer["Runtime Inference"]
end
Self --> Buffer
Proxy --> Buffer
Ingest --> Buffer
Buffer --> SSE -->|real-time events| UI["Frontend"]
Buffer --> Infer --> SchemaIR["Schema IR (runtime-observed)"]
1. Self-Capture — Record Cohesion's own API traffic. Start with POST /api/live/capture/start. A middleware intercepts every request/response (except /api/live/* paths to avoid recursion) and adds it to the buffer with source: "self".
2. Reverse Proxy — Configure a proxy target and route external traffic through Cohesion. Every request is forwarded to the real service, and the full request/response pair is captured automatically. See Dual Sources.
3. External Ingest — Add a middleware to your own application that POSTs captured traffic to POST /api/live/ingest. Works with any language or framework.
The Live page connects to GET /api/live/stream?project_id={id} via Server-Sent Events. Every captured request is broadcast in real time:
{ "type": "request", "payload": { "id": "...", "path": "/api/users", "method": "GET", ... }, "source": "self" }A "clear" event is sent when the buffer is flushed.
Call POST /api/live/infer to convert buffered traffic into Schema IR:
- Requests are grouped by
method:path - For each endpoint, request bodies and response bodies are merged across observations
- Fields seen in every request are marked required; fields seen in some are marked optional with a confidence score
- The resulting schemas are stored as
runtime-observedand appear in endpoint views and diffs
The Live page has four tabs:
| Tab | Purpose |
|---|---|
| Unified | Single chronological stream of all captured requests regardless of source. Click any request to inspect full request/response bodies. Infer schemas from the entire buffer. |
| Dual Sources | Side-by-side view of traffic from two different sources. Source selectors in the tab bar let you pick which two to compare. |
| Live Diff | Compute a schema diff between two sources' inferred schemas. See Live Diff. |
| Live Handshake | Three-column handshake visualization showing how frontend and backend schemas align at runtime. See Live Handshake. |
Dual Sources mode lets you capture and compare traffic from two different origins simultaneously.
Every captured request is tagged with a source label:
"self"— traffic captured by Cohesion's own middleware- Any custom label — traffic captured through a configured reverse proxy or tagged in external ingestion
flowchart LR
Client["Your Client"] -->|request| Proxy["Cohesion Proxy<br/>/api/live/proxy/{project}/{label}/*"]
Proxy -->|forward| Target["Target Service<br/>(e.g. localhost:3001)"]
Target -->|response| Proxy
Proxy -->|response| Client
Proxy -->|capture| Buffer["Live Buffer<br/>(source = label)"]
Configure a proxy:
curl -X POST http://localhost:8080/api/live/proxy/configure \
-H "Content-Type: application/json" \
-d '{
"project_id": "PROJECT_ID",
"label": "staging-api",
"target_url": "http://localhost:3001"
}'This registers a proxy at http://localhost:8080/api/live/proxy/PROJECT_ID/staging-api/. Any request sent to this URL is forwarded to http://localhost:3001, and the full request/response pair is captured with source: "staging-api".
- Client sends request to the proxy URL
- Cohesion reads and buffers the request body
- The request is forwarded to the target service with the original method, headers, and body
- The target's response is read and buffered
- A
LiveRequestis created with the label as source, full request/response bodies, status code, and duration - The request is ingested into the live buffer and broadcast via SSE
- The original response is returned to the client unchanged
In the Live page, click the Dual Sources tab. Two columns appear side by side, each showing traffic from one source. Use the source selectors to pick which sources to compare (e.g. self vs staging-api).
The Proxy Sources configuration panel lets you add, view, and remove proxy targets directly from the UI. Each configured proxy shows a copy button for its proxy URL.
Live Diff compares the runtime-inferred schemas of two traffic sources. Instead of comparing static code analysis, it compares what two services actually send and receive at runtime.
flowchart TD
BufferA["Source A Requests"] --> InferA["Infer Schemas<br/>(group by method:path)"]
BufferB["Source B Requests"] --> InferB["Infer Schemas<br/>(group by method:path)"]
InferA --> Tag["Tag as backend-static"]
InferB --> Tag2["Tag as frontend-static"]
Tag --> Match["Match endpoints<br/>by method + path"]
Tag2 --> Match
Match --> DiffEngine["Diff Engine<br/>(field-by-field comparison)"]
DiffEngine --> Results["Per-endpoint DiffResults<br/>with mismatches + severity"]
Step by step:
-
Infer per source — The backend groups each source's buffered requests by
method:pathand infers a schema from observed bodies. Fields seen in every request are required; fields seen in some are optional. -
Tag schemas — Source A's schemas are tagged as
backend-static, Source B's asfrontend-static. This lets the existing diff engine's directional logic apply correctly. -
Match endpoints — Endpoints are matched across both sets by method and path.
-
Compute mismatches — For every matched endpoint, the diff engine compares request and response fields, detecting missing fields, type mismatches, optionality conflicts, and extra fields.
-
Display results — The UI shows an endpoint list with status icons on the left and the full mismatch detail on the right.
| Scenario | How to set it up |
|---|---|
| Comparing environments | Proxy staging and production. Diff to find behavioral drift. |
| Comparing API versions | Proxy /v1 and /v2. Live Diff shows which fields changed between versions. |
| Validating a migration | Route traffic to old and new service. If Live Diff shows all matches, the new service is behaviourally equivalent. |
| Frontend vs Backend at runtime | Capture frontend calls (via proxy) and backend responses (via self-capture). Diff to find what the frontend actually sends vs what the backend actually returns. |
curl -X POST http://localhost:8080/api/live/diff \
-H "Content-Type: application/json" \
-d '{
"project_id": "PROJECT_ID",
"source_a": "self",
"source_b": "staging-api"
}'Response:
{
"source_a": "self",
"source_b": "staging-api",
"endpoint_count": 3,
"results": [
{
"endpoint": "/api/users",
"method": "GET",
"status": "partial",
"sources_compared": ["backend-static", "frontend-static"],
"mismatches": [
{
"path": "response.200.avatar_url",
"type": "missing",
"severity": "warning",
"description": "Field present in source_a but missing in source_b"
}
]
}
]
}Live Handshake provides a three-column, field-by-field visualization of how your frontend and backend API contracts align at runtime. While Live Diff tells you what is different, Live Handshake shows you how the two sides see each endpoint — side by side, with mismatches highlighted inline.
flowchart TD
FE["Frontend Source Traffic"] --> InferFE["Infer Schemas"]
BE["Backend Source Traffic"] --> InferBE["Infer Schemas"]
InferFE --> Diff["Diff Engine"]
InferBE --> Diff
Diff --> Map["Build Endpoint Map<br/>(FE schema + BE schema + diff)"]
Map --> Render["Three-Column Handshake View"]
- Infer schemas per source — Schemas are inferred from captured traffic for both the frontend and backend sources.
- Compute diff — The diff engine matches endpoints across both sets and compares them field by field.
- Build handshake map — Each endpoint is assembled into an entry containing the frontend schema, backend schema, and diff result.
- Render — The UI shows an endpoint list with status icons on the left, and a three-column Handshake View (Frontend / Agreement / Backend) on the right.
| Icon | Status | Meaning |
|---|---|---|
| ✓ | Match | Frontend and backend schemas agree on all fields |
| ○ | Partial | Some fields match, but there are mismatches (e.g. optional vs required) |
| ✕ | Violation | Significant contract disagreement — missing fields or type mismatches |
| • | Unknown | Only one side has traffic for this endpoint |
| Live Diff | Live Handshake | |
|---|---|---|
| Output | Mismatch list per endpoint | Three-column schema overlay |
| Best for | Quickly spotting differences | Understanding the full contract shape |
| Shows fields | Only mismatched fields | All fields from both sides |
| Use case | CI checks, regression detection | Design reviews, debugging contract gaps |
Cohesion supports connecting GitHub accounts via a GitHub App for repository access. This provides a more secure alternative to personal access tokens and supports organization-level installations.
- Install the GitHub App — From the Settings page, click "Connect Account" to install the Cohesion GitHub App on your GitHub account or organization.
- Installation callback — After installation, GitHub redirects back to Cohesion with an installation ID. The frontend saves this to the backend.
- Authenticated repo access — When scanning GitHub repositories, Cohesion can use the App installation token instead of a personal access token. App tokens are scoped to the repositories the user granted access to.
- Encrypted storage — Installation data is stored in PostgreSQL. Sensitive tokens and API keys are encrypted at rest using AES-256-GCM.
The Settings page shows all connected GitHub accounts with:
- Account name and type (user or organization)
- Disconnect button to remove an installation
- Fallback to personal access token for accounts without the App installed
The GitHub App requires these environment variables:
GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY_PATH=./github-app-private-key.pem
GITHUB_APP_CLIENT_ID=Iv1.abc123
GITHUB_APP_CLIENT_SECRET=secret
GITHUB_APP_SLUG=cohesion
FRONTEND_URL=http://localhost:3000
Next.js 16 (App Router, Turbopack), TypeScript, Tailwind CSS, Zustand, React Flow, D3.js, Framer Motion, Clerk (auth), Lucide icons, Sonner (toasts).
flowchart LR
Dashboard["/ Dashboard"] --> Project["/projects/:id"]
Project --> Endpoint["/projects/:id/endpoints/:id"]
Dashboard --> Live["/live"]
Dashboard --> Docs["/docs"]
Dashboard --> Settings["/settings"]
Live --> Unified["Unified View"]
Live --> Dual["Dual Sources"]
Live --> Diff["Live Diff"]
Live --> Handshake["Live Handshake"]
Endpoint --> Flow["Flow View"]
Endpoint --> List["List View"]
Endpoint --> Code["Code View"]
Endpoint --> HandshakeView["Handshake View"]
Project cards showing endpoint counts, schema source badges, and contract health. Onboarding checklist for new users. Global statistics (matched / partial / violations).
Endpoint table with method badges, path, source indicators, and status. Upload schemas via scan (local or GitHub) or manual JSON paste. Delete project.
Split-pane layout:
- Left panel — Schema visualization in four modes:
- Flow — Interactive React Flow graph showing request/response field connections
- List — Structured tree view of fields
- Code — Raw Schema IR JSON
- Handshake — Three-column view (Frontend Intent / Agreement / Backend Capability)
- Right panel — Diff analysis with mismatch list, severity badges, and suggestions
- Source tabs — Switch between backend-static, frontend-static, runtime-observed, handshake
Four view modes (Unified / Dual Sources / Live Diff / Live Handshake), project selector, capture controls, proxy source configuration. Real-time SSE streaming. Schema inference.
Seven documentation tabs with interactive code examples, step-by-step guides, and an "On this page" table of contents sidebar with scroll tracking:
- Import Codebase — Getting started with project creation and schema scanning
- Schemas & Handshake — Schema sources and visualization modes
- Diff Engine — How the diff engine works and mismatch types
- Live Capture — Middleware integration guides (Node.js, Python, Go), SSE streaming, ingest API
- Dual Sources — Proxy configuration and side-by-side traffic comparison
- Live Diff — Runtime schema diffing between two sources
- Live Handshake — Three-column handshake visualization from live traffic
- AI Configuration — Gemini API key and model selection for AI-powered analysis
- GitHub Integration — Connect GitHub accounts via the Cohesion GitHub App, with fallback to personal access token
- Connected Accounts — View and manage GitHub App installations per account/organization
| Method | Path | Description |
|---|---|---|
POST |
/api/projects |
Create a project |
GET |
/api/projects |
List all projects |
GET |
/api/projects/{id} |
Get project |
DELETE |
/api/projects/{id} |
Delete project |
| Method | Path | Description |
|---|---|---|
GET |
/api/endpoints?project_id={id} |
List endpoints for a project |
GET |
/api/endpoints/{id} |
Get endpoint with schemas |
| Method | Path | Description |
|---|---|---|
POST |
/api/analyze/backend |
Upload backend schemas |
POST |
/api/analyze/frontend |
Upload frontend schemas |
POST |
/api/analyze/runtime |
Upload runtime schemas |
POST |
/api/analyze/scan |
AI scan local codebase |
POST |
/api/analyze/github |
AI scan GitHub repository |
| Method | Path | Description |
|---|---|---|
POST |
/api/diff/{endpointId} |
Compute diff across all sources |
GET |
/api/stats |
Aggregated match/partial/violation counts |
| Method | Path | Description |
|---|---|---|
POST |
/api/live/ingest |
Ingest captured requests |
GET |
/api/live/requests?project_id={id} |
Get buffered requests |
GET |
/api/live/stream?project_id={id} |
SSE stream of live events |
POST |
/api/live/infer |
Infer schemas from buffer |
POST |
/api/live/clear |
Clear buffer |
POST |
/api/live/capture/start |
Start self-capture middleware |
POST |
/api/live/capture/stop |
Stop self-capture middleware |
GET |
/api/live/sources?project_id={id} |
List distinct source labels |
GET |
/api/live/schemas?project_id={id}&source={s} |
Get inferred schemas for a source |
POST |
/api/live/diff |
Diff two sources' inferred schemas |
POST |
/api/live/proxy/configure |
Register a reverse proxy target |
* |
/api/live/proxy/{projectId}/{label}/* |
Reverse proxy passthrough |
| Method | Path | Description |
|---|---|---|
GET |
/api/github/status |
Check if GitHub App is configured, get install URL |
POST |
/api/github/installations |
Save a GitHub App installation |
GET |
/api/github/installations |
List connected GitHub accounts |
DELETE |
/api/github/installations/{installationID} |
Remove a GitHub installation |
| Method | Path | Description |
|---|---|---|
GET |
/api/user/settings |
Get settings (keys masked) |
PUT |
/api/user/settings |
Save Gemini key, model, GitHub token |
- Go 1.22+
- Node 18+
- PostgreSQL
- (Optional) Gemini API key for AI-powered analysis
- (Optional) GitHub App or personal access token for repo scanning
# Backend (cohesion_backend/.env)
DATABASE_URL=postgres://user:pass@localhost:5432/cohesion
PORT=8080
ENVIRONMENT=development
GEMINI_API_KEY=your-gemini-api-key
GEMINI_MODEL=gemini-2.0-flash
CLERK_SECRET_KEY=sk_test_...
CLERK_PUBLISHABLE_KEY=pk_test_...
ENCRYPTION_KEY= # Required in production — 32-byte hex key for encrypting stored secrets (app will refuse to start without it when ENVIRONMENT=production)
# GitHub App (optional)
GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY_PATH=./github-app-private-key.pem
GITHUB_APP_CLIENT_ID=Iv1.abc123
GITHUB_APP_CLIENT_SECRET=secret
GITHUB_APP_SLUG=cohesion
FRONTEND_URL=http://localhost:3000
# Frontend (cohesion_frontend/.env)
NEXT_PUBLIC_API_URL=http://localhost:8080
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/
NEXT_PUBLIC_GITHUB_APP_SLUG=cohesioncd cohesion_backend
go run ./cmd/server
# Runs on :8080 by defaultcd cohesion_frontend
npm install
npm run dev
# Runs on :3000 by defaultcd cohesion_fe_analyzer
npm install
npm run build- Start the backend and frontend
- Create a project from the dashboard
- Upload or scan schemas (backend + frontend)
- Open an endpoint to see the handshake view and diff
- Go to Live Capture, start self-capture, browse the UI, then infer schemas to get runtime data
- Switch to Live Handshake to see how frontend and backend contracts align
Emit Schema IR and POST to /api/analyze/{backend,frontend,runtime}. The diff engine and UI work unchanged — they only consume Schema IR.
Consume /api/endpoints/{id} (schemas) and /api/diff/{id} (mismatches). The IR is purposefully simple and deterministic.
Any service that can POST captured request/response pairs to /api/live/ingest can participate. The Go middleware in pkg/runtime is just the reference implementation. Express, FastAPI, and Go middleware examples are in the docs page.
POST /api/live/proxy/configure with a label and target URL. Traffic routed through the proxy is automatically captured and tagged. No code changes needed.
- Runtime capture is opt-in — must be explicitly started
- Static analysis performs no code execution (AST / AI only)
- Request/response bodies are buffered in-memory with a 200-request circular buffer per project
- API keys and tokens are encrypted at rest using AES-256-GCM and masked in API responses.
ENCRYPTION_KEYis required in production — the server will refuse to start without it - GitHub App installations use scoped installation tokens rather than broad personal access tokens
- Self-capture excludes
/api/live/*paths to prevent recursive capture - Authentication via Clerk on all protected routes
- CORS is configured on the backend — adjust for production deployments
Built with Go, Next.js, and a belief that API contracts should be visible, inspectable, and provable.