Environment variables

Names below are exactly as the code reads them. Several are prefixed NEXT_ without being NEXT_PUBLIC_ — those are server-only despite the prefix.

Database

Variable Purpose Missing

DATABASE_URL

Pooled connection used at runtime

Nothing works

DIRECT_URL

Direct connection used by migrations

Migrations fail

Supabase

Variable Purpose Missing

NEXT_PUBLIC_SUPABASE_URL

Project URL (client and server)

Middleware allows all requests through; Realtime disabled

NEXT_PUBLIC_SUPABASE_ANON_KEY

Anon key

As above

SUPABASE_SERVICE_ROLE_KEY

Admin client

Admin operations fail

SUPABASE_GOOGLE_CLIENT_ID

Google OAuth

Google sign-in unavailable

SUPABASE_GOOGLE_CLIENT_SECRET

Google OAuth

As above

NEXT_SUPABASE_URL

Legacy alias referenced in some code paths

Depends on the path

Middleware deliberately allows requests through when the anon config is absent — auth cannot be enforced, and failing every request would make a misconfigured environment unreachable. Never deploy without it.

Retell AI

Variable Purpose Missing

NEXT_RETELLAI_API_KEY

Read into RETELLAI_API_KEY

No calls, no SMS, no agent sync

NEXT_RETELLAI_BASE_URL

API base override

Uses the SDK default

NEXT_RETELL_OUTBOUND_AGENT_ID

Default outbound agent

Falls back to the agent registry

RETELL_API_KEY

Referenced in some paths alongside the NEXT_ variant

Set both to the same value

RETELL_SMS_AGENT_ID is hardcoded in lib/constants.ts, not an environment variable.

Telnyx

Variable Purpose Missing

TELNYX_PUBLIC_KEY

Ed25519 verification of POST /api/webhooks/telnyx. Base64 raw public key from the Telnyx Mission Control portal

Inbound webhooks are rejected (503)

ElevenLabs

Variable Purpose Missing

ELEVENLABS_WEBHOOK_SECRET

HMAC verification of POST /api/webhooks/elevenlabs. Secret shown when the ElevenLabs workspace webhook is created

Inbound webhooks are rejected (503)

Carriers and number purchase

Variable Purpose Missing

NEXT_MESSAGING_APP_API_URL

MessagingApp base URL

Purchase and release fail

NEXT_MESSAGING_APP_API_KEY

MessagingApp key

As above

PHONE_NUMBER_DEFAULT_COUNTRY

Defaults to US

Defaults applied

NEXT_TWILIO_TRUNK_SID

Twilio SIP trunk

Twilio import fails

NEXT_TWILIO_TERMINATION_URL

Twilio termination URL

As above

NEXT_PLIVO_TRUNK_SID

Plivo SIP trunk

Plivo import fails

NEXT_PLIVO_TERMINATION_URL

Plivo termination URL

Falls back to a hardcoded default

Email

Variable Purpose Missing

RESEND_API_KEY

Sending

No email is sent

RESEND_WEBHOOK_SECRET

Svix verification

Verification is skipped — never omit in a deployed environment

MAILTRAP_API_KEY

Present in the environment file; not used by the current send path

—

HubSpot

Variable Purpose Missing

HUBSPOT_PRIVATE_APP_TOKEN

Direct API calls

Engagement logging fails (best-effort, so nothing else breaks)

HUBSPOT_WEBHOOK_CLIENT_SECRET

Inbound signature validation

Inbound webhooks are rejected

HUBSPOT_CLIENT_ID

OAuth app

OAuth flows unavailable

HUBSPOT_CLIENT_SECRET

OAuth app

As above

HUBSPOT_REFRESH_TOKEN

OAuth refresh

As above

HUBSPOT_OWNER_ID

Read into HUBSPOT_AI_OWNER_ID; defaults to 86817215

Default applied

HUBSPOT_CONTACT_SYNC_SUBSCRIPTION_ID

