> ## Documentation Index
> Fetch the complete documentation index at: https://getoverlay.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> Required and optional web runtime variables for Overlay Web.

Environment variables override `overlay.config.json`. Put secrets in the runtime secret manager; keep JSON config focused on non-secret deployment shape.

## Base Runtime

| Variable | Required when | Notes |
| - | - | - |
| `NEXT_PUBLIC_APP_URL` | Deployed environments | Public browser URL for the web app. |
| `NEXT_PUBLIC_CONVEX_URL` | App talks to Convex | Public Convex deployment URL for the selected environment. |
| `DEV_NEXT_PUBLIC_CONVEX_URL` | Local dev with separate dev backend | Preferred for local work against the development Convex deployment. |
| `OVERLAY_CONFIG_FILE` | JSON runtime config | Absolute or repo-relative path, usually `overlay.config.json`; Docker mounts it at `/app/overlay.config.json`. |
| `INTERNAL_API_SECRET` | Always | Shared app-to-Convex secret, matching the selected Convex deployment. |
| `INTERNAL_SERVICE_AUTH_SECRET` | Always | Signs automation callbacks from Convex to the app. Set the same value on the app and the Convex deployment, and make it different from `INTERNAL_API_SECRET`. |
| `SESSION_SECRET` | Cookie sessions | Long, random, environment-specific app secret. |
| `SESSION_TRANSFER_KEY` | Native/session transfer flows | App runtime only. |
| `SESSION_COOKIE_ENCRYPTION_KEY` | Encrypted session cookie payloads | App runtime only. |
| `API_KEY_HASH_SECRET` | `apiKeys` enabled | HMAC pepper for API key hashes. |

## Provider Variables

