Environment Variables
Complete reference for all configuration variables used by the Carbon Connect platform. Variables are loaded from a .env file in the project root via Pydantic Settings (backend/app/core/config.py).
Security
Never commit .env files or API keys to version control. In production, all secrets are managed via AWS Secrets Manager. The project includes detect-secrets pre-commit hooks to prevent accidental credential leaks.
Application
General application settings controlling runtime behavior.
| Variable | Type | Default | Description |
APP_ENV | str | development | Environment name. Also accepts alias ENVIRONMENT. Values: development, staging, production |
APP_DEBUG | bool | false | Enable debug mode with verbose logging |
APP_SECRET_KEY | str | dev-secret-key-... | Application-level secret key. Must be changed in production |
CORS_ORIGINS | list[str] | ["http://localhost:3000", "http://localhost:3001", "http://localhost:8000"] | Allowed CORS origins. Accepts JSON array or comma-separated string |
RATE_LIMIT_PER_MINUTE | int | 60 | Global API rate limit per minute |
Database (PostgreSQL)
Configuration for the primary PostgreSQL database with pgvector extension.
| Variable | Type | Default | Description |
POSTGRES_HOST | str | localhost | PostgreSQL hostname |
POSTGRES_PORT | int | 5432 | PostgreSQL port. Use 5433 locally to avoid Windows conflicts |
POSTGRES_DB | str | grant_engine | Database name |
POSTGRES_USER | str | grant_user | Database username |
POSTGRES_PASSWORD | str | grant_password_dev | Database password. Must be changed in production |
DATABASE_URL_ASYNC | str | (computed) | Full async connection string override. If set, takes precedence over individual POSTGRES_* variables. Used in container environments |
Computed Connection Strings
The Settings class automatically computes two connection URLs from the individual PostgreSQL variables:
- Sync (psycopg2):
postgresql://{user}:{password}@{host}:{port}/{db} - Async (asyncpg):
postgresql+asyncpg://{user}:{password}@{host}:{port}/{db}
In development, the async URL appends ?ssl=disable since asyncpg defaults to SSL which fails on localhost.
Cache and Queue (Valkey / Redis)
Valkey is a Redis-compatible cache used for session storage, Celery task broker, and result backend. Valkey uses the standard redis:// protocol.
| Variable | Type | Default | Description |
REDIS_HOST | str | localhost | Valkey/Redis hostname |
REDIS_PORT | int | 6379 | Valkey/Redis port |
REDIS_URL | str | (computed) | Full Redis URL override. If set, takes precedence over REDIS_HOST/REDIS_PORT. Computed default: redis://{host}:{port}/0 |
Celery (Background Tasks)
Configuration for the Celery distributed task queue used for grant scraping, embedding generation, email notifications, and scheduled sync.
| Variable | Type | Default | Description |
CELERY_BROKER_URL | str | (falls back to REDIS_URL) | Celery message broker URL |
CELERY_RESULT_BACKEND | str | (falls back to REDIS_URL) | Celery result storage URL |
CELERY_TASK_ALWAYS_EAGER | bool | false | If true, tasks run synchronously in-process. Useful for testing |
CELERY_BEAT_SCHEDULE_ENABLED | bool | true | Enable/disable Celery Beat periodic task scheduling |
Search (Meilisearch)
Configuration for the Meilisearch full-text search engine providing sub-100ms grant search.
| Variable | Type | Default | Description |
MEILI_HOST | str | http://localhost:7700 | Meilisearch server URL |
MEILI_MASTER_KEY | str | meilisearch_dev_master_key_change_in_prod | Meilisearch API master key. Must be changed in production |
MEILI_INDEX_GRANTS | str | grants | Name of the Meilisearch index for grant documents |
MEILI_SEARCH_ENABLED | bool | true | Enable/disable Meilisearch. When disabled, falls back to PostgreSQL ILIKE search |
AI / LLM (Anthropic Claude)
Configuration for the Anthropic Claude API used for AI-powered application generation.
| Variable | Type | Default | Description |
CLAUDE_API_KEY | str | (none) | Anthropic API key. Also accepts alias ANTHROPIC_API_KEY. Required for AI features |
CLAUDE_MODEL | str | claude-sonnet-4-20250514 | Claude model identifier. Sonnet 4 recommended for quality/cost balance |
CLAUDE_MAX_TOKENS | int | 4096 | Maximum tokens for Claude responses |
Model Selection
| Model | Input Cost | Output Cost | Best For |
| Claude Sonnet 4 | $3/1M tokens | $15/1M tokens | Application generation (default) |
| Claude Opus 4 | $15/1M tokens | $75/1M tokens | Complex analysis and review |
| Claude Haiku 3.5 | $0.80/1M tokens | $4/1M tokens | Quick classification and extraction |
Legacy LLM (Deprecated)
| Variable | Type | Default | Description |
GEMINI_API_KEY | str | (none) | Google Gemini API key. Deprecated -- use CLAUDE_API_KEY instead |
GEMINI_MODEL | str | gemini-1.5-flash | Gemini model identifier. Deprecated |
Carbon Calculator (Climatiq)
Configuration for the Climatiq API providing GHG Protocol-compliant emission factor calculations.
| Variable | Type | Default | Description |
CLIMATIQ_API_KEY | str | (none) | Climatiq API key. Required for carbon calculations |
CLIMATIQ_API_URL | str | https://api.climatiq.io | Climatiq API base URL |
CLIMATIQ_DATA_VERSION | str | ^21 | Emission factor data version to query against |
ML / Embeddings
Configuration for the sentence-transformers embedding model used for semantic matching.
| Variable | Type | Default | Description |
EMBEDDING_MODEL | str | all-mpnet-base-v2 | Hugging Face sentence-transformers model name |
EMBEDDING_DIMENSION | int | 768 | Vector dimension output by the model |
EMBEDDING_BATCH_SIZE | int | 32 | Batch size for embedding generation |
EMBEDDING_MAX_SEQ_LENGTH | int | 384 | Maximum input token sequence length |
EMBEDDING_DEVICE | str | (auto) | Device for inference: cpu, cuda, or auto-detect |
EMBEDDING_CACHE_ENABLED | bool | true | Enable embedding result caching |
Authentication (JWT)
JSON Web Token configuration for user authentication.
| Variable | Type | Default | Description |
JWT_SECRET_KEY | str | jwt-dev-secret-key-... | JWT signing secret. Must be changed in production |
JWT_ALGORITHM | str | HS256 | JWT signing algorithm |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES | int | 30 | Access token lifetime in minutes |
JWT_REFRESH_TOKEN_EXPIRE_DAYS | int | 7 | Refresh token lifetime in days |
Email and Notifications
Configuration for email delivery (SMTP or AWS SES) and notification preferences.
SMTP Settings
| Variable | Type | Default | Description |
EMAIL_BACKEND | str | smtp | Email delivery backend: smtp or ses |
SMTP_HOST | str | (none) | SMTP server hostname |
SMTP_PORT | int | 587 | SMTP server port |
SMTP_USER | str | (none) | SMTP authentication username |
SMTP_PASSWORD | str | (none) | SMTP authentication password |
SMTP_FROM_EMAIL | str | noreply@grant-matching.example.com | Sender email address |
SMTP_FROM_NAME | str | Granted - Carbon Funding Navigator | Sender display name |
SMTP_TLS | bool | true | Enable TLS for SMTP connection |
SMTP_START_TLS | bool | true | Use STARTTLS for SMTP connection |
AWS SES Settings
| Variable | Type | Default | Description |
AWS_SES_REGION | str | eu-west-1 | AWS region for SES |
AWS_SES_CONFIGURATION_SET | str | (none) | SES configuration set name for tracking |
Rate Limiting and Tracking
| Variable | Type | Default | Description |
EMAIL_RATE_LIMIT_PER_MINUTE | int | 30 | Maximum emails per minute |
EMAIL_RATE_LIMIT_PER_HOUR | int | 500 | Maximum emails per hour |
EMAIL_TRACKING_ENABLED | bool | true | Enable email open/click tracking |
DEFAULT_NOTIFICATION_FREQUENCY | str | immediate | Default notification frequency: immediate, daily, weekly |
DEFAULT_MATCH_THRESHOLD | int | 70 | Minimum match score (0-100) to trigger notification |
DEADLINE_REMINDER_DAYS | list[int] | [7, 3, 1] | Days before deadline to send reminders |
AWS (Storage and Infrastructure)
Configuration for AWS services used in production: S3 for document storage, Secrets Manager for credentials.
S3 Document Storage
| Variable | Type | Default | Description |
AWS_ACCESS_KEY_ID | str | (none) | AWS access key. Not needed with IAM roles |
AWS_SECRET_ACCESS_KEY | str | (none) | AWS secret key. Not needed with IAM roles |
AWS_REGION | str | eu-west-1 | Default AWS region |
S3_BUCKET_NAME | str | grant-engine-documents | S3 bucket for document storage |
S3_PRESIGNED_URL_EXPIRY | int | 3600 | Pre-signed URL expiry in seconds (default: 1 hour) |
S3_MAX_FILE_SIZE_BYTES | int | 52428800 | Maximum upload file size (default: 50MB) |
USE_LOCALSTACK | bool | false | Use LocalStack for local S3 development |
LOCALSTACK_URL | str | http://localhost:4566 | LocalStack endpoint URL |
AWS Secrets Manager
| Variable | Type | Default | Description |
USE_AWS_SECRETS | bool | false | Enable AWS Secrets Manager for production secrets |
AWS_SECRETS_PREFIX | str | grant-engine | Prefix for all secrets in AWS Secrets Manager |
AWS_SECRETS_CACHE_TTL | int | 300 | Secrets cache TTL in seconds (5 minutes) |
Grant Pipeline
Configuration for the grant data pipeline including scraper clients and sync scheduling.
CORDIS (EU Research Funding)
| Variable | Type | Default | Description |
CORDIS_API_URL | str | https://cordis.europa.eu/api | CORDIS API base URL |
CORDIS_REQUESTS_PER_SECOND | float | 1.0 | Rate limit for CORDIS requests |
CORDIS_PAGE_SIZE | int | 100 | Results per page |
CORDIS_TIMEOUT_SECONDS | int | 30 | Request timeout |
CORDIS_MAX_RETRIES | int | 3 | Maximum retry attempts |
EU Funding Portal
| Variable | Type | Default | Description |
EU_PORTAL_API_URL | str | https://api.tech.ec.europa.eu/search-api/prod/rest/search | EU Portal search API URL |
EU_PORTAL_API_KEY | str | SEDIA | API key for EU Portal |
EU_PORTAL_REQUESTS_PER_SECOND | float | 2.0 | Rate limit |
EU_PORTAL_PAGE_SIZE | int | 100 | Results per page |
EU_PORTAL_TIMEOUT_SECONDS | int | 30 | Request timeout |
Cohesion Open Data Portal (ERDF/ESF)
| Variable | Type | Default | Description |
COHESION_API_URL | str | https://cohesiondata.ec.europa.eu/resource | Cohesion Data Portal Socrata SODA API URL |
COHESION_REQUESTS_PER_SECOND | float | 2.0 | Rate limit |
Green Climate Fund (GCF)
| Variable | Type | Default | Description |
GCF_API_URL | str | https://api.gcfund.org/v1/projects | GCF projects API base URL |
GCF_API_KEY | str | (none) | GCF API subscription key |
GCF_REQUESTS_PER_SECOND | float | 2.0 | Rate limit |
GCF_PAGE_SIZE | int | 50 | Results per page |
GCF_TIMEOUT_SECONDS | int | 30 | Request timeout |
GCF_MAX_RETRIES | int | 3 | Maximum retry attempts |
IATI Datastore
| Variable | Type | Default | Description |
IATI_API_URL | str | https://api.iatistandard.org/datastore/activity/select | IATI Datastore search endpoint |
IATI_SUBSCRIPTION_KEY | str | (none) | IATI subscription key |
IATI_REQUESTS_PER_SECOND | float | 2.0 | Rate limit |
IATI_PAGE_SIZE | int | 50 | Results per page |
IATI_TIMEOUT_SECONDS | int | 30 | Request timeout |
IATI_MAX_RETRIES | int | 3 | Maximum retry attempts |
World Bank Projects
| Variable | Type | Default | Description |
WORLD_BANK_API_URL | str | https://api.worldbank.org/v2/project | World Bank Projects API base URL |
WORLD_BANK_PER_PAGE | int | 50 | Results per page |
WORLD_BANK_REQUESTS_PER_SECOND | float | 2.0 | Rate limit |
WORLD_BANK_TIMEOUT_SECONDS | int | 30 | Request timeout |
WORLD_BANK_MAX_RETRIES | int | 3 | Maximum retry attempts |
Sync Source Toggles
| Variable | Type | Default | Description |
SYNC_CORDIS_ENABLED | bool | true | Enable CORDIS source synchronization |
SYNC_EU_PORTAL_ENABLED | bool | true | Enable EU Funding Portal synchronization |
SYNC_IATI_ENABLED | bool | true | Enable IATI Datastore synchronization |
SYNC_GCF_ENABLED | bool | true | Enable Green Climate Fund synchronization |
SYNC_WORLD_BANK_ENABLED | bool | true | Enable World Bank projects synchronization |
Pipeline Scheduling
| Variable | Type | Default | Description |
PIPELINE_SYNC_INTERVAL_HOURS | int | 6 | Hours between pipeline sync runs |
PIPELINE_MAX_GRANTS_PER_RUN | int | 1000 | Maximum grants processed per sync run |
SYNC_SCHEDULE_HOUR | int | 2 | Hour (UTC, 0-23) to run daily grant sync |
DEADLINE_CHECK_INTERVAL_HOURS | int | 1 | Interval in hours for deadline reminder checks |
Minimal .env for Development
The smallest viable .env for local development:
.env (minimal)POSTGRES_PORT=5433
MEILI_MASTER_KEY=meilisearch_dev_master_key_change_in_prod
All other variables have sensible defaults for local development. Add CLAUDE_API_KEY and CLIMATIQ_API_KEY only when you need AI or carbon calculation features.