CXB API stores deployment-wide configuration in one MongoDB document, {_id: "system"} in system_settings. The settings API exposes scoped PUT endpoints (one per block), masks secrets on read, and invalidates the Redis settings cache on every write. The settings logic lives in the API service’s settings route, cache service, display-timezone service, and system-settings model.

Endpoints

All under /api/v1/settings. Reads/writes of secrets require super_admin; the display read is open to any role.
MethodPathRoleBlock updated
GETsuper_adminFull settings (secrets masked)
GET/displayanydisplay_timezone only
PUT/api-keyssuper_adminapi_keys.*
PUT/miniosuper_adminminio.*
PUT/agent-assistsuper_adminagent_assist.*
PUT/knowledgesuper_adminknowledge.*
PUT/diallersuper_admindialler.amd.*
PUT/timezonesuper_admindisplay_timezone
PUT/fleetsuper_admincore_fleet
The document is auto-created with defaults on first read (_get_or_create_settings).

Settings blocks

BlockKey fields (defaults)
api_keysOne key per configured provider: the STT engines, the TTS engines, and the language-model providers
minioendpoint (localhost:9000), access_key, secret_key, bucket (recordings), secure (false)
agent_assistenabled, stt_provider, llm_provider/model (<model-id>), system_prompt, suggestion_cooldown_seconds, max_context_messages, listen_to, publish_transcript
dialler.amdanswering-machine detection windows, action_on_machine (teardown), action_on_unknown (continue)
knowledgevectordb_url, vectordb_api_key, vectordb_collection (cxb_knowledge_chunks), embedding_model (<embedding-model>), embedding_dimensions (768), chunk_size_chars (1200), chunk_overlap_chars (180), max_upload_mb (20), tenant_id
core_fleetlist of CXB Core base URLs (see fleet routing)
display_timezoneIANA zone string, default UTC

Secret masking

GET /settings masks every secret-bearing field via _mask: short values become bullets, longer ones become first4••••••last4 (e.g. sk_a••••••cret). Masking covers all api_keys, minio.secret_key, and knowledge.vectordb_api_key.
On write, _strip_masked drops any field whose value contains the mask sentinel (••) and logs a warning — so a UI that round-trips a server-rendered placeholder can never overwrite a real secret with bullets. An explicit empty string "" is allowed through: clearing a field from the Settings page is treated as a deliberate action (e.g. switching storage backends).

Cache invalidation

Bot configs and system settings are cached in Redis (services/cache_service.py):
KeyTTLHelpers
bot:{bot_id}3600sget/set/invalidate_bot_cache
system:settings3600sget/set/invalidate_settings_cache
Every settings PUT calls invalidate_settings_cache(redis) after the Mongo write, so the next read repopulates from the database.
After editing settings or bot config directly in MongoDB (bypassing the API), you must clear the corresponding Redis key manually — direct DB writes do not trigger invalidate_*_cache.

Display timezone

services/display_timezone.py validates the configured zone with zoneinfo and falls back to UTC if invalid (normalise_display_timezone). It also provides start_of_display_day_utc (local midnight → UTC, used for day-bucketed metrics like Agent Desk) and parse_utc_datetime_filter for query date filters.

Fleet routing

The core_fleet list configured here.

KB pipeline

Consumes the knowledge block (vector database, embeddings, chunking).

Agent Assist

Uses the agent_assist block.

Agent Desk

Uses display-timezone day boundaries for metrics.