Environment variables

Copy .env.example to .env (root) and apps/web/.env. Never commit .env.

VariableRequiredDefaultDescription
DATABASE_URLyes–PostgreSQL connection string (Prisma + pg-boss). Use ?schema=public.
SESSION_SECRETyes–≥32 random characters. Signs session cookies and authoring tokens, and encrypts per-project Anthropic keys. Rotating it invalidates all authoring tokens, and projects with their own Anthropic key must enter it again (Scout uses ANTHROPIC_API_KEY meanwhile, if set).
APP_URLyeshttp://localhost:3000Public dashboard origin. Used for CSRF origin checks, invite links and the authoring postMessage origin.
NEXT_PUBLIC_GUIDELY_API_URLnoAPP_URLSDK API base URL as seen from customer browsers. Shown in install snippets; read at runtime, so it can be set on the container rather than at image build.
NEXT_PUBLIC_GUIDELY_CDN_URLno${API_URL}/sdk/guidely.jsWhere the script-tag build is served from.
REDIS_URLno–Enables Redis-backed rate limiting and config cache. In-memory fallback when unset (fine for one replica).
EVENT_RETENTION_DAYSno365Default retention for product events (projects can override in Privacy settings).
WORKER_ENABLEDnotrueInformational; run pnpm worker as a separate process.
LOG_LEVELnoinfodebug \info \warn \error. Logs are JSON lines.
SEED_DEMOnotrueSet false to skip the demo workspace in pnpm db:seed.
SENTRY_DSNno–Hook point: captureException in src/server/logger.ts is where to plug an error tracker.
PRISMA_LOGno–query to log SQL in development.
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRETno–Enable Continue with GitHub. Create an OAuth App on GitHub with callback URL ${APP_URL}/api/v1/auth/github/callback.
GITHUB_ALLOWED_ORGSno–Comma-separated GitHub organization logins. Each listed org gets a shared workspace (gh-<org>, first member Owner) the first time one of its members signs in, with the org as that workspace's auto-join rule. When set, GitHub users who match no workspace (membership, auto-join rule or invitation) are refused even with open signup.
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETno–Enable Continue with Google. Create an OAuth client (type Web application) in Google Cloud with redirect URI ${APP_URL}/api/v1/auth/google/callback. Which Google accounts get in is decided per workspace (Settings → Sign-in → Google Workspace domains, invitations). Empty or REPLACE_ME = off.
AUTH_PASSWORD_ENABLEDnotruefalse disables email/username + password login everywhere (GitHub / Google only). Workspaces can also turn password sign-in off for themselves.
AUTH_SIGNUP_ENABLEDnotruefalse closes self-service signup: new people then need an invitation, a login created by a workspace admin, or a matching workspace auto-join rule. Invited people can still create a password account.
PLATFORM_ADMIN_EMAILSno–Comma-separated emails of platform admins, who can manage every workspace at /admin. Only honoured for verified emails (GitHub sign-in); grant others from the console or with pnpm --filter @guidelytech/web admin:grant <email>.
ANTHROPIC_API_KEYno–Server-wide key that lets Scout answer messenger questions with AI and draft articles from uploaded files. Projects can set their own key in Scout settings, which takes precedence. With neither (or an empty/REPLACE_ME value) the messenger still works and every conversation goes to the team inbox. Requests go to the Anthropic API; see security.
SCOUT_MODELnoclaude-opus-5Claude model Scout uses.
SCOUT_EFFORTnomediumlow \medium \high \xhigh \max. Higher is more thorough and slower/costlier.
SMTP_URLno–SMTP connection URL for inbox notification emails, e.g. smtps://user:pass@smtp.example.com:465. When unset emails are logged instead. Locally: docker compose --profile mail up -d and smtp://localhost:51025 (Mailpit UI on :58025).
EMAIL_FROMnoGuidely <no-reply@guidely.app>From address for notification emails.
REPLAY_S3_BUCKETfor session replay–S3 bucket that stores session recordings. Without it session replay is unavailable (the SDK is told not to record). Locally guidely-replays on the SeaweedFS container from pnpm db:up.
REPLAY_S3_REGIONnous-east-1Bucket region.
REPLAY_S3_ENDPOINTno–Custom S3 endpoint for S3-compatible storage (http://localhost:59000 locally and in CI). Leave unset on AWS.
REPLAY_S3_FORCE_PATH_STYLEnofalsetrue for path-style addressing (needed by SeaweedFS/MinIO).
REPLAY_S3_PREFIXnoreplaysKey prefix; objects are <prefix>/<projectId>/<recordingId>/<pageLoadId>/<seq>.json.gz.
MEDIA_PUBLIC_URLno–Base URL of a cookieless CDN serving the bucket's media/ keys as paths (e.g. https://media.guidelytech.com; the infra stack sets it to its CloudFront distribution). New article uploads link there; unset, they link to the app's /api/v1/media/… route, which keeps serving older links either way. Use a host the dashboard's cookies are never sent to.
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYno–S3 credentials via the standard AWS chain. Locally any value works against SeaweedFS; on AWS the ECS task role is used instead.
SKIP_MIGRATIONSnofalseContainer only: skip prisma migrate deploy at start.
DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORDno–Container only: composed into DATABASE_URL when it is not set (used by the AWS stack with Secrets Manager).

Demo apps:

VariableAppDescription
NEXT_PUBLIC_GUIDELY_PROJECT_ID, NEXT_PUBLIC_GUIDELY_ENV, NEXT_PUBLIC_GUIDELY_API_URLapps/demo-reactPublic environment key, environment name, API URL.
VITE_GUIDELY_PROJECT_ID, VITE_GUIDELY_ENV, VITE_GUIDELY_API_URLapps/demo-svelteSame for SvelteKit.

Public keys are not secrets. A pk_… key only identifies an environment and unlocks its published configuration and event ingestion, further restricted by the environment's allowed origins. Dashboard credentials never reach the browser SDK.