Skip to main content

Environment Variables Reference

Complete reference for all environment variables used by the Ever Works Platform. Variables are sourced from two files:

FileAppCommitted
apps/api/.envAPI (NestJS)No -- copy from .env.example
apps/web/.env.localWeb (Next.js)No -- copy from .env.example
.env.composeDocker Compose (both apps)Template only
tip

Variables prefixed with NEXT_PUBLIC_ are exposed to the browser. All other variables are server-side only.


Core Configuration (API)​

VariableDescriptionTypeDefaultRequired
APP_TYPEApplication type identifierstringapiYes
PORTHTTP port for the API servernumber3100Yes
HTTP_DEBUGEnable verbose HTTP request loggingbooleanfalseNo
WEB_URLFull URL of the web applicationstringhttp://localhost:3000Yes
ALLOWED_ORIGINSCORS allowed origins (comma-separated)stringhttp://localhost:3000,http://localhost:3001Yes

Platform Secrets (API)​

VariableDescriptionTypeDefaultRequired
PLATFORM_ENCRYPTION_KEY32-byte hex key for per-Work PLATFORM_SYNC_SECRET / WEBHOOK_SECRET datahex string, 64 chars--Yes

Generate with:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Core Configuration (Web)​

VariableDescriptionTypeDefaultRequired
APP_NAMEApplication name (fallback for site name)stringEver WorksNo
NEXT_PUBLIC_APP_NAMEPublic application namestringEver WorksNo
NEXT_PUBLIC_WEB_URLPublic web application URLstringhttp://localhost:3000Yes
API_URLBackend API URL (server-side)stringhttp://localhost:3100Yes

Authentication -- JWT​

VariableDescriptionTypeDefaultRequired
JWT_SECRETSecret key for signing JWT tokensstring--Yes
JWT_ACCESS_TOKEN_EXPIRATIONAccess token TTL (15m, 1h, 7d, or never)string7dNo
JWT_REFRESH_TOKEN_EXPIRATION_DAYSRefresh token TTL in days (7, 30, or never)string14No
JWT_DISABLE_EXPIRATIONDisable all token expiration (dev only)booleanfalseNo

Authentication -- OAuth Providers​

GitHub OAuth​

VariableDescriptionTypeDefaultRequired
GH_CLIENT_IDGitHub OAuth application Client IDstring--No
GH_CLIENT_SECRETGitHub OAuth application Client Secretstring--No
GH_CALLBACK_URLGitHub OAuth callback URLstring${WEB_URL}/api/oauth/github/callbackNo

Google OAuth​

VariableDescriptionTypeDefaultRequired
GOOGLE_CLIENT_IDGoogle OAuth Client IDstring--No
GOOGLE_CLIENT_SECRETGoogle OAuth Client Secretstring--No
GOOGLE_CALLBACK_URLGoogle OAuth callback URLstring${WEB_URL}/api/oauth/google/callbackNo

Authentication -- Web (Cookies/Session)​

VariableDescriptionTypeDefaultRequired
COOKIE_SECRETSecret for encrypting session cookiesstring--Yes
AUTH_SECRETAlternative name for cookie secretstring--Yes
REDIRECT_SEARCH_PARAMQuery parameter key for redirectsstringredirect_uriNo
ALLOWED_REDIRECT_URLSAllowed redirect hosts (comma-separated)stringlocalhost,127.0.0.1No

Database​

Database Type Selection​

VariableDescriptionTypeDefaultRequired
DATABASE_TYPEDatabase enginesqlite | postgres | mysqlsqliteYes

SQLite Configuration​

Used when DATABASE_TYPE=sqlite:

VariableDescriptionTypeDefaultRequired
DATABASE_PATHFile path for SQLite databasestring:memory: (dev) or /tmp/ever-works-api.db (prod)No
DATABASE_IN_MEMORYForce in-memory databasebooleantrueNo

PostgreSQL Configuration​

Used when DATABASE_TYPE=postgres:

VariableDescriptionTypeDefaultRequired
DATABASE_HOSTPostgreSQL server hostnamestringlocalhostYes
DATABASE_PORTPostgreSQL server portnumber5432No
DATABASE_USERNAMEPostgreSQL usernamestringpostgresYes
DATABASE_PASSWORDPostgreSQL passwordstring--Yes
DATABASE_NAMEDatabase namestringever_worksYes
DATABASE_URLFull connection URL (overrides individual fields)string--No

MySQL / MariaDB Configuration​

Used when DATABASE_TYPE=mysql:

VariableDescriptionTypeDefaultRequired
DATABASE_HOSTMySQL server hostnamestringlocalhostYes
DATABASE_PORTMySQL server portnumber3306No
DATABASE_USERNAMEMySQL usernamestringrootYes
DATABASE_PASSWORDMySQL passwordstring--Yes
DATABASE_NAMEDatabase namestringever_worksYes
DATABASE_URLFull connection URL (overrides individual fields)string--No

