Skip to main content
SAFIA reads all configuration from a .env file in your installation directory. The safia setup wizard creates this file interactively, and safia config lets you edit individual values at any time. This page documents every supported variable.
Restart the bot after changing any variable for the new values to take effect:
safia restart

Required

These four variables must be set before the bot can start.
TELEGRAM_BOT_TOKEN
string
required
Your Telegram bot token, obtained from @BotFather. This authenticates the bot with the Telegram API.
TELEGRAM_BOT_TOKEN=7123456789:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LLM_API_KEY
string
required
API key for your chosen LLM provider. Used for all chat completions and receipt vision. See LLM Providers for per-provider instructions.
LLM_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
DATABASE_URL
string
default:"sqlite+aiosqlite:///data/safia.db"
Connection string for the database that stores transactions, debts, portfolios, and user data. Defaults to a local SQLite file — no setup required. For production use, you can point this at a PostgreSQL database.
# SQLite (default — zero configuration)
DATABASE_URL=sqlite+aiosqlite:///data/safia.db

# PostgreSQL
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/safia
REDIS_URL
string
default:"redis://localhost:6379/0"
Connection string for Redis, which handles chat history, rate limiting, and market data caching. The installer auto-installs and starts Redis on Linux and macOS.
REDIS_URL=redis://localhost:6379/0

LLM settings

LLM_PROVIDER
string
default:"lunos"
Which LLM provider to use for chat completions. Accepted values: lunos, groq, openai, custom.
LLM_PROVIDER=lunos
LLM_MODEL
string
default:"openai/gpt-oss-120b"
The model identifier sent to the LLM provider. The exact format depends on your provider — for example, Groq uses llama-3.3-70b-versatile while Lunos uses openai/gpt-oss-120b.
LLM_MODEL=openai/gpt-oss-120b
LLM_BASE_URL
string
Base URL for the LLM API. This is only required when LLM_PROVIDER=custom. Must point to an OpenAI-compatible /v1 endpoint.
LLM_BASE_URL=https://openrouter.ai/api/v1
VISION_MODEL
string
default:"mistralai/mistral-small-3.2-24b-instruct"
Model used for receipt and document photo scanning. Must support vision input. Uses the same provider and API key as LLM_PROVIDER.
VISION_MODEL=mistralai/mistral-small-3.2-24b-instruct
GROQ_API_KEY
string
API key for the Groq platform. This is always required for voice message transcription (Whisper via Groq), regardless of which LLM_PROVIDER you use for chat. If omitted, voice messages are disabled.
GROQ_API_KEY=gsk_xxxxxxxxxxxxxxxxxxxxxxxx
If you set LLM_PROVIDER=groq, your main LLM_API_KEY doubles as the Groq key for transcription — you do not need to set GROQ_API_KEY separately in that case.

Admin dashboard

ADMIN_USERNAME
string
Username for the admin dashboard at http://127.0.0.1:5454. The setup wizard defaults this to admin if you leave it blank. Leave both ADMIN_USERNAME and ADMIN_PASSWORD unset to disable authentication entirely.
ADMIN_USERNAME=admin
ADMIN_PASSWORD
string
Password for the admin dashboard. The setup wizard generates a random password if you leave the field blank. Set a strong value to protect the dashboard from unauthorized access.
ADMIN_PASSWORD=your-strong-password
FLASK_SECRET_KEY
string
Secret key used by the admin dashboard to sign session cookies. Set this to a long, random string. The setup wizard generates one automatically.
FLASK_SECRET_KEY=some-long-random-string

Knowledge base

The knowledge base uses Qdrant for vector storage and either local ONNX embeddings or a remote embedding API.
QDRANT_PATH
string
default:"data/qdrant"
Local filesystem path where Qdrant stores vector data. Used when QDRANT_URL is not set. No separate Qdrant server is required — vectors are stored directly on disk.
QDRANT_PATH=data/qdrant
QDRANT_URL
string
URL of a remote Qdrant instance. When set, this overrides QDRANT_PATH and SAFIA connects to the remote server instead of using local disk storage.
QDRANT_URL=http://127.0.0.1:6333
EMBEDDING_LOCAL
boolean
default:"true"
When true, SAFIA generates embeddings locally using the ONNX Runtime and the sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 model (~120 MB, downloads once). Set to false to use a remote embedding API instead.
EMBEDDING_LOCAL=true
EMBEDDING_BASE_URL
string
default:"https://api.lunosrouter.com/v1"
Base URL of the remote embedding API. Only used when EMBEDDING_LOCAL=false.
EMBEDDING_BASE_URL=https://openrouter.ai/api/v1
EMBEDDING_API_KEY
string
API key for the remote embedding provider. Falls back to LLM_API_KEY if not set. Only used when EMBEDDING_LOCAL=false.
EMBEDDING_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
EMBEDDING_MODEL
string
default:"openai/text-embedding-3-small"
Model name sent to the remote embedding API. Only used when EMBEDDING_LOCAL=false.
EMBEDDING_MODEL=openai/text-embedding-3-small
EMBEDDING_VECTOR_SIZE
integer
default:"384"
Dimensionality of the embedding vectors. Must match the output dimensions of your embedding model. The default 384 matches the local ONNX model. If you switch to text-embedding-3-small, set this to 1536.
EMBEDDING_VECTOR_SIZE=384
KB_CHUNK_WORDS
integer
default:"450"
Size of each document chunk in words when ingesting files into the knowledge base. Larger chunks preserve more context; smaller chunks improve retrieval precision.
KB_CHUNK_WORDS=450
KB_CHUNK_OVERLAP_WORDS
integer
default:"70"
Number of words that overlap between adjacent chunks. Overlap helps avoid splitting context across chunk boundaries.
KB_CHUNK_OVERLAP_WORDS=70
KB_MAX_UPLOAD_MB
integer
default:"200"
Maximum file size in megabytes for documents uploaded to the knowledge base via the admin dashboard.
KB_MAX_UPLOAD_MB=200

Bot behavior

REMINDER_ENABLED
boolean
default:"true"
Enables or disables the reminder system. When enabled, SAFIA can send scheduled price alerts, news digests, and portfolio summaries.
REMINDER_ENABLED=true
REMINDER_TICK_SECONDS
integer
default:"30"
How often (in seconds) the reminder scheduler checks for due reminders. Reduce this for faster reminder delivery at the cost of slightly higher CPU usage.
REMINDER_TICK_SECONDS=30
DAILY_MESSAGE_LIMIT
integer
default:"25"
Maximum number of messages a single user can send per day. Users who exceed this limit receive a rate-limit notice. Set to a higher value for less restrictive usage.
DAILY_MESSAGE_LIMIT=50