nous.env.example. A variable is Required for any instance to work, Optional when it turns on one feature, or Cloud only when it serves OpenNous Cloud and a self-hosted instance leaves it empty.
Variables starting with VITE_ are baked into the frontend at build time. Changing one needs a rebuild, not just a restart.
Domains
| Variable | Required | What it does |
|---|---|---|
APP_DOMAIN | Required | Domain of the web app. Caddy issues its certificate. APP_URL is derived as https://$APP_DOMAIN. |
API_DOMAIN | Required | Domain of the API. Used for OAuth callbacks and webhook URLs. API_URL is derived as https://$API_DOMAIN. |
MCP_DOMAIN | Required | Domain of the hosted MCP server. Remote clients connect to https://$MCP_DOMAIN/mcp. |
APP_URL or API_URL yourself only when the app or API is not served on those domains.
Database and auth
| Variable | Required | What it does |
|---|---|---|
SUPABASE_URL | Required | URL of the Supabase (or bundled) database API. |
SUPABASE_SERVICE_ROLE_KEY | Required | Service role key the API and worker use. Keep it secret. |
SUPABASE_JWT_SECRET | Optional, recommended | Lets the API verify session tokens locally. Without it, each request asks Supabase Auth. |
VITE_SUPABASE_URL | Required | Same URL, for the browser. |
VITE_SUPABASE_ANON_KEY | Required | Public anon key, for browser sign-in. |
AUTH_PROVIDER | Optional | supabase or clerk. Leave unset: with SELF_HOSTED=true it is supabase. |
VITE_AUTH_PROVIDER | Optional | Frontend side of the same switch. Leave unset. |
CLERK_SECRET_KEY | Cloud only | Cloud signs in with Clerk. Leave unset. |
VITE_CLERK_PUBLISHABLE_KEY | Cloud only | Leave unset. If set, the frontend build switches to Clerk. |
Bundled stack
On the bundled stack,node scripts/selfhost-keys.mjs nous.env writes these. It keeps values that are already set.
| Variable | What it is |
|---|---|
POSTGRES_PASSWORD | Password for postgres and for the PostgREST and GoTrue database roles. Fixed at first boot. |
SUPABASE_JWT_SECRET | HS256 secret. GoTrue signs sessions with it; the API and PostgREST verify with it. |
SUPABASE_ANON_KEY, VITE_SUPABASE_ANON_KEY | JWT with role: anon. Public; built into the frontend. |
SUPABASE_SERVICE_ROLE_KEY | JWT with role: service_role. Server side only. |
ENCRYPTION_KEY | 32-byte hex. Encrypts integration tokens at rest. |
SELFHOST_SETUP_TOKEN | One-time secret. Only the sign-up that presents it becomes the owner. |
SUPABASE_URL | http://supabase:8000, the gateway inside the compose network. |
VITE_SUPABASE_URL | https://$APP_DOMAIN. |
SELF_HOSTED, AUTH_PROVIDER, VITE_AUTH_PROVIDER | true, supabase, supabase. |
COMPOSE_FILE | docker-compose.yaml:docker-compose.selfhost.yaml (; instead of : on Windows). |
DISABLE_SIGNUPS | true. Only the setup-token sign-up and invitees get an account. |
GOTRUE_MAILER_AUTOCONFIRM | false when SMTP_HOST is set, else true. |
| Variable | Default | What it does |
|---|---|---|
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS | unset, 587 | Mail server the auth service sends through. Needed for password reset and magic links. |
SMTP_ADMIN_EMAIL, SMTP_SENDER_NAME | unset, Nous | From address and name. |
GOTRUE_DISABLE_SIGNUP | false | Leave it false: the owner and invitees create their login there. DISABLE_SIGNUPS is the gate. |
Core
| Variable | Required | What it does |
|---|---|---|
OPENROUTER_API_KEY | One AI key is required | Recommended. Runs every model below, Claude included. |
ANTHROPIC_API_KEY | Optional | Runs claude-… model ids when no OpenRouter key is set. |
LLM_BASE_URL, LLM_API_KEY | Optional | An OpenAI-compatible endpoint (OpenAI, Groq, Together, LiteLLM, a local Ollama) for every model id that is not claude-…, instead of OpenRouter. |
EXTRACTION_MODEL | Optional | Reading calls and email. Default claude-haiku-4-5-20251001. |
WRITING_MODEL | Optional | Summaries and reports. Default z-ai/glm-5.2, falling back to the reading model. |
INSIGHT_BOARD_MODEL | Optional | The Insights board. Default anthropic/claude-haiku-4.5. |
JOB_BUILDER_MODEL | Optional | The RevBox Job Builder. A Claude model; default claude-sonnet-5. |
ENCRYPTION_KEY | Required | 32-byte hex key that encrypts integration tokens at rest. Generate with openssl rand -hex 32. Do not change it after setup, or stored tokens cannot be read. |
SELF_HOSTED | Required | Set to true. Turns off billing, plan limits and metering, and blocks Cloud-only features. Never set it on Cloud. |
DISABLE_SIGNUPS | Optional | true closes public sign-up; add others with invite links. On the bundled stack the key script sets it, and only the setup-link sign-up becomes the owner. With your own Supabase, the first account becomes the owner. |
CORS_ORIGINS | Optional | Comma-separated allowed origins. Unset allows all. |
NOUS_DEFAULT_TIMEZONE | Optional | IANA zone, such as Europe/Berlin, used to resolve spoken deadlines like “by Friday”. Default UTC. |
PORT | Optional | Frontend port when running without Caddy. Default 80. |
VITE_API_URL | Optional | API URL for the browser. Set to https://api.yourdomain.com with Caddy. Leave empty when nginx proxies the API on the same domain. |
VITE_DOCS_URL | Optional | Where in-app docs links point. Default https://docs.opennous.cloud. |
| Variable | Required | What it does |
|---|---|---|
RESEND_API_KEY | Optional | Sends workspace invitation emails through Resend. Without it, invites still create the account but send no email. |
RESEND_FROM_EMAIL | Optional | Sender address. Must be on a domain you verified in Resend. |
RESEND_REPLY_TO | Optional | Reply-to address. Defaults to the sender. |
Integrations
Most integrations are connected per workspace with the provider’s own key, in Settings → Integrations. These are the ones that need instance settings.| Variable | Required | What it does |
|---|---|---|
SALESFORCE_CLIENT_ID | Optional | Your Salesforce connected app. Needed to connect Salesforce. |
SALESFORCE_CLIENT_SECRET | Optional | Its secret. |
SALESFORCE_REDIRECT_URI | Optional | https://api.yourdomain.com/api/workflow-providers/salesforce/oauth/callback |
SALESFORCE_LOGIN_URL | Optional | https://login.salesforce.com, or https://test.salesforce.com for a sandbox. |
UNIPILE_API_KEY | Optional | Unipile account key. Needed for LinkedIn. |
UNIPILE_DSN | Optional | Your Unipile DSN, such as api1.unipile.com:13xxx. |
GOOGLE_CLIENT_ID | Optional | Your Google OAuth client (Web application). With this and the secret set, members connect Gmail and Google Calendar with your own app. See Gmail & Google Calendar. |
GOOGLE_CLIENT_SECRET | Optional | Its secret. |
GOOGLE_OAUTH_REDIRECT_URI | Optional | Defaults to https://<API_DOMAIN>/api/oauth/google/callback. Set it only if your callback differs; it must match the OAuth client exactly. |
COMPOSIO_API_KEY | Optional | Not needed for self-hosting. Set it only if you want Gmail and Calendar to connect through Composio instead of your own Google app; it takes precedence when set. |
SLACK_CLIENT_ID | Cloud only | The Slack connector is Cloud only. |
SLACK_CLIENT_SECRET | Cloud only | |
SLACK_REDIRECT_URI | Cloud only | |
SIGNAL_HMAC_SECRET | Optional | Signs the per-workspace ingest tokens for RB2B. Needed only if you use RB2B. |
PROSPERO_API_KEY | Optional | An instance-wide Prospeo key. Workspaces normally use their own. |
ENRICHMENT_BUILTIN_FALLBACK | Optional | true lets workspaces without their own Prospeo key enrich on the instance key. Off unless set to exactly true. Every new contact can trigger enrichment, so this can cost a lot. |
OPENAI_API_KEY | Optional | Embeddings for semantic search. Without it, search falls back to structured retrieval. |
EMBEDDINGS_ENABLED | Optional | true turns on the background embedding sweep. Apply supabase/migrations/2026_09_21_embedding_queue_indexes.sql first. |
Inbound webhook secrets
Set the ones you use to a random string, and enter the same value in that tool’s webhook settings. Leave the rest empty.| Variable | Tool |
|---|---|
LINKEDIN_WEBHOOK_SECRET | LinkedIn (Unipile) |
INSTANTLY_WEBHOOK_SECRET | Instantly |
CALENDLY_WEBHOOK_SECRET | Calendly |
FIREFLIES_WEBHOOK_SECRET | Fireflies |
FATHOM_WEBHOOK_SECRET | Fathom |
RB2B_WEBHOOK_SECRET | RB2B |
HEYREACH_WEBHOOK_SECRET | HeyReach |
LEMLIST_WEBHOOK_SECRET | lemlist |
SMARTLEAD_WEBHOOK_SECRET | Smartlead |
EMAILBISON_WEBHOOK_SECRET | EmailBison |
STRIPE_INBOUND_WEBHOOK_SECRET | Stripe events sent to the worker as signals |
LinkedIn engagement run
| Variable | Required | What it does |
|---|---|---|
APIFY_TOKEN | Optional | Turns on the weekly run that collects people who engaged with each workspace’s recent LinkedIn posts. Unset, the feature is off. |
LINKEDIN_ENGAGEMENT_WORKSPACES | Optional | Comma-separated workspace IDs to include. On a self-hosted instance every workspace is included. |
ENGAGEMENT_WINDOW_DAYS | Optional | Days of posts to look at. Default 7. |
ENGAGEMENT_MAX_POSTS | Optional | Posts per run. Default 5. |
ENGAGEMENT_PROFILE_MODE | Optional | main or short profile depth. Default main. |
Monitoring
| Variable | Required | What it does |
|---|---|---|
OPS_ALERT_SLACK_WEBHOOK | Optional | Slack incoming webhook for crash, database and dead-letter alerts. Unset, alerts only go to logs. |
SENTRY_DSN | Optional | Sends API and worker errors to Sentry. |
VITE_POSTHOG_KEY | Optional | PostHog product analytics in the frontend. |
VITE_GOOGLE_ANALYTICS_ID | Optional | Google Analytics in the frontend. |
https://api.yourdomain.com/readyz. It returns 503 when the database is down.
Forms
| Variable | Required | What it does |
|---|---|---|
FEEDBACK_WEBHOOK_URL | Optional | Forwards in-app feedback to an endpoint such as n8n or Zapier. |
VITE_WAITLIST_WEBHOOK_URL | Cloud only | Waitlist form on the Cloud landing page. |
Cloud only
Leave these empty on a self-hosted instance.| Variable | What it does on Cloud |
|---|---|
ADMIN_EMAILS | Accounts allowed into the platform admin pages. Empty means no account can reach them. |
VIP_EMAILS | Accounts with VIP plan access. |
STRIPE_SECRET_KEY | Billing. |
STRIPE_WEBHOOK_SECRET | Billing webhooks. |
VITE_STRIPE_PUBLISHABLE_KEY | Checkout in the frontend. |
STRIPE_API_PRICE_ID | Price for the API plan. |
STRIPE_STARTER_PRICE_ID | Retired plan, kept for existing subscriptions. |
STRIPE_PRO_PRICE_ID | Retired plan, kept for existing subscriptions. |