Thinking global, living local

How to use eu-ets-compliance-platform: a hands-on EU ETS and CBAM compliance prototype

October 19, 2026

A multi-tenant FastAPI and React prototype that models EU ETS, shipping MRV, CBAM, carbon-credit sourcing, trading and an India CCTS module on illustrative data, useful for learning how the pieces fit together.

Open-Source Tools · How-To · Climate & compliance

How to use eu-ets-compliance-platform: a hands-on EU ETS and CBAM compliance prototype

Skip to article content
Text Size

Revised · v1.0.0 · what changed

13demo tenants seeded
9years in the CBAM phase-in schedule (2026 to 2034)
2,695 tdefault-value embedded direct CO2 for 1,000 t Indian hot-rolled steel
1,900 tsame shipment with supplied actual direct emissions

Code: github.com/herrrickshaw/eu-ets-compliance-platform

Watch the walkthrough

Watch on YouTube: youtu.be/ZzHSLnBqv8M

Why it is useful

  • Students, consultants and developers who need to understand how EU carbon-market obligations (ETS surrender, CBAM declarations, shipping MRV) connect get a working, inspectable system instead of PDFs.
  • It replaces a diagram-only explanation with an API you can call: declare imports, see default-value mark-ups applied, reconcile a quarter and watch certificates net off.
  • Evidence from the run: after seeding in a fresh clone, I declared three default-value consignments and one with supplied actuals over the API and reconciled Q1 2026; the numbers matched hand calculation from the default-value table.
  • The run shows why the choice matters in CBAM: for the same 1,000 t of Indian steel, default values gave 3,223 t of embedded CO2 versus 2,200 t with supplied actuals (illustrative data).

What it is for

This is a prototype that models modules after real reference systems: EU Union Registry for ETS accounts and surrender, EMSA THETIS-MRV for shipping, the CBAM Transitional Registry for importers, and the Climate Action Data Trust for credit sourcing. An India CCTS module adds sector targets, Article 6.2 activities and carbon-price comparisons.

Every tenant's private data is isolated, while market data such as order books and credit projects is shared across tenants, as on a real marketplace.

Who it is for

  • Developers and students learning how carbon-compliance systems are structured
  • Analysts who want to experiment with CBAM default-value versus actual-emissions effects
  • Teams prototyping multi-tenant compliance software
Not for.
  • Real EU ETS, CBAM, MRV or CCTS filings: this is not legal advice and not a certified compliance tool
  • Any use of the seeded numbers as real prices, emission factors or allocations
  • Anything relying on the India module as primary-source law; the repo says it comes from secondary reporting

What you need

RequirementWhyHow to get it
Python 3.11The README uses python3.11; dependencies are pinned (FastAPI 0.115, SQLAlchemy 2.0.35, bcrypt 4.0.1)python.org, or brew install python@3.11
httpx (for the scripted API test used here)FastAPI's TestClient needs it; not in requirements.txtpip install httpx
Node.js (optional)Only for the React front end (npm install, npm run dev); not used in this demonodejs.org
A terminal and gitTo clone and runTerminal on macOS/Linux, or Git Bash/WSL on Windows
No API keys or accountsSQLite, seeded data, no external feedsNone needed. The seed script prints demo logins; use those, never real credentials

Get the code and an AI assistant

You do not have to be a programmer. Get the repository, give it to an AI assistant, and ask in plain language. Any of these routes works:

ToolWhat you needBest for
GitHubFree account to fork or star; git to clone, or the green Code button, then Download ZIP, or open in CodespacesGetting the code and keeping up with updates
Claude CodeClaude subscription or API key; run claude inside the cloned folderLetting the AI read and run the whole repo
Gemini CLIGoogle account; run gemini inside the cloned folderThe same hands-on workflow with Gemini
Claude.ai, Gemini or ChatGPT in the browserA chat account; upload README.md and the files you care about (or paste the output of git ls-files)Understanding the project and asking questions without installing anything
Other tools (Copilot Chat, Cursor, Codex CLI)Open the cloned folder in the tool and point it at README.md firstEditing and extending the code
git clone https://github.com/herrrickshaw/eu-ets-compliance-platform.git
cd eu-ets-compliance-platform
claude      # or: gemini

Install

  1. Clone and enter the backend
    git clone https://github.com/herrrickshaw/eu-ets-compliance-platform.git
    cd eu-ets-compliance-platform/backend
  2. Create a Python 3.11 virtual environment and install pinned dependencies
    python3.11 -m venv .venv && source .venv/bin/activate
    pip install -r requirements.txt

Quick start: commands and what you should see

Seed the illustrative data (drops and recreates the local SQLite tables)

python -m app.seed.seed_data

'Seed complete.' followed by a table of 13 demo tenants and their login emails, with the demo password printed.

Start the API

uvicorn app.main:app --port 8000

Interactive API docs at http://127.0.0.1:8000/docs. Log in via POST /api/auth/login with a printed demo account, then use the bearer token.

Declare a CBAM import and reconcile a quarter (shown in sample outputs)

POST /api/cbam/imports
POST /api/cbam/declarations/{declarant_id}/{year}/{quarter}/reconcile

Emissions computed from default values with mark-up, or from actuals if supplied.

Sample outputs

Real output from a run on the date shown in the sources line; trimmed to fit.

CBAM phase-in schedule (GET /api/cbam/phase-in-schedule, seeded data)

