| Database Configuration | | |
| DATABASE_URL | Yes | PostgreSQL database connection URL. Can be configured to use connection poolers like PgBouncer or Prisma Accelerate. This is the main connection URL used by your application. Both DATABASE_URL and DATABASE_DIRECT_URL must be configured. |
| DATABASE_DIRECT_URL | Yes | Direct PostgreSQL database connection URL. Required when using connection poolers in DATABASE_URL. Used by Prisma CLI commands that need direct database access (like migrations, schema pushes, and introspection). Both DATABASE_URL and DATABASE_DIRECT_URL must be configured. |
| Server Configuration | | |
| NEST_SERVER_PORT | No | NestJS server port, default is 3000 |
| NODE_ENV | Yes | Node.js environment |
| Email Service Configuration | | |
| EMAIL_HOST | Yes | Email server address |
| EMAIL_PORT | Yes | Email server port |
| EMAIL_USER | Yes | Email service account |
| EMAIL_PASS | Yes | Email service password |
| Important: Email service configuration is required for user registration and member invitation features. Without proper email configuration, these features will not be available. | | |
| Redis Configuration | | |
| Redis_HOST | Yes | Redis server address |
| Redis_PORT | Yes | Redis server port |
| Redis_PASS | No | Redis server password |
| Application Configuration | | |
| APP_HOMEPAGE_URL | Yes | Application homepage URL |
| API_URL | No | The instance’s public base URL (e.g. https://usertour.example.com). The OAuth/MCP discovery metadata and the API/MCP URLs shown in Settings use it when set, and are derived per request from forwarded headers (Host / X-Forwarded-Proto) when unset — set it to pin them when a proxy chain sits in front of the instance. The OIDC SSO callback is never request-derived (this value or SSO_CALLBACK_URL, only); the GitHub/Google callbacks also default to it but fall back to per-request resolution when neither is set — so set it in production to keep the registered callbacks stable. |
| MCP_SERVER_URL | No | Full public MCP endpoint (e.g. https://api.example.com/mcp); defaults to <API_URL>/mcp when unset. Drives the Settings → MCP display and the OAuth discovery metadata / 401 challenge together — set it whenever MCP is served on its own domain, and make sure that domain also proxies /oauth/* and /.well-known/oauth-* (the shipped nginx config does). |
| API_THROTTLE_TTL | No | v2 API rate-limit window in milliseconds, default 60000 (1 minute) |
| API_THROTTLE_LIMIT | No | v2 API requests allowed per window for authenticated tokens on self-hosted deployments, default 1000 (Cloud plans use their plan tier instead) |
| API_THROTTLE_FALLBACK_LIMIT | No | v2 API requests allowed per window per IP for unauthenticated or invalid-token requests, default 100 |
| TRUST_PROXY | No | Express trust proxy — which upstream proxies to believe when resolving the client IP and protocol. The client IP feeds both the per-IP rate-limit bucket and the actor IP recorded in the audit log. Default loopback trusts only the bundled nginx in the same container; every other peer — including private-network addresses — counts as the client itself, so neither can be spoofed via X-Forwarded-For. Running a real proxy in front (Railway, Cloudflare, an ingress)? Declare it here — otherwise audit entries record the proxy’s address — with any value Express supports: a hop count (e.g. 2), an address list, or false when the Node server is exposed directly. |
| DOC_URL | No | Documentation URL for error responses, default is https://docs.usertour.com |
| USERTOUR_TOKEN | No | Usertour Environment token |
| AWS S3 Configuration | | |
| AWS_S3_REGION | Yes | AWS S3 region |
| AWS_S3_ENDPOINT | Yes | AWS S3 endpoint |
| AWS_S3_ACCESS_KEY_ID | Yes | AWS S3 access key ID |
| AWS_S3_SECRET_ACCESS_KEY | Yes | AWS S3 secret access key |
| AWS_S3_BUCKET | Yes | AWS S3 bucket name |
| AWS_S3_DOMAIN | Yes | AWS S3 domain |
| Analytics Configuration | | |
| POSTHOG_KEY | No | PostHog API key |
| POSTHOG_HOST | No | PostHog host URL |
| OpenTelemetry Configuration | | |
| OTLP_TRACES_ENDPOINT | No | OpenTelemetry traces endpoint URL for distributed tracing |
| OTLP_METRICS_ENDPOINT | No | OpenTelemetry metrics endpoint URL for metrics collection |
| Encryption | | |
| ENCRYPTION_KEY | Yes (prod) | 64-character hex string (32 bytes) used as the AES-256-GCM key for encrypting sensitive data at rest (currently 2FA TOTP secrets). Generate with openssl rand -hex 32. If unset, the server falls back to a known-insecure development key and logs no warning — do not ship that to production. Once users have enrolled in 2FA, do not rotate this key: existing TOTP secrets won’t decrypt with a new value. |
| Authentication Configuration | | |
| JWT_SECRET | Yes | JWT token secret key |
| JWT_EXPIRATION_TIME | Yes | JWT token expiration time (e.g. 1h) |
| JWT_REFRESH_EXPIRATION_TIME | Yes | JWT refresh token expiration time (e.g. 7d) |
| Email Authentication | | |
| EMAIL_AUTH_ENABLED | No | Enable/disable email authentication |
| EMAIL_SENDER | No | Email sender name and address |
| GitHub Authentication | | |
| GITHUB_AUTH_ENABLED | No | Enable/disable GitHub authentication |
| GITHUB_CLIENT_ID | No | GitHub OAuth client ID |
| GITHUB_CLIENT_SECRET | No | GitHub OAuth client secret |
| GITHUB_CALLBACK_URL | No | GitHub OAuth callback URL. Optional — defaults to <API_URL>/api/auth/github/callback when unset. |
| Google Authentication | | |
| GOOGLE_AUTH_ENABLED | No | Enable/disable Google authentication |
| GOOGLE_CLIENT_ID | No | Google OAuth client ID |
| GOOGLE_CLIENT_SECRET | No | Google OAuth client secret |
| GOOGLE_CALLBACK_URL | No | Google OAuth callback URL. Optional — defaults to <API_URL>/api/auth/google/callback when unset. |
| SSO (OIDC) | | |
| SSO_CALLBACK_URL | No | OIDC redirect URI shown to admins and sent to the IdP. Optional — defaults to <API_URL>/api/auth/sso/callback when unset. |
| Other Configuration | | |
| LOGIN_REDIRECT_URL | No | URL to redirect after login |
| USERTOUR_COOKIE_DOMAIN | No | Domain where cookies are valid and can be accessed |
| USERTOUR_COOKIE_SECURE | No | Controls whether cookies can only be transmitted over HTTPS. |
| Outbound Security | | |
| ALLOW_PRIVATE_NETWORK_EGRESS | No | When true, the server may make outbound requests — SSO issuer discovery, webhook deliveries — to private/internal addresses. Defaults to false: only public HTTPS targets are allowed, as an SSRF safeguard. Set to true if your identity provider or webhook receiver is reachable only on an internal network (common for self-hosted IdPs such as Keycloak on localhost, or an internal event bus). |
| AI Provider (machine translation) | | |
| AI_PROVIDER | No | Which AI provider powers machine translation: anthropic (default), openai-compatible (any OpenAI-shaped gateway, e.g. the OpenAI API, Azure OpenAI, or a local gateway), or bedrock (AWS). The feature is enabled by providing the provider’s requirement below — no key/config means the AI translate buttons simply don’t appear. |
| AI_API_KEY | No | API key for the provider. Required for anthropic; optional for openai-compatible (keyless gateways work); for bedrock it is treated as a Bedrock API key (Bearer auth). |
| AI_MODEL | No | Model identifier, in the provider’s own naming. Defaults to claude-opus-4-8. For bedrock, use a Bedrock model or inference-profile ID (e.g. us.anthropic.claude-sonnet-4-6). |
| AI_BASE_URL | No | Base URL of the API. Required for openai-compatible (e.g. https://api.openai.com/v1); optional override for anthropic. |
| AI_AWS_REGION | No | bedrock only. AWS region; falls back to AWS_REGION when unset. |
| AI_AWS_ACCESS_KEY_ID | No | bedrock only. Explicit SigV4 credentials. When neither this pair nor AI_API_KEY is set, the AWS default credential chain is used (env vars, profile, instance role) — so deployments on AWS can run keyless. |
| AI_AWS_SECRET_ACCESS_KEY | No | bedrock only. Secret half of the SigV4 key pair. |