Calculator verification
Live test-suite results · last run 15 June 2026 at 15:28
Every release of the calculator runs an automated regression suite against authoritative EU sources before it ships. This page surfaces the latest results so brokers, customs officers, and counterparties can verify the methodology themselves without taking our word for it.
How this verification works
- EU inputs auto-pulled weekly — every intensity, benchmark, and certificate price the calc uses comes from the live EU source files, refreshed by the
cbam-data-filescron every Monday at 09:13 UTC. - Scope cross-checked against EU SAT — 573 CN codes, every one tested for in/out-of-scope and sector mapping (CBAM Self-Assessment Tool v1.1, 28 March 2025).
- Formulas pinned to specific implementing regulations— every step of the calc cites the Article it's based on (Annex IV §4.1 for goods, §4.2 for electricity).
- ⚠Expected costs are hand-derived— the EU does not publish “shipment X → cost Y” worked examples in machine-readable form. Each card below shows the EU value our calc actually loaded + the formula we applied + our resulting cost. If the EU value drifts (cron picks it up) and our pinned cost no longer matches, the test fails on the next Monday's run and we re-derive.
Numeric precision matches Implementing Reg (EU) 2025/2547 Annex II §A.2: intensity values clamped to ≤5 decimal places (§A.2.8), per-shipment emission totals preserve all significant digits (§A.2.7), monetary totals to cent precision. Means our outputs round identically to the EU's own SAT and Communication Template Excels — the CBAM Registry won't reject submissions for precision drift.
Tests run
58
Passing
28
Failing
0
Cost-calculation reference cases
Each case is a (CN code, country, tonnage) tuple. The card shows the EU's published intensity, the value our calculator actually loads from the live DB, the formula we apply, and our result vs. the hand-derived expected cost. Goods cases use the per-tonne formula in Reg (EU) 2025/2620 §3-§4 + Article 10a(1a) of Directive 2003/87/EC; electricity cases use Annex IV §4.2 of Reg (EU) 2023/956 + Annex III of Reg (EU) 2025/2621 (no mark-up, no benchmark).
Aluminium hollow profiles · CN 76042100 + Turkey + 100t (default data)
EU published4.1155tCO2e/tOur DB4.1155tCO2e/tMatchIn syncExpected: €20,044.74 ± €5
▶Derivation + sources
embedded = 4.11554 tCO2e/t × 100 t = 411.554 tCO2e | BMg(Column B, route K) = 1.493 tCO2e/t | SEFA = 0.975 (CBAM factor 2026) × 1.00 (CSCF) × 1.493 × 100 = 145.5675 tCO2e | net = 411.554 − 145.5675 = 265.9865 tCO2e | cost = 265.9865 × €75.36 = €20,044.74
Hot-rolled flat steel · CN 72081000 + Turkey + 100t (default data, single EU route)
EU published2.6703tCO2e/tOur DB2.6703tCO2e/tMatchIn syncExpected: €10,056.89 ± €5
▶Derivation + sources
embedded = 2.670263 tCO2e/t × 100 t = 267.0263 tCO2e | BMg(Column B, route C) = 1.37 tCO2e/t | SEFA = 0.975 × 1.00 × 1.37 × 100 = 133.575 tCO2e | net = 267.0263 − 133.575 = 133.4513 tCO2e | cost = 133.4513 × €75.36 = €10,056.89
Hydrogen · CN 28041000 + Egypt + 100t (single-route sector)
EU published11.9020tCO2e/tOur DB11.9020tCO2e/tMatchIn syncExpected: €0.00 ± €1
▶Derivation + sources
Hydrogen single-route sector — no Column A/B distinction. Test asserts the EU formula matches our calc for the (embedded, no-benchmark) case.
Cement · Grey clinker CN 25231000 + Algeria + 100t (multi-route, route A)
EU published1.4080tCO2e/tOur DB1.4080tCO2e/tMatchIn syncExpected: €5,717.19 ± €30
▶Derivation + sources
embedded(A) = 1.408 tCO2e/t × 100 t = 140.8 | BMg(Column B) = 0.666 | SEFA = 0.975 × 1.00 × 0.666 × 100 = 64.935 | net = 75.865 × €75.36 = €5,717.19
Cement · White clinker CN 25231000 + Algeria + 100t (route B, higher intensity)
EU published1.4740tCO2e/tOur DB1.4740tCO2e/tMatchIn syncExpected: €6,500.00 ± €1500
▶Derivation + sources
embedded(B) = 1.474 tCO2e/t × 100 t = 147.4 | Same benchmark formula as (A); net cost should be MEASURABLY higher than route (A) due to higher intensity.
Aluminium · Unwrought CN 76011000 + Algeria + 100t (single route L, country-specific)
EU published0.3960tCO2e/tOur DB0.3960tCO2e/tMatchIn syncExpected: €80.00 ± €100
▶Derivation + sources
DZA aluminium uses route (L) low intensity (0.396 tCO2e/t). Net cost low because EU default for aluminium ingots is small and benchmark covers most of it.
Fertilisers · Urea aqueous low-N CN 31021012 + Macao + 300t
EU published0.9090tCO2e/tOur DB0.9090tCO2e/tMatchIn syncExpected: €13,849.66 ± €50
▶Derivation + sources
ZZZ value_2026 = 0.909 tCO2e/t (Macao falls back to ZZZ via Reg 2025/2621 Annex I) | BMg(Column B, default-data path) = 0.304 tCO2e/t | SEFA = 0.975 × 1.00 × 0.304 × 300 = 88.92 tCO2e | net = (272.7 − 88.92) × €75.36 = €13,849.66
Fertilisers · Ammonia CN 28141000 + China + 100t (high-emissions origin)
EU published4.4036tCO2e/tOur DB4.4036tCO2e/tMatchIn syncExpected: €25,000.00 ± €5000
▶Derivation + sources
CHN value_2026 = 4.4036 tCO2e/t (coal-route ammonia, high emissions) × 100 t = 440.36 tCO2e. Net cost in €20k–€30k range after free-allocation deduction.
Electricity uses a different default-value methodology per Annex IV §4.2 of Reg (EU) 2023/956: per-MWh emission factor from Annex III of Reg (EU) 2025/2621 (sourced from IEA), no mark-up, no free-allocation benchmark. Values are flat across 2026 / 2027 / 2028+.
Annex III · live EU value vs. our DB
18 rows from Annex III of Implementing Reg (EU) 2025/2621, page 2354. Each row compares the EU's published emission factor to what our calculator actually loads. ✓ means the seeded DB row matches the regulation; ✗ would surface stale or drifted data.
| Country | EU Annex III (tCO2eq/MWh) | Our DB | Match | Source |
|---|---|---|---|---|
| AlbaniaALB | 0.0000 | 0.0000 | Reg 2025/2621 Annex III | |
| BelarusBLR | 0.3830 | 0.3830 | Reg 2025/2621 Annex III | |
| Bosnia and HerzegovinaBIH | 1.1480 | 1.1480 | Reg 2025/2621 Annex III | |
| EgyptEGY | 0.4420 | 0.4420 | Reg 2025/2621 Annex III | |
| GeorgiaGEO | 0.4400 | 0.4400 | Reg 2025/2621 Annex III | |
| IsraelISR | 0.4800 | 0.4800 | Reg 2025/2621 Annex III | |
| KosovoXKX | 0.9840 | 0.9840 | Reg 2025/2621 Annex III | |
| Moldova, Republic ofMDA | 0.5300 | 0.5300 | Reg 2025/2621 Annex III | |
| MontenegroMNE | 0.9790 | 0.9790 | Reg 2025/2621 Annex III | |
| MoroccoMAR | 0.9070 | 0.9070 | Reg 2025/2621 Annex III | |
| North MacedoniaMKD | 0.8870 | 0.8870 | Reg 2025/2621 Annex III | |
| Russian FederationRUS | 0.5850 | 0.5850 | Reg 2025/2621 Annex III | |
| SerbiaSRB | 1.0410 | 1.0410 | Reg 2025/2621 Annex III | |
| TunisiaTUN | 0.4360 | 0.4360 | Reg 2025/2621 Annex III | |
| TürkiyeTUR | 0.7180 | 0.7180 | Reg 2025/2621 Annex III | |
| UkraineUKR | 0.9070 | 0.9070 | Reg 2025/2621 Annex III | |
| United KingdomGBR | 0.4300 | 0.4300 | Reg 2025/2621 Annex III | |
| European Union (alternative default per §4.2.2)ZZZ§4.2.2 fallback | 0.6120 | 0.6120 | Reg 2025/2621 Annex III |
Electricity · CN 27160000 + Türkiye + 100 MWh (country-specific Annex III)
EU published0.7180tCO2e/MWhOur DB0.7180tCO2e/MWhMatchIn syncExpected: €5,410.85 ± €5
▶Derivation + sources
ef = 0.7180 tCO2eq/MWh (Annex III row for Türkiye, Reg (EU) 2025/2621) | embedded = 0.7180 × 100 MWh = 71.80 tCO2e | no benchmark for electricity (no SEFA deduction) | no mark-up per Annex IV §4.1 of Reg (EU) 2023/956 | cost = 71.80 × €75.36 = €5,410.85
Electricity · CN 27160000 + Canada + 100 MWh (alternative default per §4.2.2)
EU published0.6120tCO2e/MWhOur DB0.6120tCO2e/MWhMatchIn syncExpected: €4,612.03 ± €5
▶Derivation + sources
Canada is not listed in Annex III; per Annex IV §4.2.2 of Reg (EU) 2023/956 the alternative default = the Union's CO₂ emission factor (0.6120 tCO2eq/MWh, the European Union row of Annex III) | embedded = 0.6120 × 100 = 61.20 tCO2e | cost = 61.20 × €75.36 = €4,612.03
Electricity · CN 27160000 + Albania + 100 MWh (zero-emission edge case)
EU published0.0000tCO2e/MWhOur DB0.0000tCO2e/MWhMatchIn syncExpected: €0.00 ± €0
▶Derivation + sources
ef = 0 tCO2eq/MWh (Annex III row for Albania) | embedded = 0 × 100 = 0 tCO2e | cost = €0.00
Electricity · CN 27160000 + United Kingdom + 100 MWh (decarbonised grid)
EU published0.4300tCO2e/MWhOur DB0.4300tCO2e/MWhMatchIn syncExpected: €3,240.48 ± €5
▶Derivation + sources
ef = 0.4300 tCO2eq/MWh (Annex III row for United Kingdom) | embedded = 0.4300 × 100 = 43.00 tCO2e | cost = 43.00 × €75.36 = €3,240.48
Electricity · CN 27160000 + Bosnia and Herzegovina + 100 MWh (lignite-heavy, highest in Annex III)
EU published1.1480tCO2e/MWhOur DB1.1480tCO2e/MWhMatchIn syncExpected: €8,651.33 ± €5
▶Derivation + sources
ef = 1.1480 tCO2eq/MWh (Annex III row for Bosnia and Herzegovina, highest in the table) | embedded = 1.1480 × 100 = 114.80 tCO2e | cost = 114.80 × €75.36 = €8,651.33
EU CBAM Self Assessment Tool cross-check
Every CN code the EU's SAT v1.0 (28 March 2025) marks as CBAM-applies is asserted to resolve as in-scope by our scope checker. The same suite verifies our sector mapping (cement / iron-steel / aluminium / fertilisers / electricity / hydrogen) matches the SAT's main-category column.
573 CN codes scoped correctly · 6 sectors mapped correctly
Raw test suite results
tests/cbam-calc-coverage.test.ts
- Per-sector calc-coverage sweep (573 CN codes) Cement: all 6 CN codes return status='ok' or 'needs_data' (no throws / no NaN)NaNms
- Per-sector calc-coverage sweep (573 CN codes) Cement: ok-status results stay within €30–€200/t sanity bandNaNms
- Per-sector calc-coverage sweep (573 CN codes) Iron and steel: all 479 CN codes return status='ok' or 'needs_data' (no throws / no NaN)NaNms
- Per-sector calc-coverage sweep (573 CN codes) Iron and steel: ok-status results stay within €30–€350/t sanity bandNaNms
- Per-sector calc-coverage sweep (573 CN codes) Electricity: all 1 CN codes return status='ok' or 'needs_data' (no throws / no NaN)NaNms
- Per-sector calc-coverage sweep (573 CN codes) Electricity: ok-status results stay within €1–€100/t sanity bandNaNms
- Per-sector calc-coverage sweep (573 CN codes) Chemicals (hydrogen): all 1 CN codes return status='ok' or 'needs_data' (no throws / no NaN)NaNms
- Per-sector calc-coverage sweep (573 CN codes) Chemicals (hydrogen): ok-status results stay within €100–€2000/t sanity bandNaNms
- Per-sector calc-coverage sweep (573 CN codes) Fertilisers: all 27 CN codes return status='ok' or 'needs_data' (no throws / no NaN)NaNms
- Per-sector calc-coverage sweep (573 CN codes) Fertilisers: ok-status results stay within €10–€500/t sanity bandNaNms
- Per-sector calc-coverage sweep (573 CN codes) Aluminium: all 59 CN codes return status='ok' or 'needs_data' (no throws / no NaN)NaNms
- Per-sector calc-coverage sweep (573 CN codes) Aluminium: ok-status results stay within €50–€600/t sanity bandNaNms
tests/cbam-calc-reference.test.ts
- CBAM cost-calculation reference cases Aluminium hollow profiles · CN 76042100 + Turkey + 100t (default data)NaNms
- CBAM cost-calculation reference cases Hot-rolled flat steel · CN 72081000 + Turkey + 100t (default data, single EU route)NaNms
- CBAM cost-calculation reference cases Hydrogen · CN 28041000 + Egypt + 100t (single-route sector)NaNms
- CBAM cost-calculation reference cases Cement · Grey clinker CN 25231000 + Algeria + 100t (multi-route, route A)NaNms
- CBAM cost-calculation reference cases Cement · White clinker CN 25231000 + Algeria + 100t (route B, higher intensity)NaNms
- CBAM cost-calculation reference cases Aluminium · Unwrought CN 76011000 + Algeria + 100t (single route L, country-specific)NaNms
- CBAM cost-calculation reference cases Fertilisers · Urea aqueous low-N CN 31021012 + Macao + 300tNaNms
- CBAM cost-calculation reference cases Fertilisers · Ammonia CN 28141000 + China + 100t (high-emissions origin)NaNms
- CBAM cost-calculation reference cases Electricity · CN 27160000 + Türkiye + 100 MWh (country-specific Annex III)NaNms
- CBAM cost-calculation reference cases Electricity · CN 27160000 + Canada + 100 MWh (alternative default per §4.2.2)NaNms
- CBAM cost-calculation reference cases Electricity · CN 27160000 + Albania + 100 MWh (zero-emission edge case)NaNms
- CBAM cost-calculation reference cases Electricity · CN 27160000 + United Kingdom + 100 MWh (decarbonised grid)NaNms
- CBAM cost-calculation reference cases Electricity · CN 27160000 + Bosnia and Herzegovina + 100 MWh (lignite-heavy, highest in Annex III)NaNms
tests/cbam-input-validation.test.ts
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES excludes all 27 EU member states4ms
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES excludes EFTA + UK (Norway/Iceland/Liechtenstein/Switzerland/UK)0ms
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES still contains the major CBAM origins0ms
- Origin-country filter (Reg 2023/956 Annex III + EU SAT) CBAM_ORIGIN_COUNTRIES is strictly smaller than ORIGIN_COUNTRIES0ms
- Inexact-CN fallback warning (Reg 2025/2547 §A.2.7) CN 31021000 (urea heading, no exact 8-digit row) emits a ⚠ noteNaNms
- Inexact-CN fallback warning (Reg 2025/2547 §A.2.7) CN 72081000 (steel, exact match via chapter heading 7208) does NOT emit fallback warningNaNms
tests/cbam-pricing.test.ts
- pickPaygTier — band boundaries €0 → cbam_report_micro (zero tax (out-of-scope CN) still wants a PDF)2ms
- pickPaygTier — band boundaries €1 → cbam_report_micro (minimal exposure)0ms
- pickPaygTier — band boundaries €999.99 → cbam_report_micro (just under €1k boundary)0ms
- pickPaygTier — band boundaries €1000 → cbam_report_micro (exactly €1k — tie goes to cheaper tier (buyer-friendly))0ms
- pickPaygTier — band boundaries €1000.01 → cbam_report_standard (first cent above €1k)0ms
- pickPaygTier — band boundaries €5000 → cbam_report_standard (mid-Standard)0ms
- pickPaygTier — band boundaries €10000 → cbam_report_standard (exactly €10k boundary — cheaper tier wins)0ms
- pickPaygTier — band boundaries €10000.01 → cbam_report_heavy (first cent above €10k)0ms
- pickPaygTier — band boundaries €25000 → cbam_report_heavy (mid-Heavy)0ms
- pickPaygTier — band boundaries €50000 → cbam_report_heavy (exactly €50k boundary)0ms
- pickPaygTier — band boundaries €50000.01 → cbam_report_enterprise (first cent above €50k)0ms
- pickPaygTier — band boundaries €1000000 → cbam_report_enterprise (absurd value still resolves)0ms
- pickPaygTier — band boundaries €-10 → cbam_report_micro (negative cost (refund?) defaults to Micro)0ms
- pickPaygTier — band boundaries €NaN → cbam_report_micro (NaN guard — never crash the buy form)0ms
- PAYG tier metadata PAYG_TIER_IDS lists exactly 4 tiers in cheapest-first order1ms
- PAYG tier metadata paygTierLabel returns short and long forms0ms
- PAYG tier metadata formatUsd (kept as alias for formatEur) renders euros0ms
- PAYG tier metadata paygTierPrice handles missing tier and missing price safely0ms
tests/cbam-rounding.test.ts
- EU rounding helpers roundEmissionsTotal: preserves 4dp for per-shipment values (Reg 2025/2547 §A.2.7)2ms
- EU rounding helpers roundAnnualReportEmissions: full integer tonnes (Reg 2025/2547 §A.2.6)0ms
- EU rounding helpers roundIntensity: ≤5 decimal places (Reg 2025/2547 §A.2.8)0ms
- EU rounding helpers roundEur: 2 decimal places (cent precision)0ms
- EU rounding helpers roundPricePerTco2e: 4 decimal places (EU certificate-price format)0ms
- EU rounding helpers symmetry: helpers are pure functions0ms
- API boundaries clamp intensity to ≤5dp per Reg 2025/2547 §A.2.8 /api/v1/cbam/routes (lookupAvailableRoutes) — every value_for_year is ≤5dpNaNms
tests/cbam-sat-scope.test.ts
- EU SAT scope cross-check (573 CN codes) every SAT-listed CN code resolves as in-scopeNaNms
- EU SAT scope cross-check (573 CN codes) scope sectors match SAT's main categoriesNaNms
How to read this page
- Cost-calculation cases are derived BY HAND from the EU formulas — independent of our calculator's implementation. A regression in the calculator changes the output but NOT the expected number, so the test fails immediately.
- Scope assertions cross-reference the EU's own published Self-Assessment Tool. If the EU adds CN codes or revises the SAT, we re-import + re-run the suite.
- Tests run before every release. A failing test blocks the build — the calculator can't go live with known-wrong outputs.
- Want to add a reference case? Open an issue with the input and the regulatory derivation; we'll add it to the suite.