Common Database Options​

VariableDescriptionTypeDefaultRequired
DATABASE_LOGGINGEnable SQL query loggingbooleanfalseNo
DATABASE_SSL_MODEEnable SSL/TLS for database connectionsbooleanfalseNo
DATABASE_CA_CERTCA certificate for SSL connectionsstring--No

Email / Mailer​

VariableDescriptionTypeDefaultRequired
MAILER_PROVIDERMail providersmtp | none | resendnoneNo
EMAIL_FROMDefault sender addressstringEver Works <ever@ever.works>No

SMTP Configuration​

Used when MAILER_PROVIDER=smtp:

VariableDescriptionTypeDefaultRequired
SMTP_HOSTSMTP server hostnamestringsmtp.gmail.comYes
SMTP_PORTSMTP server portnumber587Yes
SMTP_USERSMTP username / emailstring--Yes
SMTP_PASSWORDSMTP passwordstring--Yes
SMTP_SECUREUse TLS for SMTP connectionbooleanfalseNo
SMTP_IGNORE_TLSIgnore TLS (insecure, dev only)booleanfalseNo

Resend Configuration​

Used when MAILER_PROVIDER=resend:

VariableDescriptionTypeDefaultRequired
RESEND_APIKEYResend API keystring--Yes
RESEND_EMAIL_FROMSender address for Resendstring--No

Subscriptions & Billing​

VariableDescriptionTypeDefaultRequired
SUBSCRIPTIONS_ENABLEDEnable the subscription systembooleanfalseNo
BILLING_DEFAULT_CURRENCYDefault billing currencystringusdNo
SUBSCRIPTIONS_DEFAULT_PLANDefault plan for new usersstringfreeNo
STRIPE_SECRET_KEYStripe API secret keystring--When subscriptions enabled
STRIPE_WEBHOOK_SECRETStripe webhook signing secretstring--When subscriptions enabled

Work Generation​

VariableDescriptionTypeDefaultRequired
WORK_STALE_TIMEOUT_HOURSTimeout before a stale generation is cleaned upnumber2No

Scheduled Work Updates​

VariableDescriptionTypeDefaultRequired
SCHEDULED_UPDATES_ENABLEDEnable automatic work updatesbooleantrueNo
SCHEDULED_UPDATES_DISPATCH_INTERVAL_MINUTESInterval between update dispatch cyclesnumber5No
SCHEDULED_UPDATES_MAX_BATCHMaximum works per update batchnumber25No
SCHEDULED_UPDATES_MAX_FAILURE_BEFORE_PAUSEFailures before pausing updates for a worknumber3No
PAY_PER_USE_PRICE_USDPrice per on-demand work updatenumber5No

Website Template​

VariableDescriptionTypeDefaultRequired
WEBSITE_TEMPLATE_AUTO_UPDATE_ENABLEDEnable automatic template updatesbooleantrueNo
WEBSITE_TEMPLATE_BETA_BRANCHGit branch for beta template updatesstringstageNo

Trigger.dev (Background Jobs)​

VariableDescriptionTypeDefaultRequired
TRIGGER_ENABLEDEnable Trigger.dev integrationbooleanfalseNo
TRIGGER_SECRET_KEYTrigger.dev API secret keystring--When enabled
TRIGGER_API_URLTrigger.dev API endpointstringhttps://api.trigger.devNo
TRIGGER_INTERNAL_SECRETShared secret for internal trigger callbacksstring--When enabled
TRIGGER_MACHINEWorker machine sizemicro | small-1x | small-2x | medium-1x | medium-2x | large-1x | large-2x--No
TRIGGER_INTERNAL_API_URLInternal callback URL for Trigger.dev workersstringhttp://localhost:3100/internal/triggerNo

App Works (preview)​

App Works run an existing GitHub repository as a Work. They are a preview, and every switch below is off unless it is set to exactly true.

VariableDescriptionTypeDefaultRequired
EVER_WORKS_APP_WORKS_ENABLEDTurns App Works on. Off, the API refuses to inspect a repository for, or create, an App Work. The web app reads its own copy only when it has no PostHog key; otherwise the works-app flag decides.booleanfalseNo
APP_WORKS_CLOUD_PUSH_ENABLEDLets a cloud (API-side) agent run push an App Work branch and open its pull request, after the change guard has judged the exact commit. Off, only Fleet runs publish App Work changes. Read at API start.booleanfalseNo
EVER_WORKS_APPS_DOMAINA dedicated apex for App Works' managed subdomains. It may not equal, sit under, or be a parent of the platform domain or the API and web hosts; an unusable value turns the managed subdomain off.stringThe platform domain (EVER_WORKS_DOMAIN)No
EVER_WORKS_APPS_CLUSTER_WORKER_ISOLATEDProduction only: the operator's statement that the worker running App cluster jobs has no route to internal networks. Without it, every App deploy request answers 422 worker_not_isolated.booleanfalseIn production, to deploy
EVER_WORKS_APPS_CATALOG_TOKENGitHub token for reading App Blueprint repositories under ever-works, used when the Ever Works GitHub App is not installed there. Falls back to GITHUB_TOKEN.string--No

