Skip to content

Environment variables

The canonical annotated list lives in .env.example. This page groups them by which app or package owns validation.

For the must-set subset, see Self-hosting → Environment variables.

App-level env vars belong to the app itself — its bind port, its database connection, its frontend origin. Each app parses process.env once at boot via a zod schema in apps/<app>/src/config/env.ts and exits with a clear error listing every failing variable.

VariableRequired in prodPurpose
DATABASE_URLyesPostgres 16+ connection string
REDIS_URLyesRedis 7+ connection string
BETTER_AUTH_SECRETyes32+ chars; rotates every session if changed
JOBS_HMAC_SECRETyesShared secret for HMAC-gated job admin endpoints
FRONTEND_URLyesBrowser-visible frontend origin (CORS + cookies)
BACKEND_URLyesBrowser-visible api origin
SCANI_CLOUD_URLyesWhere the data-provider lives
SCANI_CLOUD_API_KEYyesBearer token the api presents to the data-provider
LOG_ID_PEPPERyesPepper for log-id hashing
SENTRY_DSNnoBackend Sentry DSN; no DSN ⇒ SDK is a no-op

Same DB / Redis / Sentry / cloud-URL set as the api; plus shares ENCRYPTION_KEY for credential decryption.

VariableRequired in prodPurpose
DATABASE_URLyesPostgres connection
DATA_PROVIDER_API_KEYyesBearer the api + worker must present
VariableRequired in prodPurpose
VITE_BACKEND_URLyesBrowser-visible api origin
VITE_SENTRY_DSNnoFrontend Sentry DSN; no DSN ⇒ SDK no-op

Apps that depend on a package do not redeclare that package’s env vars in their own schema. The package owns validation; the app just sets the env var and trusts the package’s loader.

VariableRequired in prodPurpose
ENCRYPTION_KEYyes32 hex chars; must match between api and worker

Refuses to start in production without a key. Used to AES-256-GCM encrypt per-user provider credentials at rest.

VariableRequired in prodPurpose
S3_ENDPOINTyesS3-compatible endpoint URL
S3_REGIONyesRegion (any string; some providers ignore it)
S3_BUCKETyesBucket name
S3_ACCESS_KEY_IDyesAccess key
S3_SECRET_ACCESS_KEYyesSecret key

Either Fastmail JMAP or SMTP — set one block, not both.

VariableRequired in prodPurpose
FASTMAIL_API_TOKENconditionalFastmail JMAP delivery
SMTP_URLconditionalSMTP server URL
SMTP_FROMconditionalFrom: address for outbound mail

Optional. Each one unlocks specific functionality. The corresponding tRPC router returns a PRECONDITION_FAILED error at call-time if unset.

VariableUnlocks
COINGECKO_API_KEYCoinGecko pricing
FINNHUB_API_KEYFinnhub pricing
OPENAI_API_KEYScreenshot parsing
PERPLEXITY_API_KEY, DEEPSEEK_API_KEYToken-identity backfill
ETHERSCAN_API_KEYEVM wallet balances (all EVM chains)
HELIUS_API_KEYSolana balances
BINANCE_OAUTH_CLIENT_ID / BINANCE_OAUTH_CLIENT_SECRET / BINANCE_OAUTH_REDIRECT_URIBinance OAuth exchange connection