Skip to main content

Environment Overview

Pulse Content uses environment variables to configure:
  • External service credentials (Sanity, Pinecone, Kie.ai)
  • API keys for AI providers
  • Authentication secrets
  • Feature flags and service URLs

Environment Files

Local Development (.dev.vars)

Create .dev.vars in project root (gitignored):
# Sanity CMS
SANITY_PROJECT_ID=your-project-id
SANITY_DATASET=production
SANITY_API_TOKEN=your-token-with-editor-role

# AI Providers
ANTHROPIC_API_KEY=sk-ant-xxx
OPENROUTER_API_KEY=sk-or-xxx

# Vector Database
PINECONE_API_KEY=your-pinecone-key
PINECONE_HOST=https://your-index.svc.region.pinecone.io

# Image Generation
KIEAI_API_KEY=your-kie-api-key

# LinkedIn Scraper
RAPIDAPI_KEY=your-rapidapi-key

# Authentication
JWT_SECRET=your-random-32-byte-hex-string

# Email (Password Reset)
RESEND_API_KEY=re_xxx
RESEND_FROM_EMAIL="Pulse Studio <[email protected]>"
APP_BASE_URL=http://localhost:5173

# Media Processing
ASSEMBLYAI_API_KEY=your-assemblyai-key
GOOGLE_DRIVE_SA_KEY=base64-encoded-service-account-json

# Optional: YBH Sales Integration
YBH_SALES_API_URL=https://api.youvebeenheard.com
YBH_SALES_API_KEY=your-shared-api-key
YBH_BACKFILL_API_KEY=your-backfill-key
PULSE_BOT_API_KEY=your-bot-key
Never commit .dev.vars to version control. It’s listed in .gitignore.

Production (Cloudflare Pages)

Set via Cloudflare dashboard or Wrangler CLI: Dashboard: Workers & Pages > pulse-content > Settings > Environment Variables CLI:
wrangler secret put JWT_SECRET
wrangler secret put SANITY_API_TOKEN
wrangler secret put ANTHROPIC_API_KEY

Required Variables

Sanity CMS

SANITY_PROJECT_ID
string
required
Project ID from sanity.io/manage
SANITY_DATASET
string
required
Dataset name (typically production)
SANITY_API_TOKEN
string
required
API token with Editor role for write accessGenerate:
  1. Go to sanity.io/manage
  2. Select project > API > Tokens
  3. Add token with Editor permissions

AI Services

ANTHROPIC_API_KEY
string
required
Claude API key for content generationGet key: console.anthropic.com
OPENROUTER_API_KEY
string
required
OpenRouter API key for multi-model accessGet key: openrouter.ai/keys

Vector Database

PINECONE_API_KEY
string
required
Pinecone API key for RAG (design templates, brand guidelines)Get key: app.pinecone.io > API Keys
PINECONE_HOST
string
required
Full Pinecone host URLFormat: https://your-index.svc.region.pinecone.ioFind: Pinecone dashboard > Indexes > your-index > Connection

Image Generation

KIEAI_API_KEY
string
required
Kie.ai API key for Nano Banana Pro image generationGet key: kie.ai dashboard

Data Scraping

RAPIDAPI_KEY
string
required
RapidAPI key for LinkedIn profile scrapingGet key: rapidapi.com > My Apps

Authentication

JWT_SECRET
string
required
Secret key for signing JWT tokens (minimum 32 bytes)Generate:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Email Service

RESEND_API_KEY
string
required
Resend API key for password reset emailsGet key: resend.com/api-keys
RESEND_FROM_EMAIL
string
required
Email address for sending password resetsFormat: "Pulse Studio <[email protected]>"
APP_BASE_URL
string
required
Base URL of the applicationLocal: http://localhost:5173Production: https://production.youvebeenheard.com

Media Processing

