Convertella uses different env files for different contexts:
| File | Purpose |
| File | Purpose |
|---|---|---|
| .env | Local development (gitignored). Template at .env.example |
| env.production.example | Reference for Cloudflare Pages secrets (production + preview) |
| Context | How vars are set |
|---|
Local dev (wrangler pages dev) | Reads .env file |
Production (main branch) | Pages Secrets — set via wrangler pages secret put or Cloudflare Dashboard |
| Branch Previews (feature branches) | Inherit Production secrets automatically. Can be overridden per-branch via Dashboard |
Production and preview share the same DATABASE_URL by default. To isolate preview DB traffic, use a Neon Logical Branch and set a DATABASE_URL override on the preview branch in the Dashboard.
The two Neon databases are configured separately:
| Database | Pages Secret | Used by |
|---|
| Testing | DATABASE_URL in all preview branches + local .env | Feature branches, local dev |
| Production | DATABASE_URL in production environment | main branch deployments |
| Variable | Purpose | Required |
|---|
DATABASE_URL | Neon connection string (use -pooler URL for serverless). Testing DB in preview branches and local dev, Production DB in production environment | Yes |
The Pages Production environment has DATABASE_URL set to the production Neon database. All preview branches inherit this value — so you must explicitly override DATABASE_URL to point to the testing database if you want previews isolated from production data.
| Variable | Purpose | Required |
|---|
AUTH_SECRET | Secret for signing/validating Lucia session cookies (long random string) | Yes |
OTP_PEPPER | Optional HMAC secret for OTP hashing (defaults to AUTH_SECRET if unset, min 16 chars) | No |
OTP_LOG_DELIVERY | If set, OTP codes are logged to stdout (staging/dev only — do not set in production) | Dev/staging |
ALLOW_OTP_LOG_DELIVERY_IN_PROD | Emergency override to log OTPs even in production (use with extreme caution) | No |
TURNSTILE_SITE_KEY | Cloudflare Turnstile site key (OTP abuse protection) | Yes |
TURNSTILE_SECRET_KEY | Cloudflare Turnstile secret key | Yes |
Email delivery uses Cloudflare Email Routing + Email Workers (not Resend).
| Variable | Purpose | Required |
|---|
EMAIL_FROM | Sender address, e.g. Convertella <noreply@convertella.app> | Yes |
OTP_EMAIL_PROJECT_NAME | Optional project name override in email body | No |
OTP_EMAIL_SUBJECT | Optional subject line override | No |
Sender domain must be verified in the Cloudflare zone (e.g. convertella.app).
| Variable | Purpose | Required |
|---|
WHATSAPP_ACCESS_TOKEN | Meta Cloud API access token | If WhatsApp enabled |
WHATSAPP_PHONE_NUMBER_ID | WhatsApp sender phone number ID | If WhatsApp enabled |
WHATSAPP_OTP_TEMPLATE_NAME | Approved WhatsApp OTP template name | If WhatsApp enabled |
WHATSAPP_OTP_TEMPLATE_LANG | Template language code (default: en_US) | No |
WHATSAPP_GRAPH_API_VERSION | Meta Graph API version (default: v21.0) | No |
WHATSAPP_BUSINESS_ACCOUNT_ID | WhatsApp Business Account ID | If WhatsApp enabled |
WHATSAPP_APP_SECRET | Meta App Secret (webhook verification) | If WhatsApp enabled |
WHATSAPP_VERIFY_TOKEN | Webhook verify token | If WhatsApp enabled |
| Variable | Purpose | Required |
|---|
CLOUDFLARE_API_TOKEN | Least-privilege API token (include “Custom Hostnames” for for-SaaS) | Yes |
CLOUDFLARE_ACCOUNT_ID | Cloudflare account ID (Dashboard → Workers & Pages → Account ID) | Yes |
CLOUDFLARE_ZONE_ID | Main zone ID (DNS, Custom Hostnames, SSL/TLS) | Yes |
CLOUDFLARE_PAGES_PROJECT_ADMIN | Pages project name for the CRM (default: convertella-admin) | Yes |
| Variable | Purpose | Required |
|---|
R2_ACCOUNT_ID | R2 account ID | Yes |
R2_ENDPOINT | R2 endpoint URL | Yes |
R2_REGION | Region (default: auto) | No |
R2_DOCUMENTS_BUCKET | Bucket name for documents/images | Yes |
R2_DOCUMENTS_ACCESS_KEY_ID | R2 access key for documents bucket | Yes |
R2_DOCUMENTS_SECRET_ACCESS_KEY | R2 secret key for documents bucket | Yes |
R2_BACKUPS_BUCKET | Bucket name for database backups | If backups enabled |
R2_BACKUPS_ACCESS_KEY_ID | R2 access key for backups bucket | If backups enabled |
R2_BACKUPS_SECRET_ACCESS_KEY | R2 secret key for backups bucket | If backups enabled |
| Variable | Purpose | Required |
|---|
OPERATOR_PORTAL_TOKEN | Bearer token for headless API access | Yes |
OPERATOR_PORTAL_ALLOWED_PROJECT_IDS | Comma-separated project UUIDs (omit = any project) | No |
| Variable | Purpose | Required |
|---|
CF_ACCESS_TEAM_DOMAIN | Zero Trust team domain (e.g. convertella.cloudflareaccess.com) | Yes |
CF_ACCESS_AUD | Access audience tag | Yes |
OPERATOR_ALLOWED_EMAILS | Comma-separated email addresses allowed as operators | Yes |
| Variable | Purpose | Required |
|---|
DEFAULT_OTP_PROJECT_ID | Fallback project UUID when Host-based tenant resolution is not active (local dev only) | Dev |