Configuration Reference
All settings are configured via environment variables with the CHATINBIO_ prefix. Copy .env.example to .env to get started.
Database
| Variable | Default | Description |
|---|---|---|
CHATINBIO_DATABASE_URL | sqlite+aiosqlite:///./chatinbio.db | SQLAlchemy async database URL |
Security
| Variable | Default | Description |
|---|---|---|
CHATINBIO_SECRET_KEY | (must be set) | Used to derive the Fernet encryption key for integration credentials. The app refuses to start with the default value. |
CHATINBIO_ADMIN_API_KEY | (must be set) | Bearer token for all /api/admin/* endpoints. The app refuses to start with the default value. |
CHATINBIO_TURNSTILE_SECRET_KEY | (empty) | Cloudflare Turnstile secret key. When set, WebSocket connections require a valid token |
CHATINBIO_TURNSTILE_SITE_KEY | (empty) | Cloudflare Turnstile site key (passed to frontend) |
The app validates SECRET_KEY and ADMIN_API_KEY at startup. If either is left at the default placeholder or set to common insecure values (changeme, secret, admin, empty), the app will refuse to start with a clear error message.
Generate secure values:
python -c "import secrets; print(secrets.token_urlsafe(32))"
CORS
| Variable | Default | Description |
|---|---|---|
CHATINBIO_ALLOWED_ORIGINS | [] (same-origin only) | JSON list of allowed CORS origins. Set to ["*"] to allow all origins (not recommended for production). |
Example:
CHATINBIO_ALLOWED_ORIGINS=["https://chtbio.com","https://www.chtbio.com"]
Webhook Secrets
| Variable | Default | Description |
|---|---|---|
CHATINBIO_GUMROAD_WEBHOOK_SECRET | (empty) | HMAC-SHA256 secret for Gumroad webhook signature verification |
CHATINBIO_LEANPUB_WEBHOOK_SECRET | (empty) | HMAC-SHA256 secret for Leanpub webhook signature verification |
When a webhook secret is configured, incoming webhook requests must include a valid x-gumroad-signature or x-leanpub-signature header. Requests with missing or invalid signatures are rejected with HTTP 401.
LLM Providers
Set at least one. The bot config's model_provider determines which key is used at runtime.
| Variable | Default | Description |
|---|---|---|
CHATINBIO_ANTHROPIC_API_KEY | (empty) | Anthropic API key |
CHATINBIO_OPENAI_API_KEY | (empty) | OpenAI API key |
CHATINBIO_GOOGLE_AI_API_KEY | (empty) | Google AI (Gemini) API key |
CHATINBIO_OPENROUTER_API_KEY | (empty) | OpenRouter API key (access 100+ models) |
Google OAuth
Optional. Required for Google Calendar/Meet integration.
| Variable | Default | Description |
|---|---|---|
CHATINBIO_GOOGLE_OAUTH_CLIENT_ID | (empty) | OAuth 2.0 client ID |
CHATINBIO_GOOGLE_OAUTH_CLIENT_SECRET | (empty) | OAuth 2.0 client secret |
Rate Limits
| Variable | Default | Description |
|---|---|---|
CHATINBIO_RATE_LIMIT_PER_MINUTE | 60 | Global HTTP rate limit |
CHATINBIO_SESSION_MESSAGE_LIMIT | 30 | Max messages per visitor per hour (survives reconnects) |
CHATINBIO_DAILY_TOKEN_BUDGET | 100000 | Daily LLM token budget |
Settings class
All settings are loaded by the Settings class in src/chatinbio/settings.py using pydantic-settings. The model_config uses env_prefix = "CHATINBIO_", so every setting maps to a CHATINBIO_* environment variable.
The fernet_key property derives a Fernet encryption key from secret_key using SHA-256. This is used to encrypt integration credentials stored in the database.