HTTP API Reference
Base URL: http://<host>:2900
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/sqlGET /v1/files/{namespace}/{table_name}/{subfolder}/{file_id}
WebSocket
GET /v1/ws
Auth
POST /v1/api/auth/loginPOST /v1/api/auth/refreshPOST /v1/api/auth/logoutGET /v1/api/auth/mePOST /v1/api/auth/setupGET /v1/api/auth/status
Topic HTTP API
POST /v1/api/topics/consumePOST /v1/api/topics/ack
Authentication Rules
Bearer token required
Authorization: Bearer <JWT_TOKEN>POST /v1/api/sqlGET /v1/files/...POST /v1/api/topics/consumePOST /v1/api/topics/ack
Basic auth is rejected on these endpoints.
Cookie or bearer accepted
POST /v1/api/auth/refreshGET /v1/api/auth/me
Public endpoints
POST /v1/api/auth/loginPOST /v1/api/auth/logoutPOST /v1/api/auth/setup(localhost-only unlessauth.allow_remote_setup = true)GET /v1/api/auth/status(localhost-only unless remote setup enabled)GET /healthandGET /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/jsonormultipart/form-data
JSON body
{ "sql": "SELECT * FROM app.messages WHERE id = $1", "params": [123], "namespace_id": "app"}namespace_id applies only to that request. Interactive clients such as the
CLI can store the namespace locally after a successful USE namespace and send
it again on later requests.
Multipart body for FILE(...)
Parts:
sqlparams(optional JSON array string)namespace_id(optional request-scoped default namespace)- 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_SQLPERMISSION_DENIEDTABLE_NOT_FOUNDRATE_LIMIT_EXCEEDEDNOT_LEADERCLUSTER_UNAVAILABLEFILE_TOO_LARGETOO_MANY_FILESINVALID_MIME_TYPE
File Download
GET /v1/files/{namespace}/{table_name}/{subfolder}/{file_id}
- bearer token required
- optional
user_idquery parameter for user-table scope resolution SYSTEMandSTREAMtables are rejected for file paths
Response:
200with binary content400/403/404for validation, permission, or not-found failures
Auth Endpoints
POST /v1/api/auth/login
{ "user": "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.
{ "user": "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.