Workspace that receives inbound HubSpot contacts, calls, and Payability suppliers from BigQuery

Contact, call, and supplier import crons return missing_subscription and do not query BQ

AWS SQS

Variable Purpose Missing

AWS_REGION

SQS region

No CRM or categorisation messages

AWS_ACCESS_KEY_ID

Credentials

As above

AWS_SECRET_ACCESS_KEY

Credentials

As above

CRM_QUEUE_URL

CRM event queue

CRM hand-off silently stops

INCOMING_EMAIL_SQS_QUEUE_URL

Reply categorisation; defaults to the morpheus-sam-email-agent queue

Default applied

EMAIL_VARIATION_QUEUE_URL

Variation generation requests

That path is unavailable

Publishers return false rather than throwing, so a missing queue URL degrades to "not published". Watch the logs, because nothing else will complain.

AI

Variable Purpose Missing

AI_GATEWAY_API_KEY

Vercel AI Gateway

No call analysis, variation generation, prompt suggestions or test runs

AI_GATEWAY_BASE_URL

Defaults to https://ai-gateway.vercel.sh/v1

Default applied

OPENAI_API_KEY

Direct OpenAI access in some helpers

Depends on the path

ANTHROPIC_API_KEY

Direct Anthropic access in some helpers

Depends on the path

BigQuery

Variable Purpose Missing

BIGQUERY_PROJECT_ID

Defaults to bigqueryexport-183608

Default applied

BIGQUERY_PRIVATE_KEY

Service-account PEM, with \n escaped

Sequence data gates fail

BIGQUERY_PRIVATE_KEY_ID

Key id

As above

BIGQUERY_CLIENT_ID

Client id

As above

The PEM is stored with escaped \n and restored to real newlines at runtime. Paste it escaped.

Redis

Variable Purpose Missing

REDIS_URL

In-flight call counter

Broadcast throttling misbehaves — investigate before running campaigns

Machine secrets

Variable Purpose Missing

INTERNAL_API_SECRET

Broadcast and internal endpoints

Every broadcast returns 401 — all campaigns stop

MCP_API_SECRET

MCP tool server

MCP returns -32603 (HTTP 500)

INNGEST_EVENT_KEY

Sending Inngest events

Workflows are never triggered

INNGEST_SIGNING_KEY

Serving Inngest functions

Inngest cannot invoke functions

NOOKS_WEBHOOK_SECRET

Nooks verification

Verification skipped

NOOKS_API_KEY

Present; not used by the webhook path

—

INTERNAL_API_SECRET fails closed. An unset value stops all outbound work, which is by design — the alternative is an open broadcast endpoint.

Monitoring

Variable Purpose Missing

NEXT_PUBLIC_SENTRY_DSN

Sentry DSN

No error reporting

NEXT_PUBLIC_SENTRY_ENVIRONMENT

Environment tag

Events are untagged

.env.sentry-build-plugin holds the build-time source-map upload token.

Application

Variable Purpose Missing

NEXT_PUBLIC_APP_URL

Base URL for unsubscribe links

Falls back to https://$VERCEL_URL, then http://localhost:3000

VERCEL_URL

Provided by Vercel

Used as the fallback base URL

NODE_ENV

Standard

—

NEXT_RUNTIME

Set by Next.js; used to branch Sentry init

—

DEBUG

Verbose logging

—

An incorrect NEXT_PUBLIC_APP_URL produces unsubscribe links pointing at the wrong host — a compliance problem, not just a broken link. Set it explicitly in production.

Client-exposed variables

Only these reach the browser: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, NEXT_PUBLIC_SENTRY_DSN, NEXT_PUBLIC_SENTRY_ENVIRONMENT, NEXT_PUBLIC_APP_URL.

Everything else is server-only, including the NEXT_-prefixed Retell and MessagingApp variables.

Where they are read

Most are centralised in lib/constants.ts and lib/ai/config.ts, which read process.env at module load. A running instance therefore keeps the value it started with — changing a variable requires a redeploy, not just a save.