The web app also evaluates the PostHog flag works-app for the dashboard's App chip. Unlike the other works-<kind> flags it fails closed: a missing flag, an error or a timeout hides the chip.

App Launcher​

The App Launcher is off by default on every installation.

VariableDescriptionTypeDefaultRequired
EVER_WORKS_APP_LAUNCHER_ENABLEDTurns the launcher on. Off, every launcher route answers 404. Read per request, so no new image is needed.booleanfalseNo
EVER_WORKS_PLATFORM_CATALOG_REPOThe repository the launcher reads Ever apps from. Must match ^ever-works/[a-z0-9-]+$.stringever-works/platformsNo
EVER_WORKS_PLATFORM_CATALOG_REFThe branch, tag or 40-character commit SHA read from that repository.stringmainNo
EVER_WORKS_PLATFORM_CATALOG_ENVWhose addresses the tiles use. Set it per deployment, or a stage installation shows production addresses.production | stage | developproductionNo
EVER_WORKS_PLATFORM_CATALOG_SELF_IDThe catalog entry marked as the app you are in.stringever-worksNo
EVER_WORKS_APP_LAUNCHER_ORIGINSOrigins another Ever app may read a person's launcher list from, with a delegated token.string--No
EVER_ID_TRUSTED_CLIENT_IDSOptional: the Ever ID client ids such a delegated token must have been issued to.string--No

Where the web app has PostHog configured, the launcher also needs the app-launcher flag to resolve to true for the person; without PostHog, EVER_WORKS_APP_LAUNCHER_ENABLED alone decides.

EVER_WORKS_APP_LAUNCHER_ORIGINS takes exact https:// origins, comma-separated, at most 50: a delegated read from any other origin, or from none, is refused (403), and an invalid entry stops a production API from starting. EVER_ID_TRUSTED_CLIENT_IDS takes at most 5 client ids; unset, any client whose token verifies may read.


Anonymous Usage Statistics​

One small, signed report a day (plus one for the closed month on days 1–3 of a month) with counts, monthly totals and feature switches only — never a name, an address, a URL or any content. See Anonymous usage statistics for exactly what is sent and how to verify it.

VariableDescriptionTypeDefaultRequired
EVER_STATS_ENABLEDfalse (or any value other than empty / true) switches the module off entirelystringonNo
EVER_STATS_API_URLBase URL of the statistics endpoint (https; http only for a private or local host)stringEVER_PLATFORM_API_URLNo
EVER_PLATFORM_API_URLEver Platform base URLstringhttps://api.ever.coNo
EVER_STATS_COUNTRYThe country you declare (ISO 3166-1 alpha-2); unset sends ZZstring--No
EVER_INSTALL_SOURCEself-hosted, cloud, ever.sh, works_app, desktop or partner:<slug> — never inferredstringself-hostedNo
EVER_STATS_SEND_INTERVAL_SSeconds between reports; below 3600 only in testsnumber86400No
EVER_WORKS_STATS_SINKThe stats-sink plugin that delivers reportsstringever-stats-sinkNo

Set EVER_STATS_ENABLED=false where the API reads its settings: .env.compose with the Docker Compose files (a .env next to them never reaches the containers), apps/api/.env when you run the API from source, or the container / pod environment. A value already in the environment wins over the .env file.

The operator can also switch statistics off in Settings → Ever Platform without a restart.


CRM Integration (Twenty CRM)​

VariableDescriptionTypeDefaultRequired
TWENTY_CRM_BASE_URLTwenty CRM API base URLstringhttps://api.twenty.comNo
TWENTY_CRM_API_KEYTwenty CRM API keystring--When using CRM
TWENTY_CRM_WORKSPACE_IDTwenty CRM workspace identifierstring--When using CRM
TWENTY_CRM_MAX_RETRIESMaximum retry attempts for failed requestsnumber3No
TWENTY_CRM_RETRY_DELAY_MSInitial delay between retries (milliseconds)number1000No
TWENTY_CRM_BACKOFF_MULTIPLIERExponential backoff multipliernumber2No
TWENTY_CRM_TIMEOUT_MSRequest timeout (milliseconds)number30000No
TWENTY_CRM_ENABLE_LOGGINGEnable CRM request/response loggingbooleantrueNo

