Every SupplierPurchaseRecord automatically calculates transport emissions when transport_method, distance_km, and related weight fields are provided. This recipe shows how to leverage that calculation to compare modes side-by-side and justify transport choices in ESG reports.
Emission Factor Formula
CO₂ (kg) = factor × distance_km × (weight_kg / 1000)
| Transport Mode | Emission Factor | Unit |
|---|---|---|
ROAD | 0.000096 | kg CO₂ / (tonne · km) |
SEA | 0.000011 | kg CO₂ / (tonne · km) |
AIR | 0.000602 | kg CO₂ / (tonne · km) |
RAIL | 0.000028 | kg CO₂ / (tonne · km) |
1. Create One Record per Transport Mode
Use the same shipment parameters for all four records so the comparison is apples-to-apples. Here: 500 kg fabric from India to Italy, 7 200 km.
curl -X POST "http://localhost:8080/api/v1/purchases?userId=1" \-H "Content-Type: application/json" \-d '{"supplier_id": 42,"supplier_product_id": 17,"purchase_date": "2026-03-01T08:00:00","quantity_kg": 500.0,"transport_method": "ROAD","distance_km": 7200,"batch_number": "COMP-ROAD-2026-03"}'
curl -X POST "http://localhost:8080/api/v1/purchases?userId=1" \-H "Content-Type: application/json" \-d '{"supplier_id": 42,"supplier_product_id": 17,"purchase_date": "2026-03-01T08:00:00","quantity_kg": 500.0,"transport_method": "SEA","distance_km": 7200,"batch_number": "COMP-SEA-2026-03"}'
curl -X POST "http://localhost:8080/api/v1/purchases?userId=1" \-H "Content-Type: application/json" \-d '{"supplier_id": 42,"supplier_product_id": 17,"purchase_date": "2026-03-01T08:00:00","quantity_kg": 500.0,"transport_method": "AIR","distance_km": 7200,"batch_number": "COMP-AIR-2026-03"}'
curl -X POST "http://localhost:8080/api/v1/purchases?userId=1" \-H "Content-Type: application/json" \-d '{"supplier_id": 42,"supplier_product_id": 17,"purchase_date": "2026-03-01T08:00:00","quantity_kg": 500.0,"transport_method": "RAIL","distance_km": 7200,"batch_number": "COMP-RAIL-2026-03"}'
2. Results at a Glance
The API returns emissions data in every 201 Created response. For the scenario above (7 200 km, 500 kg):
| Transport Mode | CO₂ Emissions | vs. SEA baseline |
|---|---|---|
SEA | 0.0396 kg | baseline |
RAIL | 0.1008 kg | +155% |
ROAD | 0.3456 kg | +773% |
AIR | 2.1672 kg | +5 373% |
Sea freight emits ~55× less CO₂ than air for the same route. When lead time allows, sea is the default recommended choice for intercontinental textile shipments.
3. Python: Automate the Comparison
import requestsBASE_URL = "http://localhost:8080"def compare_transport(supplier_id: int, product_id: int,distance_km: float, weight_kg: float,purchase_date: str = "2026-03-01T08:00:00"):modes = ["ROAD", "SEA", "AIR", "RAIL"]results = []for mode in modes:resp = requests.post(f"{BASE_URL}/api/v1/purchases?userId=1",json={"supplier_id": supplier_id,"supplier_product_id": product_id,"purchase_date": purchase_date,"quantity_kg": weight_kg,"transport_method": mode,"distance_km": distance_km,"batch_number": f"COMP-{mode}-AUTO",}).json()results.append((mode, resp.get("transport_emissions_tco2", 0)))results.sort(key=lambda x: x[1])print(f"\nCO₂ comparison — {distance_km} km, {weight_kg} kg\n")print(f"{'Mode':<8} {'CO₂ (kg)':>12} {'vs best':>10}")print("-" * 34)baseline = results[0][1]for mode, co2 in results:ratio = f"+{((co2 / baseline) - 1) * 100:.0f}%" if co2 != baseline else "baseline"print(f"{mode:<8} {co2:>12.4f} {ratio:>10}")compare_transport(supplier_id=42,product_id=17,distance_km=7200,weight_kg=500)
4. Cancel Comparison Records
Comparison records are created with status ORDERED by default. Cancel them immediately if they were only created for analysis purposes.
for id in 201 202 203 204; docurl -X PATCH "http://localhost:8080/api/v1/purchases/$id?userId=1" \-H "Content-Type: application/json" \-d '{ "purchase_status": "CANCELLED" }'done
If you use batch_number values in comparison records, choose unique names (e.g. COMP-SEA-2026-03) so they do not conflict with real production batches. batch_number must be unique per supplier_id.