What you can do#
The client engagement chat provides a private, branded chat portal for individual clients. Each client gets a dedicated endpoint that draws on client-specific knowledge documents, with answers grounded in engagement materials relevant to that client.
| Capability | Description | Status |
|---|---|---|
| Per-client portal | Unique URL per client slug | Shipped |
| Vector retrieval | Semantic search across client knowledge documents | Shipped |
| Filesystem fallback | Works without a database using local markdown files | Shipped |
| Token authentication | Simple token-based access control | Shipped |
| Streaming chat | Real-time SSE streaming responses | Shipped |
| Conversation limits | Turn cap and message length validation | Shipped |
How it works#
Each client portal is accessed via a unique URL:
POST /api/clients/<client-slug>/chat?token=<portal-token>
When a user sends a message:
- The portal token is verified against
CLIENT_PORTAL_TOKEN - The client slug is checked against known client portals (filesystem or database)
- The latest user query is embedded and matched against the client's knowledge documents using vector similarity search
- The AI generates a streaming response grounded in the retrieved engagement materials
Knowledge sources#
Client knowledge can come from two sources:
Markdown files (filesystem)#
Place markdown files in docs/clients/<client-slug>/ with
numbered prefixes (e.g., 01-overview.md, 02-roadmap.md).
These are loaded directly when the database is unavailable.
Vector store (database)#
For production use, sync client documents into the
client_knowledge_documents table. Documents are chunked and
embedded for semantic retrieval, providing more relevant results
than full-document injection.
info The vector store is preferred when available. If no synced documents exist for a client, the system falls back to reading markdown files from the filesystem automatically.
Configuration#
| Variable | Description |
|---|---|
CLIENT_PORTAL_TOKEN | Shared token for portal access (required) |
SIDEKICK_PUBLIC_API_KEY | API key for the AI model (required) |
SIDEKICK_PUBLIC_VECTOR_API_KEY | API key for embeddings (falls back to OPENAI_API_KEY) |
Limits#
- Conversation turns -- maximum 10 turns per session
- Message length -- 2,000 characters per message
- Retrieval results -- top 6 chunks above 0.6 similarity threshold
Security#
- Token-gated access -- every request requires a valid portal token as a query parameter
- Client isolation -- each client slug resolves to its own knowledge set; cross-client access is not possible
- Safe file patterns -- only numbered markdown files matching the expected naming convention are loaded from the filesystem
warning The
CLIENT_PORTAL_TOKENis a shared secret. Treat it like an API key and rotate it if it may have been exposed.