5.9 KiB
ICD-API — Chat Switchboard Backend API Contract
Version: 0.28.0 Updated: 2026-03-11 Audience: Frontend developers, integrators, API consumers
Organization principle: Each file is one domain — the complete story. Every endpoint that touches Knowledge Bases is in
knowledge.md, every endpoint that touches Personas is inpersonas.md, etc.
Files
| File | Domain | Endpoints |
|---|---|---|
| auth.md | Auth — login, register, refresh, OIDC, mTLS | 6 |
| channels.md | Channels, messages, completions, participants, folders, presence | ~35 |
| personas.md | Personas, persona groups, avatars, KB bindings, tool grants | ~20 |
| knowledge.md | Knowledge bases, documents, search, channel/persona bindings | ~12 |
| notes.md | Notes, wikilinks, graph, search, folders | ~10 |
| workspaces.md | Workspaces, file ops, git, credentials | ~20 |
| projects.md | Projects, channel/KB/note associations | ~14 |
| memory.md | Memory extraction, review, admin | 7 |
| providers.md | Provider configs, health, capabilities, routing policies | ~25 |
| models.md | Enabled models, user preferences | 4 |
| notifications.md | Notifications, preferences | 7 |
| extensions.md | Extensions, user settings, admin | 8 |
| profile.md | User profile, avatar, password, app settings | 7 |
| teams.md | Teams, members, groups, permissions, grants | ~25 |
| admin.md | Platform admin — users, settings, stats, audit, usage, vault | ~25 |
| utility.md | Health, export, files, storage | ~12 |
| workflows.md | Workflow definitions, stages, instances, assignments, entry | ~20 |
| tasks.md | Task definitions, runs, scheduler, team tasks | ~14 |
| surfaces.md | Surface registry, extension surfaces | 6 |
| websocket.md | WebSocket protocol, events, rooms | — |
| enums.md | All enum values, policies | — |
Conventions
Base URL
{scheme}://{host}{BASE_PATH}/api/v1
BASE_PATH is empty by default. In path-routed K8s deployments (e.g.
/staging/), all routes shift accordingly. The frontend reads BASE_PATH
from a <meta> tag injected by the Go template engine.
Authentication
JWT bearer tokens. Every request to a protected or admin route requires:
Authorization: Bearer {access_token}
Access token: HS256 JWT, 15-minute TTL. Claims: user_id, email,
role, exp, iat, jti.
Refresh token: Opaque, DB-stored, 7-day TTL. Used to obtain new access tokens without re-login.
WebSocket fallback: ?token={access_token} query parameter when
the Authorization header isn't available.
Cookie sync: On every token save/refresh, the frontend writes
sb_token as a cookie. Go template page routes read this cookie via
AuthOrRedirect middleware for server-rendered surfaces.
Auth Modes
| Mode | AUTH_MODE |
How it works |
|---|---|---|
| Builtin | builtin (default) |
Username/password, bcrypt, JWT |
| mTLS | mtls |
Reverse proxy cert headers, auto-provision |
| OIDC | oidc |
Authorization code flow (Keycloak etc.) |
All three modes issue the same JWT after authentication. Downstream middleware is auth-mode-agnostic.
Authorization Tiers
| Tier | Middleware | Who |
|---|---|---|
| Public | none | Anyone (health, login, register, public settings) |
| Session | AuthOrSession() |
JWT user OR anonymous session cookie (workflow visitors) |
| Authenticated | Auth() |
Any logged-in user |
| Permission | RequirePermission(perm) |
User whose groups grant perm |
| Team Admin | RequireTeamAdmin() |
Admin of the specific team |
| Platform Admin | RequireAdmin() |
Users with role = "admin" |
Error Envelope
All errors return:
{ "error": "human-readable message" }
Standard HTTP status codes: 400 (bad request), 401 (not authenticated), 403 (not authorized), 404 (not found), 409 (conflict), 500 (server error), 502 (upstream provider failure).
Pagination Envelope
Endpoints that paginate return:
{
"data": [...],
"page": 1,
"per_page": 50,
"total": 142,
"total_pages": 3
}
Query params: ?page=1&per_page=50. Not all list endpoints paginate —
some return { "data": [...] } or a bare array in a named key.
ID Format
All resource IDs are UUIDv4 strings, generated application-side via
store.NewID() (Go uuid.New()). This ensures compatibility across
both Postgres and SQLite backends.
Timestamps
ISO 8601 with timezone: "2025-06-15T14:30:00Z". Stored as
TIMESTAMPTZ (Postgres) or TEXT (SQLite).
Page Routes (Non-API)
Server-rendered Go template surfaces. Not REST endpoints — return HTML.
| Route | Surface | Description |
|---|---|---|
/login |
Login | Standalone login/register page |
/ |
Chat | Main chat interface |
/chat/:chatID |
Chat | Chat with specific channel loaded |
/editor |
Editor | Workspace file editor |
/editor/:wsId |
Editor | Editor with specific workspace |
/notes |
Notes | Notes interface |
/notes/:noteId |
Notes | Notes with specific note loaded |
/admin |
Admin | Platform administration |
/admin/:section |
Admin | Admin with specific section |
/settings |
Settings | User settings |
/settings/:section |
Settings | Settings with specific section |
/w/:id |
Workflow Landing | Branded workflow entry page |
/w/:id/:slug |
Workflow Landing | Slug-suffixed workflow entry |
/s/:slug |
Extension Surface | Dynamic surface from registry |
All page routes (except /login, /w/) require authentication via
AuthOrRedirect middleware. Admin routes additionally require
RequireAdminPage(). Workflow landing pages use AuthOrSession.