ASSEMBLYAI_API_KEY
string
required
AssemblyAI API key for video transcriptionGet key: assemblyai.com/dashboard
GOOGLE_DRIVE_SA_KEY
string
required
Base64-encoded Google Cloud service account key JSONSetup:
  1. Create service account at console.cloud.google.com/iam-admin/serviceaccounts
  2. Download JSON key file
  3. Base64 encode:
    cat service-account.json | base64
    

Optional Variables

YBH Sales Integration

YBH_SALES_API_URL
string
Base URL for YBH Sales API (guest auto-sync)Example: https://api.youvebeenheard.com
YBH_SALES_API_KEY
string
Shared API key for YBH Sales integrationMust match WEBHOOK_API_KEY or one of KANBAN_API_KEYS in ybh-sales-platform
YBH_BACKFILL_API_KEY
string
Protects /api/ybh/backfill-guests endpoint
PULSE_BOT_API_KEY
string
Allows server-to-server auth for /api/late/* via X-Pulse-Bot-Api-Key header

Environment-Specific Configuration

Development vs. Production

VariableDevelopmentProduction
APP_BASE_URLhttp://localhost:5173https://production.youvebeenheard.com
SANITY_DATASETdevelopment or productionproduction
API KeysTest/sandbox keysProduction keys
LoggingVerboseError-only

Feature Flags

Toggle features based on environment:
// src/config.ts
export const config = {
  isDevelopment: import.meta.env.DEV,
  isProduction: import.meta.env.PROD,
  apiUrl: import.meta.env.VITE_API_URL || '/api',
  enableDebugLogs: import.meta.env.DEV,
  enableYBHSalesSync: !!process.env.YBH_SALES_API_URL
}

Managing Secrets

Local Development

  1. Copy example file:
    cp .env.example .dev.vars
    
  2. Fill in values:
    nano .dev.vars
    
  3. Source automatically when running:
    npm run dev  # Wrangler loads .dev.vars automatically
    

Production (Cloudflare)

  1. Navigate to Workers & Pages
  2. Select pulse-content project
  3. Go to Settings > Environment Variables
  4. Click Add variable
  5. Choose Encrypt for sensitive values
  6. Click Save

Accessing Environment Variables

In Cloudflare Workers (Backend)

// functions/api/episodes/index.ts
export const onRequestGet: PagesFunction<Env> = async ({ env }) => {
  const sanityToken = env.SANITY_API_TOKEN
  const apiKey = env.ANTHROPIC_API_KEY
  
  // Use environment variables
}

// Type definition
interface Env {
  SANITY_API_TOKEN: string
  ANTHROPIC_API_KEY: string
  // ... other vars
}

In Frontend (Client)

Never expose secrets to the frontend. Only use public configuration.
// Use VITE_ prefix for client-side variables
const publicConfig = {
  apiUrl: import.meta.env.VITE_API_URL || '/api',
  environment: import.meta.env.MODE
}

Security Best Practices

Rotate Secrets Regularly

Change API keys and tokens periodically (every 3-6 months)

Use Minimum Permissions

Grant only required permissions (e.g., Editor role, not Admin)

Never Commit Secrets

Add .dev.vars and .env* to .gitignore

Separate Dev/Prod Keys

Use different API keys for development and production

Validation

Validate environment variables at startup:
// src/utils/validateEnv.ts
const requiredEnvVars = [
  'SANITY_PROJECT_ID',
  'SANITY_API_TOKEN',
  'ANTHROPIC_API_KEY',
  'JWT_SECRET'
]

export function validateEnv(env: Record<string, string | undefined>) {
  const missing = requiredEnvVars.filter(key => !env[key])
  
  if (missing.length > 0) {
    throw new Error(`Missing required environment variables: ${missing.join(', ')}`)
  }
}

Next Steps

Cloudflare Deployment

Deploy to Cloudflare Pages

CI/CD Pipeline

Automate deployment with GitHub Actions

Setup Guide

Local development setup

Architecture

System architecture overview

Build docs developers (and LLMs) love