Reference

HTTP API, CLI and observability

Every endpoint group, the uniform error shape, the zaanix CLI, Prometheus metrics and OpenTelemetry traces.

HTTP API#

All API routes live under /api and take Authorization: Bearer <jwt> (UI sessions) or Authorization: Bearer zx_… (API tokens).

AreaEndpoints
AuthPOST /api/auth/login · POST /api/auth/register · GET /api/auth/me · POST /api/auth/password · GET /api/auth/oidc/login · GET /api/auth/oidc/callback
WorkspacesGET/POST /api/workspaces · GET/PATCH/DELETE /api/workspaces/:id · POST /api/workspaces/:id/restart · …/tabs CRUD (per user)
SharingGET/PUT /api/workspaces/:id/members · DELETE …/members/:memberId · POST …/leave · POST …/transfer · GET /api/users/directory · GET/POST /api/groups · PATCH/DELETE /api/groups/:id · GET/PUT /api/groups/:id/members · DELETE …/members/:userId
Storage explorerGET/POST/DELETE /api/workspaces/:id/folders · GET /api/storage/browse · GET /api/storage/local · GET /api/storage/cloud · POST /api/storage/inspect
Cloud connectionsGET /api/cloud-connections/providers · GET/POST/PATCH/DELETE /api/cloud-connections · POST /api/cloud-connections/:id/test
ExportsPOST /api/workspaces/:id/export {sql, format: parquet|csv|json|arrow} · GET /api/exports · GET /api/exports/:id/download · DELETE /api/exports/:id
BI…/queries CRUD · …/dashboards CRUD (kind: grid|mosaic, spec) · GET/PATCH/DELETE /api/dashboards/:id (layout, spec) · POST/PATCH/DELETE /api/dashboards/:id/widgets[/:wid] · POST /api/dashboards/:id/widgets/:wid/data
ConnectionsGET /api/sources/catalog · GET /api/sources · GET/POST /api/database-connections · PATCH/DELETE /api/database-connections/:id · POST …/:id/test · GET …/:id/browse · GET/POST /api/workspaces/:id/syncs · POST …/syncs/preview · GET/PATCH/DELETE /api/syncs/:id · POST /api/syncs/:id/run · GET /api/syncs/:id/runs
Data appsGET /api/apps/templates · GET /api/apps · GET/POST /api/workspaces/:id/apps · GET/PATCH/DELETE /api/apps/:id · POST /api/apps/:id/start|stop|restart · GET /api/apps/:id/logs · POST /api/apps/:id/session (cookie for /apps) · the app itself at /apps/:id/
ConnectorsGET /api/connectors · GET/POST /api/connector-connections · PATCH/DELETE /api/connector-connections/:id · POST …/:id/test · GET …/:id/browse?path=a/b · POST …/:id/query {sql, limit?} · POST /api/oauth/google/start · GET /api/oauth/google/callback · admin GET/PUT/DELETE /api/admin/integrations/google
MosaicPOST /api/workspaces/:id/mosaic {type: arrow|json|exec, sql} (Arrow IPC / JSON reads with ETag; admitted plumbing statements) · POST /api/workspaces/:id/mosaic/prepare {spec | spec_text} (validate + bind a spec) · GET /api/mosaic/info
DataPOST /api/workspaces/:id/files (multipart upload) · DELETE /api/workspaces/:id/files?path= · POST /api/workspaces/:id/overview · GET /api/workspaces/:id/catalog
QueryPOST /api/workspaces/:id/query · /explain · /profile · /save · WS /api/ws/query (auth → run/cancel; schema → rows* → done)
Cachequery, explain, profile, overview, storage/inspect and widget data are conditional (ETag / If-None-Match → 304, refresh: true) · DELETE /api/workspaces/:id/cache · POST /api/admin/cache/clear
LiveWS /api/ws/events — audit rows, MCP tool invocations, session and workspace-epoch events in real time · GET /api/system/live — CPU, RAM, duckdb_memory() per engine, disk usage, cache stats
AgentsGET/POST/DELETE /api/tokens · GET /api/mcp/sessions · GET /api/mcp/info · /api/agents… · GET /api/agent/openapi.json · GET/POST /api/agent/v1/tools[/:tool]
LakehouseGET /api/lakehouse/providers · /api/lakehouse-connections… · GET /api/lakehouse/browse · GET /api/lakehouse/:id/inspect · POST /api/lakehouse/:id/query · POST /api/lakehouse/:id/materialize
AIGET /api/ai/status · GET /api/ai/providers · GET/PUT/DELETE /api/ai/settings (administrators) · GET/PUT/DELETE /api/ai/own-key · GET /api/ai/usage · POST /api/agent/assist {kind, input} (inline actions)
OpsGET /api/system · GET /api/audit · GET/POST/PATCH/DELETE /api/admin/users · GET /api/admin/engines · POST /api/admin/engines/:id/evict · GET /api/admin/config
ProbesGET /healthz · GET /readyz · GET /metrics

Errors#

Uniform JSON: { error, message, request_id, challenge? }.

StatuserrorWhen
400SQL_ERROR, BAD_REQUEST, VALIDATION_ERRORDuckDB parser/binder errors, bad input
403SANDBOX_VIOLATION, FORBIDDENPath or extension outside policy; role or scope too low
404NOT_FOUNDAlso for workspaces the caller has no grant on
408QUERY_TIMEOUTInterrupted at the workspace timeout
409APPROVAL_REQUIREDAgent mutation held for a human (with the challenge)
429RATE_LIMITEDGlobal and per-route limits

CLI#

zaanix serve [--port] [--host]
zaanix mcp [--token zx_…|--user email] [--workspace id]
zaanix migrate
zaanix create-user --email … --password … [--role ADMIN|USER|READ_ONLY]
zaanix create-token --email … --name … [--scopes read,write,mcp] [--workspace id] [--days n]
zaanix config

In the image the binary is /app/server/dist/cli.js, so docker exec zaanix node /app/server/dist/cli.js create-user --email ….

Observability#

  • Logs: pino structured JSON (pretty in dev TTYs), x-request-id propagated.
  • Metrics (/metrics): zaanix_queries_total{actor,class,status}, zaanix_query_duration_seconds, zaanix_query_rows_returned, zaanix_active_queries, zaanix_engines_active, zaanix_mcp_connections_active{transport}, zaanix_mcp_tool_calls_total{tool,status}, zaanix_mcp_tool_duration_seconds, zaanix_mcp_hitl_challenges_total, zaanix_sandbox_violations_total{actor}, zaanix_ws_connections_active, zaanix_cache_lookups_total{kind,result}, zaanix_cache_bytes, zaanix_cache_entries, zaanix_copilot_*, host/DuckDB memory gauges, plus Node process defaults.
  • Traces: duckdb.query and mcp.tool.<name> spans (db.system, db.statement, workspace, actor, statement class) via OpenTelemetry; exported over OTLP/HTTP when observability.otel.enabled.
  • Probes: /healthz (liveness) and /readyz (metadata store, data directory, DuckDB).