The API reads its configuration from environment variables. It also loads apps/api/.env if present; real environment variables take precedence. apps/api/.env.example lists the common ones.
production turns on the checks above, disables dev routes and dev sign-in, and changes the TRUST_PROXY default. test is used by the test suite. Anything else means development.
PORT
3001
Port the API listens on.
APP_URL
http://localhost:5173
Yes
Public URL of the app, used in email links, Stripe return URLs and the Microsoft admin-consent redirect. In production the API serves the app itself, so this is the API’s public URL.
TRUST_PROXY
1 in production, loopback otherwise
Express trust proxy. A number means that many proxy hops; otherwise an Express value such as loopback or an IP/subnet list. Determines the client IP that’s logged and rate-limited.
WEB_DIST
apps/web/dist
Folder of the built web app. If it has no index.html, the API serves only /api.
LOG_LEVEL
info
Log level for the API’s JSON (pino) logs.
MIGRATE_ON_START
Outside production, migrations always run on start. In production they run on start only when this is true. See Database.
Signs session tokens and the Microsoft admin-consent state. Generate with openssl rand -hex 32.
SIGNING_LINK_SECRET
SESSION_SECRET
Recommended
Derives the personal links in signing emails. Set it to its own random value so you can rotate SESSION_SECRET without affecting signing requests. See the warning below.
The marketing site’s contact form posts to /api/contact, which checks a Cloudflare Turnstile token and emails the message to BRAND.salesEmail or BRAND.supportEmail (with the visitor as Reply-To). Create a Turnstile widget for the marketing site’s hostname in the Cloudflare dashboard; it gives you a site key (for the marketing build, PUBLIC_TURNSTILE_SITE_KEY) and a secret key (for the API).
Variable
Default
Required in production
Notes
TURNSTILE_SECRET_KEY
Cloudflare’s always-pass test secret outside production
Yes
Secret key of the Turnstile widget.
MARKETING_URL
http://localhost:4321 outside production
Yes
Origin of the marketing site, e.g. https://www.example.com. Only this origin may call /api/contact from a browser. Separate several with commas.