Plugins​

GitHub Plugin​

Separate from the GitHub OAuth configuration above -- used for work Git operations:

VariableDescriptionTypeDefaultRequired
PLUGIN_GITHUB_CLIENT_IDGitHub OAuth App ID for plugin operationsstring--No
PLUGIN_GITHUB_CLIENT_SECRETGitHub OAuth App Secret for plugin operationsstring--No

Callback URL: {WEB_URL}/api/oauth/github/callback/plugins

VariableDescriptionTypeDefaultRequired
PLUGIN_TAVILY_API_KEYTavily search API keystring--No

ScreenshotOne Plugin​

VariableDescriptionTypeDefaultRequired
PLUGIN_SCREENSHOTONE_ACCESS_KEYScreenshotOne API access keystring--No
PLUGIN_SCREENSHOTONE_SECRET_KEYScreenshotOne API secret keystring--No

OpenRouter Plugin (AI Provider)​

VariableDescriptionTypeDefaultRequired
PLUGIN_OPENROUTER_API_KEYOpenRouter API keystring--No
PLUGIN_OPENROUTER_DEFAULT_MODELDefault model for general usestringopenai/gpt-5-nanoNo
PLUGIN_OPENROUTER_SIMPLE_MODELModel for simple/fast tasksstringopenai/gpt-5-nanoNo
PLUGIN_OPENROUTER_MEDIUM_MODELModel for medium complexity tasksstringmoonshotai/kimi-k2.5No
PLUGIN_OPENROUTER_COMPLEX_MODELModel for complex generation tasksstringmoonshotai/kimi-k2.5No

Web -- Site & SEO Configuration​

These variables control branding and metadata for the web dashboard. All are optional with sensible defaults.

VariableDescriptionTypeDefault
NEXT_PUBLIC_SITE_NAMESite display namestringUses APP_NAME
NEXT_PUBLIC_SITE_TITLEHTML title / SEO titlestringUses APP_NAME
NEXT_PUBLIC_SITE_DESCRIPTIONMeta descriptionstringBuild Works with AI
NEXT_PUBLIC_SITE_KEYWORDSMeta keywords (comma-separated)stringEver Works,Works,AI,...
NEXT_PUBLIC_SITE_AUTHORSite author metadatastringUses APP_NAME
NEXT_PUBLIC_SITE_IMAGEDefault Open Graph image pathstring/logo-light.png

Web -- Logo & Favicon​

VariableDescriptionTypeDefault
NEXT_PUBLIC_LOGO_LIGHTLogo for light modestring/logo-light.png
NEXT_PUBLIC_LOGO_DARKLogo for dark modestring/logo-ever-work.png
NEXT_PUBLIC_FAVICON_LIGHTFavicon for light modestring/favicon-light.png
NEXT_PUBLIC_FAVICON_DARKFavicon for dark modestring/favicon-dark.png

Web -- Social Media / Twitter Cards​

VariableDescriptionTypeDefault
NEXT_PUBLIC_TWITTER_CARDTwitter card typesummary | summary_large_imagesummary_large_image
NEXT_PUBLIC_TWITTER_TITLETwitter card titlestringUses APP_NAME
NEXT_PUBLIC_TWITTER_DESCRIPTIONTwitter card descriptionstringUses site description

Web -- Internationalization (i18n)​

VariableDescriptionTypeDefault
NEXT_PUBLIC_LOCALESSupported locales (comma-separated)stringen,ar,de,es,fr,zh
NEXT_PUBLIC_DEFAULT_LOCALEDefault localestringen

Web -- Application Settings​

VariableDescriptionTypeDefault
NEXT_PUBLIC_WORK_LIST_LIMITWorks per page (pagination)number6
NEXT_BUILD_OUTPUTNext.js build output modestandalone | export-- (default Next.js behavior)

Environment-Specific Values​

# API
DATABASE_TYPE=sqlite
DATABASE_IN_MEMORY=true
HTTP_DEBUG=false
MAILER_PROVIDER=none
SUBSCRIPTIONS_ENABLED=false
TRIGGER_ENABLED=false

# Web
API_URL=http://localhost:3100
NEXT_PUBLIC_WEB_URL=http://localhost:3000

Production​

# API
DATABASE_TYPE=postgres
DATABASE_SSL_MODE=true
JWT_SECRET=<strong-random-secret>
MAILER_PROVIDER=smtp
SUBSCRIPTIONS_ENABLED=true

# Web
API_URL=https://api.yoursite.com
NEXT_PUBLIC_WEB_URL=https://yoursite.com
COOKIE_SECRET=<strong-random-secret>
NEXT_BUILD_OUTPUT=standalone

Generate secrets with:

openssl rand -base64 32