Environment Variables
Environment Variables
All environment variables used by the Groundtruth Platform, organized by service.
Supabase (Required)
| Variable | Public | Description |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Yes | Supabase project URL. Found in your Supabase dashboard under Settings > API. |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Yes | Supabase anonymous (public) key. Used by the browser client for auth and public queries. Safe to expose in client-side code. |
SUPABASE_SERVICE_ROLE_KEY | No | Service role key for server-side operations. Bypasses Row-Level Security. Must never be exposed to the client. |
DATABASE_URL | No | PostgreSQL connection string. Use the Supabase pooler URL (port 6543) in production to avoid connection exhaustion. Format: postgresql://postgres.[ref]:[password]@[host]:6543/postgres?pgbouncer=true |
DIRECT_URL | No | Direct PostgreSQL connection string (port 5432). Required by Prisma for running migrations, which need a direct connection rather than a pooled one. Format: postgresql://postgres.[ref]:[password]@[host]:5432/postgres |
Stripe (Required for Billing)
Soft Launch Note (2026-03-08): No
STRIPE_PRICE_*env vars are needed during the soft launch. Credit packs (Spark/Boost/Vault) use dynamicprice_datain Stripe checkout sessions. When subscription tiers reactivate, addSTRIPE_PRICE_OPERATORandSTRIPE_PRICE_STUDIOenv vars pointing to the Stripe price IDs.
| Variable | Public | Description |
|---|---|---|
STRIPE_SECRET_KEY | No | Stripe secret API key. Used server-side for creating checkout sessions, managing subscriptions, and processing webhooks. Starts with sk_test_ (test) or sk_live_ (production). |
STRIPE_WEBHOOK_SECRET | No | Stripe webhook signing secret. Used to verify that incoming webhook events originate from Stripe. Starts with whsec_. Obtained when registering a webhook endpoint in the Stripe dashboard. |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Yes | Stripe publishable key. Used by the browser client for Stripe.js and Checkout redirects. Starts with pk_test_ (test) or pk_live_ (production). |
Engine (Required)
| Variable | Public | Description |
|---|---|---|
RAILWAY_ENGINE_URL | No | URL of the Railway-hosted Python engine. The Next.js API routes proxy requests to this URL for crew execution, health checks, and SSE streams. Defaults to http://localhost:8000 for local development. |
LLM API Keys (Required by Python Engine)
These keys are configured on the Railway-hosted Python engine, not the Next.js application.
| Variable | Provider | Used By |
|---|---|---|
OPENAI_API_KEY | OpenAI | GPT-4o-mini for the analytical tier and observer quality scoring |
XAI_API_KEY | xAI | Grok-4 for the strategy tier |
ANTHROPIC_API_KEY | Anthropic | Claude Sonnet 4.5 for writing and fullstack tiers |
GOOGLE_API_KEY | Gemini for the multimodal tier |
At least one LLM API key must be configured for the engine to function. The engine will use available models and skip tiers where keys are missing.
Redis (Optional)
| Variable | Public | Description |
|---|---|---|
UPSTASH_REDIS_REST_URL | No | Upstash Redis REST API URL. Used for caching (agent configs, engagement lists, tenant settings) and rate limiting. |
UPSTASH_REDIS_REST_TOKEN | No | Upstash Redis REST API token. Authenticates requests to the Upstash Redis instance. |
Graceful degradation: If Redis variables are not set, the platform falls back to in-memory caching and in-memory rate limiting. This is suitable for local development and low-traffic deployments. At scale, Redis is recommended for consistent rate limiting across multiple Vercel serverless function instances.
Email (Optional)
| Variable | Public | Description |
|---|---|---|
RESEND_API_KEY | No | Resend API key for transactional emails. Used for engagement notifications (started, completed, failed), deliverable ready alerts, client portal comment notifications, and team invitations. |
If not configured, the platform operates normally but email notifications are silently skipped.
Sentry (Optional)
| Variable | Public | Description |
|---|---|---|
SENTRY_DSN | No | Sentry Data Source Name. The ingest URL that tells the Sentry SDK where to send error events. |
SENTRY_ORG | No | Sentry organization slug. Used during CI builds to upload source maps for readable production stack traces. |
SENTRY_PROJECT | No | Sentry project slug. Identifies which Sentry project receives events and source maps. |
If not configured, the platform operates normally without error tracking. See monitoring.md for details on the Sentry integration.
Local Development
For local development, the minimum required variables are:
# Minimum for local dev
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=<your-local-anon-key>
DATABASE_URL=postgresql://postgres:postgres@localhost:54322/postgres
DIRECT_URL=postgresql://postgres:postgres@localhost:54322/postgresOptional but recommended for full functionality:
# Stripe (for billing features)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
# Engine (defaults to localhost:8000 if not set)
RAILWAY_ENGINE_URL=http://localhost:8000
# At least one LLM key for the engine
OPENAI_API_KEY=sk-...Redis, Resend, and Sentry are not needed for local development.
Production Checklist
Before deploying to production, verify:
- All Supabase variables point to your production Supabase project (not local)
DATABASE_URLuses the pooler URL (port 6543) with?pgbouncer=trueDIRECT_URLuses port 5432 (for Prisma migrations only)- Stripe keys are live mode (
sk_live_,pk_live_), not test mode STRIPE_WEBHOOK_SECRETmatches the production webhook endpoint registrationRAILWAY_ENGINE_URLpoints to the deployed Railway service URL- All required LLM API keys are set on the Railway engine
SUPABASE_SERVICE_ROLE_KEYis set only in server-side environments (never in client-side code orNEXT_PUBLIC_prefixed variables)
Related Documentation
- Monitoring — Sentry configuration and health check details
- Security — How secrets are used for RLS, API keys, and webhook signing