/healthzliveopsHealth check
Returns 200 OK if the API process is alive. No auth required.
responses
| field | type | notes |
|---|---|---|
| ok* | boolean | — |
| ts* | string | — |
example — curl
curl -X GET 'http://localhost:7710/healthz'
API reference
This is the data plane. Customer recorders POST captured sessions to POST /v1/sessions; the warehouse auto-generates a Playwright/Vitest spec, persists it under tenant isolation, and returns the spec id and confidence in the same response. Everything else — spec list, insights, audit log export, MCP tool surface — is a thin shell over the same shape.
Spec is OpenAPI 3.0, sourced from the same Zod schemas that validate inbound requests at runtime. Same source of truth as the server. When the API changes, this page changes — there is no hand-maintained docs drift.
Per-tenant bearer token issued at onboarding. Pass on every /v1/* request:
authorization: Bearer <TOKEN>
Token resolves to a tenant_id which we set in the Postgres connection's app.current_tenant_idGUC. Row Level Security handles cross-tenant isolation; the application code cannot accidentally read another tenant's data.
https://cuit-saas-pilot.fly.dev— Pilot — LIVE today on Fly.io (IAD) + Neon (us-east-1)http://localhost:7710— Local developmenthttps://api.cuit.dev— Production — sprint week 8 (AWS ECS Fargate + Aurora)Pilot is on Fly.io + Neon Postgres. Production lands on AWS ECS Fargate + Aurora in sprint week 8 — same OpenAPI surface, no breaking changes.
Path-prefixed under /v1/. We bump /v2/ only for genuine breaking changes; additive fields and new optional parameters ship under /v1/ forever.
Every error is JSON, always shape { error: string, message?: string, issues?: [] }. HTTP status is the source of truth for category; the body is the source of truth for what to tell the developer.
| status | error | when |
|---|---|---|
| 400 | invalid payload | Body did not match the route's Zod schema. issues is the Zod error array verbatim. |
| 401 | missing bearer token | No Authorization header. Or the header doesn't start with Bearer . |
| 401 | invalid token | Token didn't resolve to a tenant. Rotated? Revoked? Typo? |
| 404 | not found | Resource ID doesn't exist in this tenant. RLS makes cross-tenant 404s look identical to genuinely missing — by design. |
| 500 | server error | Our fault. message is the underlying exception. We log every 500 with a request id; mention it when you file a ticket. |
The REST API exists for CI workflows, batch scripts, and direct integration. The MCP server (@cuit-saas/mcp) is what Claude Code / Cursor / Codex consume in-loop. Both call the same endpoints below. If you're wiring an agent: use MCP. If you're wiring CI: use REST.
// ~/.claude/mcp_servers.json
{
"mcpServers": {
"cuit": {
"command": "npx",
"args": ["-y", "@cuit-saas/mcp"],
"env": {
"CUIT_API_URL": "https://api.cuit.dev",
"CUIT_TENANT_TOKEN": "<YOUR_TENANT_TOKEN>"
}
}
}
}The MCP server ships 3 of 8 tools wired today (query_sessions, find_similar_sessions, flake_rate). The remaining 5 ship across sprint weeks 3-8 — see docs/12 §6 for the frozen tool interface.
Auto-generated from openapi.json. Same schemas as the runtime validation. Examples are real shapes the API accepts — copy and paste them.
Health and operations endpoints (no auth)
/healthzliveopsHealth check
Returns 200 OK if the API process is alive. No auth required.
| field | type | notes |
|---|---|---|
| ok* | boolean | — |
| ts* | string | — |
curl -X GET 'http://localhost:7710/healthz'
Tenant + token management. Admin or tenant-bearer auth.
/v1/admin/tenantsliveadminCreate a new tenant
Admin-only. Issues an initial bearer token returned in the response. Token is shown ONCE; we store only its hash. Customer onboarding flow uses this endpoint.
| field | type | notes |
|---|---|---|
| slug* | string | — |
| display_name* | string | — |
| tier* | "team" | "business" | "enterprise" | — |
| pii_redaction | boolean | — |
| retention_days | integer | — |
| field | type | notes |
|---|---|---|
| tenant* | object | — |
| initial_token* | object | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/v1/admin/tenants' \
-H 'content-type: application/json' \
-d '{
"slug": "acme-corp",
"display_name": "Acme Corp",
"tier": "business",
"pii_redaction": true,
"retention_days": 0
}'/v1/admin/tokensliveadminIssue a new bearer token for the current tenant
Used to rotate tokens or to issue scoped tokens for specific environments (CI vs. dev). Token shown ONCE in the response.
| field | type | notes |
|---|---|---|
| label* | string | — |
| expires_at | string<date-time> | — |
| field | type | notes |
|---|---|---|
| token* | string | Plaintext bearer token. Shown ONCE; we store only a hash. Save it now. |
| token_id* | string<uuid> | — |
| label* | string | — |
| created_at* | string | — |
| expires_at* | string | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/v1/admin/tokens' \
-H 'authorization: Bearer <YOUR_TENANT_TOKEN>' \
-H 'content-type: application/json' \
-d '{
"label": "github-actions-ci",
"expires_at": "2027-01-01T00:00:00Z"
}'/v1/meliveadminCurrent tenant info
Returns the tenant resolved from the bearer token. Useful for the dashboard.
| field | type | notes |
|---|---|---|
| tenant* | object | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/me' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/auditliveadminStream audit log as CSV / JSON / NDJSON
Compliance export. Returns a streaming response in the requested format. For large windows, prefer NDJSON for line-by-line consumption.
| name | in | type | notes |
|---|---|---|---|
| since* | query | string<date-time> | — |
| until* | query | string<date-time> | — |
| format | query | "csv" | "json" | "ndjson" | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/audit' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/admin/tenantliveadminPurge all tenant data (GDPR right-to-delete)
Hard-deletes sessions, specs, runs, signals, audit log for the authenticated tenant. Asynchronous: completes within 30 days. Returns a purge job id.
| field | type | notes |
|---|---|---|
| purge_job_id* | string<uuid> | — |
| eta_at* | string | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X DELETE 'http://localhost:7710/v1/admin/tenant' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
Capture session upload and retrieval
/v1/sessionslivesessionsList sessions for the authenticated tenant
Returns up to `limit` most-recent sessions ordered by created_at DESC.
| name | in | type | notes |
|---|---|---|---|
| limit | query | string | — |
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| sessions* | object[] | — |
| count* | integer | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/sessions' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/sessionslivesessionsUpload a captured session
Accepts a SessionEvent[] captured by the recorder. Auto-generates a regression spec when feasible (rule-based today; LLM pipeline ships sprint week 5). Idempotent on (tenant_id, session_id).
| field | type | notes |
|---|---|---|
| sessionId* | string | — |
| vendor* | "cuit" | "jam" | "logrocket" | "sentry-replay" | "fullstory" | "datadog-rum" | — |
| createdAt | number | — |
| url* | string | — |
| events* | object[] | — |
| gitSha | string | — |
| gitBranch | string | — |
| capturedByUserId | string<uuid> | — |
| field | type | notes |
|---|---|---|
| id* | string<uuid> | — |
| tenant* | string | — |
| event_count* | integer | — |
| spec_id* | string<uuid> | — |
| confidence* | number | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/v1/sessions' \
-H 'authorization: Bearer <YOUR_TENANT_TOKEN>' \
-H 'content-type: application/json' \
-d '{
"sessionId": "tur-live-1717459200000",
"vendor": "cuit",
"createdAt": 0,
"url": "http://localhost:3000/projects/abc?cuitRecorder=1",
"events": [
{
"seq": 7,
"vendor": "cuit",
"vendorEventId": "tur-001-p-10",
"ts": 1200,
"wallClock": 1748952001200,
"type": "pointer"
}
],
"gitSha": "abc1234",
"gitBranch": "developNoWaveFormFinal",
"capturedByUserId": "00000000-0000-0000-0000-000000000000"
}'/v1/sessions/{id}livesessionsFetch one session by id
| name | in | type | notes |
|---|---|---|---|
| id* | path | string<uuid> | — |
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| session* | object | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/sessions/:id' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/sessions/{id}/similarlivesessionsFind sessions vector-similar to this one
Backed by pgvector cosine similarity over per-session embeddings (voyage-3-lite). The MCP tool `cuit__find_similar_sessions` is a thin wrapper around this endpoint.
| name | in | type | notes |
|---|---|---|---|
| id* | path | string<uuid> | — |
| threshold | query | string | — |
| field | type | notes |
|---|---|---|
| reference_session_id* | string<uuid> | — |
| threshold* | number | — |
| similar* | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/sessions/:id/similar' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/sessions/{id}/eventslivesessionsFetch the full events array for a single session
Returns the JSONB events column for a session. This is the AX-compliant drill-down counterpart to GET /v1/sessions, which returns only compact id+summary rows to stay within token budget (ADR-011 Rule 2). Pass the returned events to cuit__close_loop to generate and run a regression spec.
| name | in | type | notes |
|---|---|---|---|
| id* | path | string<uuid> | — |
| field | type | notes |
|---|---|---|
| outcome* | "ok" | — |
| summary* | string | — |
| data* | object | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| outcome* | "error" | — |
| error* | string | — |
| fix_hint* | string | — |
curl -X GET 'http://localhost:7710/v1/sessions/:id/events' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
Generated regression specs
/v1/specslivespecsList generated specs for the authenticated tenant
Returns up to 100 most-recent specs ordered by created_at DESC.
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| specs* | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/specs' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/specs/generatelivespecsGenerate a spec synchronously from a session payload OR session id
POST /v1/sessions auto-generates a spec asynchronously. Use this endpoint when you want the spec back in the same HTTP response — typical for CI integrations or the /cuit-loop skill. Calls the LLM 3-pass pipeline (Haiku normalize → Sonnet ground → Opus materialize) with prompt caching; falls back to rule-based when model_tier=rule-based.
| field | type | notes |
|---|---|---|
| sessionId | string<uuid> | Existing session UUID OR session payload below. |
| session | object | — |
| model_tier | "rule-based" | "haiku" | "sonnet" | "opus" | "auto" | — |
| force_regenerate | boolean | — |
| field | type | notes |
|---|---|---|
| id* | string<uuid> | — |
| session_id* | string<uuid> | — |
| model_version* | string | — |
| confidence* | number | — |
| auto_pr_eligible* | boolean | — |
| primitives* | object[] | — |
| serialized* | string | The rendered .spec.ts source code. |
| created_at* | string | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/v1/specs/generate' \
-H 'authorization: Bearer <YOUR_TENANT_TOKEN>' \
-H 'content-type: application/json' \
-d '{
"sessionId": "00000000-0000-0000-0000-000000000000",
"session": {
"sessionId": "tur-live-1717459200000",
"vendor": "cuit",
"createdAt": 0,
"url": "http://localhost:3000/projects/abc?cuitRecorder=1",
"events": [
{
"seq": 7,
"vendor": "cuit",
"vendorEventId": "tur-001-p-10",
"ts": 1200,
"wallClock": 1748952001200,
"type": "pointer"
}
],
"gitSha": "abc1234",
"gitBranch": "developNoWaveFormFinal",
"capturedByUserId": "00000000-0000-0000-0000-000000000000"
},
"model_tier": "rule-based",
"force_regenerate": true
}'/v1/specs/{id}livespecsFetch one spec by id (with full primitives + source)
| name | in | type | notes |
|---|---|---|---|
| id* | path | string<uuid> | — |
| field | type | notes |
|---|---|---|
| id* | string<uuid> | — |
| session_id* | string<uuid> | — |
| model_version* | string | — |
| confidence* | number | — |
| auto_pr_eligible* | boolean | — |
| primitives* | object[] | — |
| serialized* | string | The rendered .spec.ts source code. |
| created_at* | string | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/specs/:id' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
Spec executions against customer URLs
/v1/specs/{id}/runliverunsRun a spec against a customer URL; returns RED or GREEN with step-level annotations
The runner spins up a vitest-in-process worker (or headless Playwright per `browser`), executes the spec, and returns the structured outcome. On RED: the response includes `failed_at_primitive`, `last_snapshot`, and the preceding event window so an agent can reason about the failure without re-reading the spec source.
| name | in | type | notes |
|---|---|---|---|
| id* | path | string<uuid> | — |
| field | type | notes |
|---|---|---|
| target_url* | string<uri> | — |
| browser | "chromium" | "firefox" | "webkit" | "jsdom" | — |
| expected_outcome | "red" | "green" | "either" | — |
| field | type | notes |
|---|---|---|
| id* | string<uuid> | — |
| spec_id* | string<uuid> | — |
| outcome* | "red" | "green" | "error" | — |
| browser* | string | — |
| duration_ms* | integer | — |
| git_sha_at_run* | string | — |
| is_flake* | boolean | — |
| created_at* | string | — |
| state_at_assertion | object | — |
| failed_at_primitive | object | — |
| last_snapshot | object | When outcome=red: the state snapshot at the moment of failure. |
| preceding_events | object[] | When outcome=red: the last N events before failure for context. |
| steps | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/v1/specs/:id/run' \
-H 'authorization: Bearer <YOUR_TENANT_TOKEN>' \
-H 'content-type: application/json' \
-d '{
"target_url": "http://localhost:3000/projects/abc?cuitRecorder=1",
"browser": "chromium",
"expected_outcome": "red"
}'/v1/runsliverunsList runs across all specs for this tenant
Filterable by `spec_id`, `outcome`, `since`, `until`. Default: last 100 runs across the tenant.
| name | in | type | notes |
|---|---|---|---|
| spec_id | query | string<uuid> | — |
| outcome | query | "red" | "green" | "error" | — |
| since | query | string<date-time> | — |
| until | query | string<date-time> | — |
| limit | query | string | — |
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| runs* | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/runs' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/loop/closeliverunsOne-shot loop close: generate spec → run spec → persist trace
ADR-011 Rule 6 (one-shot composition) + Rule 7 (self-measuring). Runs generate→run→report in ONE call inside a single DB transaction (spec row + run row + loop_trace row + audit row). Returns the loop AX envelope with outcome green|red|error and a trace {turns_to_green, tool_calls, tokens, wall_ms}. Always returns HTTP 200 — the envelope carries the outcome. NOTE: not deduplicated in v0 (each call inserts a new spec row; non-destructive).
| field | type | notes |
|---|---|---|
| session_id | string<uuid> | sessions.id UUID. Mutually exclusive with session. |
| session | object | Inline session payload. Mutually exclusive with session_id. |
| target_url* | string<uri> | URL the spec runner will navigate to. |
| field | type | notes |
|---|---|---|
| outcome* | "green" | "red" | "error" | — |
| summary* | string | — |
| next_actions* | string[] | — |
| details_ref* | string | — |
| data* | object | — |
| trace* | object | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| outcome* | "green" | "red" | "error" | — |
| summary* | string | — |
| next_actions* | string[] | — |
| details_ref* | string | — |
| data* | object | — |
| trace* | object | — |
| field | type | notes |
|---|---|---|
| outcome* | "green" | "red" | "error" | — |
| summary* | string | — |
| next_actions* | string[] | — |
| details_ref* | string | — |
| data* | object | — |
| trace* | object | — |
curl -X POST 'http://localhost:7710/v1/loop/close' \
-H 'authorization: Bearer <YOUR_TENANT_TOKEN>' \
-H 'content-type: application/json' \
-d '{
"session_id": "00000000-0000-0000-0000-000000000000",
"session": {
"sessionId": "string",
"vendor": "cuit",
"url": "string",
"events": [
{
"seq": 7,
"vendor": "cuit",
"vendorEventId": "tur-001-p-10",
"ts": 1200,
"wallClock": 1748952001200,
"type": "pointer"
}
],
"gitSha": "string",
"gitBranch": "string",
"capturedByUserId": "00000000-0000-0000-0000-000000000000"
},
"target_url": "http://localhost:3000/projects/abc"
}'App-shape detection and instrumentation proposals (powers /cuit-instrument skill)
/v1/instrument/detect-shapeliveinstrumentDetect customer app shape (framework, state libs, selectors)
Used by the `/cuit-instrument` skill via the `cuit__detect_app_shape` MCP tool. Returns the structured shape so the proposal step can target the right files.
| field | type | notes |
|---|---|---|
| package_json* | object | Contents of the customer repo package.json |
| file_tree | string[] | Flat list of source file paths. |
| sample_files | object | Optional map of path → content for AST hints. |
| field | type | notes |
|---|---|---|
| framework* | "next.js" | "vite" | "cra" | "remix" | "astro" | "sveltekit" | "unknown" | — |
| router* | string | — |
| state_libs* | string[] | — |
| ui_libs* | string[] | — |
| test_runner* | string | — |
| pkg_manager* | "pnpm" | "npm" | "yarn" | "bun" | — |
| selectors_in_use* | object | — |
| candidate_state_files* | string[] | — |
| candidate_root_files* | string[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/v1/instrument/detect-shape' \
-H 'authorization: Bearer <YOUR_TENANT_TOKEN>' \
-H 'content-type: application/json' \
-d '{
"package_json": null,
"file_tree": [
"string"
],
"sample_files": null
}'/v1/instrument/proposeliveinstrumentGiven an app shape, propose the instrumentation diff
Used by the `/cuit-instrument` skill via `cuit__propose_instrumentation`. The returned operations[] is consumed by Claude Code's Edit/Write tools to apply the diff.
| field | type | notes |
|---|---|---|
| app_shape* | object | — |
| overrides | object | — |
| field | type | notes |
|---|---|---|
| operations* | object[] | — |
| npm_dependencies* | string[] | — |
| github_actions_secrets* | string[] | — |
| estimated_minutes* | integer | — |
| rationale* | string | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/v1/instrument/propose' \
-H 'authorization: Bearer <YOUR_TENANT_TOKEN>' \
-H 'content-type: application/json' \
-d '{
"app_shape": {
"framework": "next.js",
"router": "string",
"state_libs": [
"string"
],
"ui_libs": [
"string"
],
"test_runner": "string",
"pkg_manager": "pnpm",
"selectors_in_use": null,
"candidate_state_files": [
"string"
],
"candidate_root_files": [
"string"
]
},
"overrides": null
}'Per-tenant analytics (flake rate, bug-class distribution)
/v1/insights/flake-rateliveinsightsPer-spec flake rate over the last 28 days
Returns up to 20 specs ordered by flake rate descending. A spec with `reds`/`runs` close to 1.0 is highly unstable.
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| window* | string | — |
| flake_rates* | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/insights/flake-rate' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/insights/bug-class-distributionliveinsightsAggregate bug-class stats by component over a time window
| name | in | type | notes |
|---|---|---|---|
| window | query | string | — |
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| window* | string | — |
| classes* | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/insights/bug-class-distribution' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
Usage stats and Stripe subscription details
/v1/billing/usagelivebillingCurrent-period usage stats
Returns sessions, specs, runs, inference tokens, and estimated cost for the current billing period.
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| period_start* | string | — |
| period_end* | string | — |
| seats_active* | integer | — |
| sessions_uploaded* | integer | — |
| specs_generated* | integer | — |
| specs_run* | integer | — |
| inference_tokens* | integer | — |
| estimated_cost_usd* | number | — |
| tier* | "team" | "business" | "enterprise" | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/billing/usage' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/v1/billing/subscriptionlivebillingStripe subscription details for the current tenant
Returns subscription status + a link to the Stripe customer portal for self-service.
| field | type | notes |
|---|---|---|
| tenant* | string | — |
| stripe_subscription_id* | string | — |
| status* | "active" | "past_due" | "canceled" | "trialing" | — |
| tier* | "team" | "business" | "enterprise" | — |
| current_period_end* | string | — |
| cancel_at_period_end* | boolean | — |
| customer_portal_url* | string | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X GET 'http://localhost:7710/v1/billing/subscription' \ -H 'authorization: Bearer <YOUR_TENANT_TOKEN>'
/webhooks/stripelivebillingStripe webhook receiver
Stripe webhook receiver. NOT bearer-authenticated — signature verified via HMAC-SHA256 of the raw body against STRIPE_WEBHOOK_SECRET. Routes customer.subscription.created/deleted and invoice.payment_failed events to tenant updates and audit log entries.
| name | in | type | notes |
|---|---|---|---|
| stripe-signature* | header | string | — |
| field | type | notes |
|---|
| field | type | notes |
|---|---|---|
| received* | true | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
curl -X POST 'http://localhost:7710/webhooks/stripe' \
-H 'content-type: application/json' \
-d '{}'Unauthenticated endpoints — no bearer token required
/v1/public/signuplivepublicSelf-serve tenant signup
No authentication required. Creates a tenant (tier=team) and returns an initial bearer token in a single round-trip. Rate-limited to 3 signups per IP per rolling hour. The token is shown ONCE in the response — store it securely. PII (email, IP) is stored server-side for compliance and is never echoed back.
| field | type | notes |
|---|---|---|
| email* | string<email> | — |
| company_name* | string | — |
| requested_slug* | string | Lowercase slug for your tenant. Must start with a letter. |
| field | type | notes |
|---|---|---|
| tenant* | object | — |
| initial_token* | object | — |
| getting_started_url* | string<uri> | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| message | string | — |
| issues | object[] | — |
| field | type | notes |
|---|---|---|
| error* | string | — |
| retry_after_seconds* | integer | — |
curl -X POST 'http://localhost:7710/v1/public/signup' \
-H 'content-type: application/json' \
-d '{
"email": "dev@acme.com",
"company_name": "Acme Corp",
"requested_slug": "acme-corp"
}'POST /v1/sessions auto-triggers the LLM spec-gen pipeline (today: rule-based). Confidence threshold ≥ 0.75 enables auto-PR.POST /v1/specs/:id/run against a customer URL, returns RED or GREEN with structured step-level annotations.cuit__find_similar_sessions wires the pgvector query end-to-end. New endpoints land for app-shape detection + instrumentation proposal — see the /cuit-instrument skill.GET /v1/audit?since=...&until=... with streaming CSV export. Stripe billing webhooks. Rate limits per tier.api.cuit.dev is the production URL. SOC 2 evidence collection begins.