GET /api/cbam/phase-in-schedule
year  free_allocation_pct  cbam_factor_pct
2026  97.5                 2.5
2027  95.0                 5.0
2028  90.0                 10.0
2029  77.5                 22.5
2030  51.5                 48.5
2031  39.0                 61.0
2032  26.5                 73.5
2033  14.0                 86.0
2034   0.0                 100.0

The 2030 row carries the note 'Largest single-year jump in the schedule: +26 points from 2029.' Run 19 Oct 2026 against the seeded demo database.

Declaring imports as the CBAM demo importer (POST /api/cbam/imports, 10 Feb 2026)

1,000 t hot-rolled steel, CN code 7208
Origin  basis            direct_t  indirect_t
IN      default value    2,695     528
CN      default value    2,860     605
IN      actual verified  1,900     300   (declared 11 Feb, supplied by the importer)

500 t Portland cement (2523), TR: default value, direct 467.5, indirect 55

Default factors: India steel 2.45 direct and 0.48 indirect t CO2/t plus a 10% mark-up, so 1,000 t gives 2,695 and 528. These factors are seeded illustrative values, not official ones.

Quarterly reconcile (POST /api/cbam/declarations/1/2026/1/reconcile)

reconcile Q1 2026
{"year": 2026, "quarter": 1,
 "total_embedded_emissions_t": 17668.75,
 "certificates_surrendered_t": 2500.0,
 "status": "reconciled"}

The total includes the seeded imports as well as my four, and certificates surrendered are capped at the certificates held in the seed.

EU ETS compliance row for the demo steelworks (GET /api/ets/compliance)

GET /api/ets/compliance
year 2025, verified emissions 480,000 t,
free allocation 300,000 t, surrendered 0 t,
deadline 2026-09-30, status: open

Illustrative seed data for an invented operator.

Ways to use it

MethodHow it works
Swagger UIStart uvicorn and use /docs to log in and try each module's endpoints.
React dashboardRun npm install and npm run dev in frontend/ for a tabbed UI over the same API. Not run in this demo.
Scripted API callsUse any HTTP client, or FastAPI's TestClient as I did, to automate scenarios.
Through an AI assistantOpen the cloned folder in Claude Code or Gemini CLI and ask it to add a CN code, change a phase-in factor or explain a router.

Sample prompts for your AI assistant

Copy, paste and edit the parts in [brackets].

  • Explain this repository in plain English: which modules does it have, and which real systems is each one modelled on?
  • Walk me through what POST /api/cbam/imports does when I supply actual emissions versus when I do not.
  • Add a default emission factor for [CN code and good] to the seed data and show the embedded emissions for [quantity] tonnes from [country].
  • Read docs/INDIA_CCTS_SOURCES.md and list which India module facts are verified and which come from secondary reporting.
  • Review backend/app/modules/cbam/router.py against the real CBAM rules and list where the prototype simplifies them.

Limits and honest caveats

  • Not legal advice and not a certified compliance tool. The README says all data is illustrative and must not be used for real filings.
  • I ran the backend only (seed plus API calls through a test client). The React front end and the trading, credit and verification flows were not run.
  • There is no automated test suite in the repo; the checks shown are my own API calls on 19 Oct 2026 against a freshly seeded database.
  • The reconcile step adds direct and indirect emissions for every good. Real CBAM treats indirect emissions differently by product; check the regulation before relying on totals.
  • Default-value factors and the CBAM phase-in schedule are seeded illustrative values, not official figures.
  • The India CCTS module comes from secondary reporting, not gazette text or an official API, per the repo's own source notes.
  • The README states the demo password openly; this is a local demo only, so never deploy it as is.

Sources: the eu-ets-compliance-platform README, backend source and seed script; backend seeded and exercised through FastAPI's test client on 19 October 2026 on a fresh clone with Python 3.11.

Revision history.
  • v1.0.0 — 19 October 2026 — first published.

About this article: Researched, written and edited by Umashankar Triplicane Dwarakanathan, with AI research assistance; every figure is meant to trace to the primary source cited. See the Editorial Policy for how sourcing, AI use and corrections work.

Umashankar Triplicane Dwarakanathan
Contact Us
Umashankar Triplicane Dwarakanathan
Investment Promotion & Energy-Sector Leader · Chennai, Tamil Nadu, India
LinkedIn → GitHub → Email +91 78273 81696
How this site works

Data-led analysis of India's trade, currency and industrial policy. Every article is built from primary official sources, and every figure links back to the release, table or filing it came from.

Sources. DGCI&S TradeStat (imports/exports, HSN-wise) · PIB (government press releases, January 2017 to today, refreshed daily) · RBI (circulars, balance of payments) · MoSPI (CPI/WPI, IIP) · PARIVESH (environmental clearances) · CCIL (bond yields) · BIS (policy rates) · SEBI, NSE/BSE and SEC filings for company data.

Interpretation. Figures carry their vintage and retrieval date; estimates and press-reported numbers are labelled as such; where sources disagree, both are shown. Corrections are made visibly, never silently. Articles are written with AI assistance from the cited sources — AI-generated text can misstate figures even when working from real material, so verify any number that matters to a decision against the linked primary source.

footer

Browse all articles by topic

Every piece on this blog, grouped. Or read the full index.

Agriculture & FertilisersAI ToolsChemicalsClimate & CarbonEnergy & FuelsGas & LNGImport SubstitutionIndustrial PolicyMarkets & FinanceMobility & EVPrices & InflationTextilesTrade & Tariffs

Each topic is a live archive page that updates itself as pieces are labelled. It replaces a hand-kept list that had fallen 18 articles behind.