| Provider family | Variables |
| - | - |
| WorkOS auth | `WORKOS_CLIENT_ID`, `WORKOS_API_KEY`; dev fallback uses `DEV_WORKOS_CLIENT_ID`, `DEV_WORKOS_API_KEY`. |
| Better Auth | `BETTER_AUTH_URL`, `BETTER_AUTH_SECRET`, `BETTER_AUTH_DATABASE_URL`, `BETTER_AUTH_JWT_ISSUER`, `BETTER_AUTH_JWT_AUDIENCE`, `BETTER_AUTH_JWKS_URL`, and one connection registry using `BETTER_AUTH_CONNECTION_ID`, `BETTER_AUTH_CONNECTION_PRESET`, `BETTER_AUTH_CONNECTION_LABEL`, `BETTER_AUTH_CONNECTION_DOMAINS`, and the applicable connection client/issuer variables. See [Authentication](https://getoverlay.io/docs/self-hosting/configure/authentication/index.md). Legacy `BETTER_AUTH_DEFAULT_SSO_*` and `BETTER_AUTH_OIDC_*` variables exist for migration compatibility but must not be mixed with the connection registry. |
| OIDC auth | `OIDC_ISSUER_URL`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_AUDIENCE`. Use these variables for Keycloak-compatible realm issuers too. |
| Stripe billing | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET`, `STRIPE_PAID_UNIT_PRICE_ID`, `STRIPE_TOPUP_UNIT_PRICE_ID`, `STRIPE_PORTAL_CONFIGURATION_ID`; dev fallback uses `DEV_STRIPE_SECRET_KEY`, `DEV_STRIPE_WEBHOOK_SECRET`. |
| Transactional email | `OVERLAY_EMAIL_PROVIDER` (`resend`, `ses`, `smtp`, or `none`), `OVERLAY_EMAIL_FROM`, and optional `OVERLAY_EMAIL_REPLY_TO`. Resend uses `RESEND_API_KEY` (or `OVERLAY_EMAIL_RESEND_API_KEY`). SES uses `OVERLAY_EMAIL_SES_ACCESS_KEY_ID`, `OVERLAY_EMAIL_SES_SECRET_ACCESS_KEY`, `OVERLAY_EMAIL_SES_SESSION_TOKEN`, `OVERLAY_EMAIL_SES_REGION`, and `OVERLAY_EMAIL_SES_CONFIGURATION_SET`. SMTP uses `OVERLAY_EMAIL_SMTP_HOST`, `OVERLAY_EMAIL_SMTP_PORT`, `OVERLAY_EMAIL_SMTP_SECURE`, `OVERLAY_EMAIL_SMTP_USERNAME`, and `OVERLAY_EMAIL_SMTP_PASSWORD`. |
| R2 storage | `R2_ACCOUNT_ID`, `R2_BUCKET_NAME`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `S3_API`. |
| S3-compatible storage | `S3_BUCKET_NAME`, `S3_REGION`, and optionally `S3_ENDPOINT_URL`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `S3_FORCE_PATH_STYLE`. AWS task and instance roles work with both key variables omitted; otherwise configure both together. |
| Models | `OPENROUTER_API_KEY`, `AI_GATEWAY_API_KEY`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GROQ_API_KEY`, `LLM_API_KEY_ENV_VAR`, `DEFAULT_CHAT_MODEL_ID`, `LLM_MODEL_ALLOWLIST`. |
| Web search and fetch | `ELO_API_KEY` (ELO routes `web_search`/`deep_search` to Tavily and Parallel) and `TINYFISH_API_KEY` (`web_fetch` page extraction). Server-side only; both resolve from WorkOS Vault first with env fallback. |
| Integrations and provider keys | `PROVIDER_KEYS_SECRET`, `HOOKS_TOKEN_SALT`. |
| Telemetry | `NEXT_PUBLIC_POSTHOG_TOKEN`, `NEXT_PUBLIC_POSTHOG_HOST`, `SENTRY_DSN`, `NEXT_PUBLIC_SENTRY_DSN`, `SENTRY_AUTH_TOKEN`. |
| Docs hosting | `MINTLIFY_DOCS_URL`, used at build time for Vercel rewrites from `/docs` and `docs.getoverlay.io` to Mintlify. |

## Private Deployment Defaults

For private deployments, disable unapproved processors in both server and client-visible env:

```bash theme={null}
OVERLAY_FEATURE_INTEGRATIONS=false
OVERLAY_FEATURE_BROWSER_USE=false
OVERLAY_FEATURE_SANDBOXES=false
OVERLAY_FEATURE_WEB_SEARCH=false
OVERLAY_FEATURE_ANALYTICS=false
OVERLAY_FEATURE_ERROR_REPORTING=false
OVERLAY_FEATURE_TRANSACTIONAL_EMAIL=false
NEXT_PUBLIC_OVERLAY_FEATURE_ANALYTICS=false
NEXT_PUBLIC_OVERLAY_FEATURE_ERROR_REPORTING=false

OVERLAY_PROVIDER_INTEGRATIONS=none
OVERLAY_PROVIDER_BROWSER=none
OVERLAY_PROVIDER_SANDBOX=none
OVERLAY_PROVIDER_WEB_SEARCH=none
OVERLAY_PROVIDER_ANALYTICS=none
OVERLAY_PROVIDER_ERROR_REPORTING=none
OVERLAY_EMAIL_PROVIDER=none
```

## Where each secret goes

| Secret | Web app | Convex backend |
| - | - | - |
| `INTERNAL_API_SECRET` | Yes | Yes, the same value |
| `INTERNAL_SERVICE_AUTH_SECRET` | Yes | Yes, the same value (different from `INTERNAL_API_SECRET`) |
| `SESSION_SECRET`, `SESSION_TRANSFER_KEY`, `SESSION_COOKIE_ENCRYPTION_KEY` | Yes | No |
| `API_KEY_HASH_SECRET`, `PROVIDER_KEYS_SECRET`, `HOOKS_TOKEN_SALT`, `MCP_CREDENTIAL_ENCRYPTION_KEY` | Yes | No |
| Identity provider, Stripe, storage and model provider keys | Yes | Only the providers the backend calls itself (see below) |
| `OVERLAY_EMAIL_*`, when email is on | Yes | Yes. The backend sends transactional email. |
| WorkOS keys, when using WorkOS | Yes | Yes |

Set backend values with `npx convex env set <NAME> <value>` against your deployment (for a self-hosted backend, add `--env-file convex.env.local`). After changing `convex/`, deploy it with `npx convex deploy`. Never point a production deploy at a development env file.

Public and safe to expose: `NEXT_PUBLIC_APP_URL`, `NEXT_PUBLIC_CONVEX_URL`, `NEXT_PUBLIC_POSTHOG_TOKEN`, `NEXT_PUBLIC_POSTHOG_HOST`, and the origins in `app.cspConnectSrc`.

Use different values in staging and production for every secret, the app URL, the Convex deployment, identity provider and Stripe credentials, buckets, and telemetry projects. The config schema rejects some mixed combinations, but keeping environments apart is the operator's job.

## Better Auth and email

When `auth.provider="better-auth"`, `BETTER_AUTH_DATABASE_URL` points at a
separate auth-scoped Postgres database owned by Better Auth. It is unrelated to
application data, which always lives in Convex.

Transactional email is sent from the Convex backend, so the selected
`OVERLAY_EMAIL_*` values must exist on the backend as well as the app. Keep
`OVERLAY_EMAIL_PROVIDER=none` to turn off all Overlay transactional email. Your
identity provider still sends its own verification and password-reset messages.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.