156 lines
5.9 KiB
Markdown
156 lines
5.9 KiB
Markdown
# 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 in `personas.md`, etc.
|
|
|
|
## Files
|
|
|
|
| File | Domain | Endpoints |
|
|
|------|--------|-----------|
|
|
| [auth.md](auth.md) | Auth — login, register, refresh, OIDC, mTLS | 6 |
|
|
| [channels.md](channels.md) | Channels, messages, completions, participants, folders, presence | ~35 |
|
|
| [personas.md](personas.md) | Personas, persona groups, avatars, KB bindings, tool grants | ~20 |
|
|
| [knowledge.md](knowledge.md) | Knowledge bases, documents, search, channel/persona bindings | ~12 |
|
|
| [notes.md](notes.md) | Notes, wikilinks, graph, search, folders | ~10 |
|
|
| [workspaces.md](workspaces.md) | Workspaces, file ops, git, credentials | ~20 |
|
|
| [projects.md](projects.md) | Projects, channel/KB/note associations | ~14 |
|
|
| [memory.md](memory.md) | Memory extraction, review, admin | 7 |
|
|
| [providers.md](providers.md) | Provider configs, health, capabilities, routing policies | ~25 |
|
|
| [models.md](models.md) | Enabled models, user preferences | 4 |
|
|
| [notifications.md](notifications.md) | Notifications, preferences | 7 |
|
|
| [extensions.md](extensions.md) | Extensions, user settings, admin | 8 |
|
|
| [profile.md](profile.md) | User profile, avatar, password, app settings | 7 |
|
|
| [teams.md](teams.md) | Teams, members, groups, permissions, grants | ~25 |
|
|
| [admin.md](admin.md) | Platform admin — users, settings, stats, audit, usage, vault | ~25 |
|
|
| [utility.md](utility.md) | Health, export, files, storage | ~12 |
|
|
| [workflows.md](workflows.md) | Workflow definitions, stages, instances, assignments, entry | ~20 |
|
|
| [tasks.md](tasks.md) | Task definitions, runs, scheduler, team tasks | ~14 |
|
|
| [surfaces.md](surfaces.md) | Surface registry, extension surfaces | 6 |
|
|
| [websocket.md](websocket.md) | WebSocket protocol, events, rooms | — |
|
|
| [enums.md](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:
|
|
|
|
```json
|
|
{ "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:
|
|
|
|
```json
|
|
{
|
|
"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`.
|