See Parent Issue for more context - #5874
Summary
Create a FastAPI service under carbon-atlas/api/ that serves unified carbon registry data (projects, credits, developers) with filtering, pagination, and aggregation endpoints. Uses PostgreSQL for storage and Alembic for schema migrations. Packaged as Docker containers.
Scope
Database (PostgreSQL + SQLModel + Alembic)
Tables:
projects — unified project data (project_id, name, registry, status, country, category, protocol, proponent, issued, retired, project_url, listed_at, etc.)
credits — credit transactions (project_id, quantity, vintage, transaction_date, transaction_type, retirement_beneficiary, etc.)
project_developers — developer entities (id, name, project_count, total_issued, total_retired, countries, registries, categories, methodologies)
project_developer_links — junction table (project_id, developer_id)
ETL Pipeline
- Reads raw registry CSVs, processes through data processors (Verra, Gold Standard, ACR, CAR, ART TREES)
- Outputs harmonized Parquet, then loads into PostgreSQL via seed script
- Developer resolution: extracts, normalizes, and deduplicates developer entities from the
proponent field
API Endpoints
| Method |
Endpoint |
Description |
GET |
/api/v1/projects |
Paginated, filterable (registry, status, category, country, search) |
GET |
/api/v1/projects/{project_id} |
Single project detail with linked developers |
GET |
/api/v1/credits |
Paginated, filterable (project_id, transaction_type, vintage range) |
GET |
/api/v1/stats |
Market summary (totals by registry, category, country) |
GET |
/api/v1/charts/issuances-by-vintage |
Aggregated chart data |
GET |
/api/v1/charts/credits-over-time |
Time-series aggregation |
GET |
/api/v1/charts/projects-by-country |
Geographic breakdown |
GET |
/health |
Service health check |
Packaging
Dockerfile for FastAPI service (Python 3.12 slim)
docker-compose.yml with FastAPI + PostgreSQL 16 containers
- Configuration via environment variables (
DATABASE_URL, CORS_ORIGINS)
Planned directory structure
carbon-atlas/
api/
main.py
routers/
projects.py
credits.py
charts.py
schemas.py
db/
models.py
database.py
seed.py
developer_resolver.py
requirements.txt
Dockerfile
alembic/
alembic.ini
env.py
versions/
docker-compose.yml
.env.example
pipeline/
process.py
data/processed/
projects.parquet
credits.parquet
Acceptance criteria
See Parent Issue for more context - #5874
Summary
Create a FastAPI service under
carbon-atlas/api/that serves unified carbon registry data (projects, credits, developers) with filtering, pagination, and aggregation endpoints. Uses PostgreSQL for storage and Alembic for schema migrations. Packaged as Docker containers.Scope
Database (PostgreSQL + SQLModel + Alembic)
Tables:
projects— unified project data (project_id, name, registry, status, country, category, protocol, proponent, issued, retired, project_url, listed_at, etc.)credits— credit transactions (project_id, quantity, vintage, transaction_date, transaction_type, retirement_beneficiary, etc.)project_developers— developer entities (id, name, project_count, total_issued, total_retired, countries, registries, categories, methodologies)project_developer_links— junction table (project_id, developer_id)ETL Pipeline
proponentfieldAPI Endpoints
GET/api/v1/projectsGET/api/v1/projects/{project_id}GET/api/v1/creditsGET/api/v1/statsGET/api/v1/charts/issuances-by-vintageGET/api/v1/charts/credits-over-timeGET/api/v1/charts/projects-by-countryGET/healthPackaging
Dockerfilefor FastAPI service (Python 3.12 slim)docker-compose.ymlwith FastAPI + PostgreSQL 16 containersDATABASE_URL,CORS_ORIGINS)Planned directory structure
Acceptance criteria
docker compose upstarts FastAPI + PostgreSQLpython -m api.db.seedloads Parquet data into PostgreSQL?registry=verra&status=registered&category=forest-and-land-use?search=cookstove(matches project name or ID)DATABASE_URL