Skip to content

Web HTTP API

The web service (karet) hosts both the UI and the JSON API the UI talks to. Every /api/* route enforces auth except the explicitly-public ones below.

Auth

EndpointAuthPurpose
GET /api/auth/setuppublicReturns { needsSetup: boolean } so the login page knows which form to show.
POST /api/auth/setuppublic, single-shotBody { password }. Refuses if an admin already exists.
POST /api/auth/loginpublicBody { password }. Sets the session cookie on success.
POST /api/auth/logoutsessionClears the session cookie.
GET /api/auth/mesessionReturns { authenticated: true }.
PATCH /api/auth/mesessionBody { currentPassword, newPassword }. Re-issues the cookie.

Pipelines

EndpointPurpose
GET /api/pipelinesList pipeline slugs.
POST /api/pipelinesBody { slug, template }. Provisions a new pipeline from a template.
POST /api/pipelines/importMultipart upload of a .zip exported from another instance.
DELETE /api/pipelines/[slug]Delete every object under pipelines/<slug>/.
PATCH /api/pipelines/[slug]Body { newSlug }. Renames by copy-then-delete.

Per-pipeline

EndpointPurpose
GET /api/p/[pipeline]/configFetch pipeline.json. Returns the parsed body and the S3 ETag in a Last-Modified style header.
PUT /api/p/[pipeline]/configReplace pipeline.json. Honors If-Match: <etag> for optimistic concurrency.
POST /api/p/[pipeline]/validateForward to the worker's /config/validate.
GET /api/p/[pipeline]/dashboardsList dashboard names.
GET /api/p/[pipeline]/dashboards/[name]Fetch a single dashboard config.
GET /api/p/[pipeline]/tablesPer-table metadata: name, schema, file count.
GET /api/p/[pipeline]/tables/[table]/rowsStream the table's rows (parses every Parquet file under the prefix).
GET /api/p/[pipeline]/jobsJob history with orphan reconciliation (running jobs older than 10 min get marked failed).
POST /api/p/[pipeline]/jobs?clean=trueTrigger a manual run. Returns the initial running record immediately; the worker call happens in the background.
GET /api/p/[pipeline]/previewDashboard thumbnail (PNG). Returns a 1×1 transparent fallback if missing.
PUT /api/p/[pipeline]/previewUpload a thumbnail PNG. Used by the graph page's auto-capture.
HEAD /api/p/[pipeline]/preview200 if a real thumbnail exists, 404 otherwise.
GET /api/p/[pipeline]/exportStream a .zip of every object under the slug.

Webhooks

EndpointAuthPurpose
POST /api/events/s3shared secretRustFS S3-event receiver. See Auto-runs.

Auth shapes

The middleware (middleware.ts) accepts requests authenticated via:

  1. The karet_session cookie set by /api/auth/login or /api/auth/setup.
  2. KARET_API_KEY in either X-API-Key or Authorization: Bearer <key>.

/api/auth/* and /api/events/* bypass the middleware and handle their own auth: the auth routes are public, and the events route checks a shared webhook secret.

Error shape

Most routes return a JSON error body on 4xx/5xx:

json
{ "error": "<machine_code>", "message": "Human-readable detail" }

Common codes:

CodeMeaning
unauthorizedMissing/invalid session or API key.
bucket_not_foundThe S3 bucket doesn't exist. Most-common cause: S3_BUCKET mistype.
s3_errorCatch-all for everything else from the S3 SDK.
pipeline_config_not_foundThe slug exists but its pipeline.json is missing.
dashboard_not_foundThe slug exists but no dashboard at the given name.
invalid_slugThe slug failed sanitization.
already_existsTrying to create or rename onto an existing slug.

MIT licensed