Environment variables
Every variable an Intelligo app reads: the two it cannot boot without, and the ones that switch on email, OAuth, Stripe, the cron and the admin console.
intelligo create writes these to .env.example; copy it to .env.local and fill it in. intelligo doctor reports what is still missing, and the app refuses to boot without the required ones rather than failing when a feature is first used. AUTH_SECRET is accepted as a legacy alias of BETTER_AUTH_SECRET.
Required — the app will not boot without these
| Variable | What it is |
|---|---|
DATABASE_URL |
Postgres with the pgvector extension (Neon, Supabase, RDS, or local). |
INTELLIGO_DB_DRIVER |
Driver is chosen from the URL (Neon hosts get the WebSocket driver, everything else node-postgres). Force it with pg | neon-serverless. |
BETTER_AUTH_SECRET |
At least 32 characters. Generate with: openssl rand -base64 32 |
NEXT_PUBLIC_APP_URL |
Where users reach the app. Auth callbacks, email links and redirects are built from it, so production needs the public https URL. The scaffold sets http://localhost:3000. |
INTELLIGO_BILLING_PRODUCT |
Which product’s plans the billing engine bills against. Your composition root also sets this via setDefaultProductSlug(); the variable is here so CLI tooling can check it without booting the app. The scaffold sets your-app. |
Optional — everything works locally without these
| Variable | What it is |
|---|---|
GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGITHUB_CLIENT_IDGITHUB_CLIENT_SECRET |
Sign in with Google or GitHub. A provider’s button appears once both of its values are set; the callback URL to register with the provider is NEXT_PUBLIC_APP_URL + /api/auth/callback/google (or /github). |
RESEND_API_KEY |
Email. Without a provider, emails (verification, invitations, reset links) are printed to the server console, and sign-ups are not held for email verification. |
EMAIL_FROM |
The sender of every email, on a domain verified with Resend. Required with RESEND_API_KEY: there is no built-in sender, so sends fail without it. Loops ignores it and takes the sender from each template. The scaffold sets Acme <noreply@example.com>. |
APP_NAMESUPPORT_EMAIL |
The product’s name in every email’s heading and footer; defaults to the display name in EMAIL_FROM. SUPPORT_EMAIL is the address the footer offers for replies; without it the footer offers none. The scaffold sets Acme. |
LOOPS_API_KEY |
Loops sends by template id instead of HTML: map each template with LOOPS_TRANSACTIONAL_ID_<KEY>, e.g. LOOPS_TRANSACTIONAL_ID_VERIFY_EMAIL. |
EMAIL_PROVIDER |
With both keys set Resend wins; force one with resend | loops | console. |
STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRET |
Stripe. Billing pages say “not configured” until these are set; the webhook at /api/webhooks/stripe verifies with the secret. |
PAYMENT_MODE |
Which registered payment provider serves payments outside Stripe (registerPaymentProvider in the composition root). Defaults to the in-memory mock, which production refuses. |
OPENAI_API_KEYANTHROPIC_API_KEYGOOGLE_GENERATIVE_AI_API_KEY |
AI providers. Chat runs on a built-in stub model until lib/chat-model.ts names a real one. Set only the key of the provider that model belongs to — the provider’s SDK reads it, and the framework checks none of them. |
CRON_SECRET |
Bearer token your scheduler sends to /api/cron/maintenance (intelligo add maintenance). At least 32 characters. |
PLATFORM_ADMIN_EMAILS |
Comma-separated emails allowed to reach the Intelligo admin console. Closed by default: with no value, nobody is a platform admin. |