Skip to content

[Carbon Atlas] Add carbon market data API service #5875

@gautamp8

Description

@gautamp8

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

  • docker compose up starts FastAPI + PostgreSQL
  • Alembic migrations create all tables (projects, credits, project_developers, project_developer_links)
  • python -m api.db.seed loads Parquet data into PostgreSQL
  • All endpoints return correct paginated JSON
  • Filters work: ?registry=verra&status=registered&category=forest-and-land-use
  • Search works: ?search=cookstove (matches project name or ID)
  • Stats endpoint returns correct totals
  • Chart endpoints return data shaped for frontend chart consumption
  • CORS configurable via environment variable
  • Works with any PostgreSQL instance via DATABASE_URL
  • README with Docker setup and API documentation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions