Skip to Content
API ReferenceHTTP API Reference

HTTP API Reference

Base URL: http://<host>:8080
Version prefix: /v1

Route Map

Health and status

  • GET /health (localhost-only)
  • GET /v1/api/healthcheck (localhost-only)
  • GET /v1/api/cluster/health (localhost-only)

SQL and files

  • POST /v1/api/sql
  • GET /v1/files/{namespace}/{table_name}/{subfolder}/{file_id}

WebSocket

  • GET /v1/ws

Auth

  • POST /v1/api/auth/login
  • POST /v1/api/auth/refresh
  • POST /v1/api/auth/logout
  • GET /v1/api/auth/me
  • POST /v1/api/auth/setup
  • GET /v1/api/auth/status

Topic HTTP API

  • POST /v1/api/topics/consume
  • POST /v1/api/topics/ack

Authentication Rules

Bearer token required

Authorization: Bearer <JWT_TOKEN>
  • POST /v1/api/sql
  • GET /v1/files/...
  • POST /v1/api/topics/consume
  • POST /v1/api/topics/ack

Basic auth is rejected on these endpoints.

  • POST /v1/api/auth/refresh
  • GET /v1/api/auth/me

Public endpoints

  • POST /v1/api/auth/login
  • POST /v1/api/auth/logout
  • POST /v1/api/auth/setup (localhost-only unless auth.allow_remote_setup = true)
  • GET /v1/api/auth/status (localhost-only unless remote setup enabled)
  • GET /health and GET /v1/api/healthcheck (localhost-only)
  • GET /v1/api/cluster/health (localhost-only)

SQL Endpoint

POST /v1/api/sql

Headers:

  • Authorization: Bearer <JWT_TOKEN>
  • Content-Type: application/json or multipart/form-data

JSON body

{ "sql": "SELECT * FROM app.messages WHERE id = $1", "params": [123], "namespace_id": "app" }

Multipart body for FILE(...)

Parts:

  • sql
  • params (optional JSON array string)
  • namespace_id (optional)
  • file parts named file:<placeholder>

SQL:

INSERT INTO app.docs (id, attachment) VALUES ('d1', FILE("contract"));

Multipart file key must be file:contract.

Success shape

{ "status": "success", "results": [ { "schema": [{"name":"id","data_type":"BigInt","index":0}], "rows": [[1]], "row_count": 1, "as_user": "alice" } ], "took": 12.3 }

Error shape

{ "status": "error", "results": [], "took": 1.2, "error": { "code": "INVALID_SQL", "message": "...", "details": null } }

Common SQL error codes

  • INVALID_SQL
  • PERMISSION_DENIED
  • TABLE_NOT_FOUND
  • RATE_LIMIT_EXCEEDED
  • NOT_LEADER
  • CLUSTER_UNAVAILABLE
  • FILE_TOO_LARGE
  • TOO_MANY_FILES
  • INVALID_MIME_TYPE

File Download

GET /v1/files/{namespace}/{table_name}/{subfolder}/{file_id}

  • bearer token required
  • optional user_id query parameter for user-table scope resolution
  • SYSTEM and STREAM tables are rejected for file paths

Response:

  • 200 with binary content
  • 400/403/404 for validation, permission, or not-found failures

Auth Endpoints

POST /v1/api/auth/login

{ "username": "alice", "password": "Secret123!" }

Returns user profile + access/refresh tokens and sets auth cookie.

POST /v1/api/auth/refresh

Accepts bearer token or cookie. Returns rotated token pair.

POST /v1/api/auth/logout

Clears auth cookie.

GET /v1/api/auth/me

Returns current authenticated user info.

POST /v1/api/auth/setup

Initial bootstrap only, when root has no password yet.

{ "username": "admin", "password": "AdminPass123!", "root_password": "RootPass123!", "email": "admin@example.com" }

Sets root password and creates the DBA user. Does not auto-login.

GET /v1/api/auth/status

Returns setup status:

{ "needs_setup": true, "message": "Server requires initial setup..." }

Topic Endpoints

Both require bearer auth and role in {service, dba, system}.

POST /v1/api/topics/consume

{ "topic_id": "orders_topic", "group_id": "worker_group", "start": "Latest", "limit": 100, "partition_id": 0, "timeout_seconds": 10 }

Accepted start formats:

  • "Latest"
  • "Earliest"
  • { "Offset": 123 }

POST /v1/api/topics/ack

{ "topic_id": "orders_topic", "group_id": "worker_group", "partition_id": 0, "upto_offset": 10 }

Health Endpoints

GET /health and GET /v1/api/healthcheck return the same payload and are localhost-only:

{ "status": "healthy", "version": "...", "api_version": "v1", "build_date": "..." }

For live protocol details, continue to WebSocket Protocol.

Last updated on