Inside Our Emission Engine: How EcoFreight Turns a Route Into a Carbon Number
TL;DR
A single API call calculates WTW emissions in under 50ms. Here's what happens behind the scenes.
50 milliseconds. That's the budget my team set for a single POST /api/v1/calculate call — from raw origin string to a verified WTW emissions number with GLEC Framework v3.2 factor attribution. We hit p50 around 42 ms and p95 around 174 ms in production. Below is what fits inside that window. I am Mayur Rawte (background on the author page); I work on the calculation engine and I want this post to be the answer to "what exactly happens when I make one call against your REST API?"
The five steps below are the literal pipeline. Every box is code one of us shipped. When something is approximate, I have flagged it. When something is exact, I have flagged that too. If you came here to read a marketing piece, this is not it; if you came to understand what your auditor will be able to verify from the JSON response, read on.
Step 1: Geocoding
We resolve location names to coordinates using Mapbox geocoding. "Rotterdam" becomes [51.9225, 4.4792]. You can pass city names, full addresses, port codes (NLRTM), or airport codes (FRA) — we normalize everything to lat/lng pairs before moving on. The lookup is cached for 24 hours, so a repeat city name avoids the Mapbox round trip. Cache hit ratio sits around 91% across our top thousand origins and destinations, which is most of the latency budget recovered.
Step 2: Route Calculation
Distance calculation depends on the mode:
Road
Actual driving routes via the road network -- not great-circle distance. Accounts for highways, borders, and realistic routing.
Sea
Port-to-port distances via shipping lanes. The calculation accounts for canals (Suez, Panama) and chokepoints -- vessels don't travel in straight lines.
Air
Great-circle distance plus a standard 95 km detour factor to account for non-direct flight paths, holding patterns, and airport approach procedures.
Step 3: Emission Factor Selection
We use GLEC Framework v3.2 default emission factors, published by the Smart Freight Centre and aligned with ISO 14083. The factor we select depends on four things:
- Transport mode — road, rail, sea, or air
- Vehicle/vessel type — a 3.5t van differs from a 40t articulated truck
- Fuel type — diesel, LNG, electric, etc.
- Boundary — WTW (well-to-wheel) or TTW (tank-to-wheel)
The selected factor is expressed in grams of CO2e per tonne-kilometer (g CO2e/tkm). The full factor table is downloadable from our methodology page with every value mapped back to its Smart Freight Centre source row, so an auditor can cross-walk a single response back to the input table without asking us for anything.
What happens when the input is messy
Real freight data is not a clean demo payload. We see port names written in three languages, city names without countries, IATA airport codes mixed into sea-freight forms, and shipment weights copied from commercial invoices in pounds, kilograms, and occasionally cartons. The engine treats those as data-quality problems, not as silent guesses. If a location resolves to multiple plausible places, we either return the confidence score or require the caller to send coordinates, IATA, or UN/LOCODE.
The most common production failure is not math. It is ambiguity. "Santiago" can be Chile, Spain, the Dominican Republic, or a local depot name in a customer's TMS. A route calculation that quietly picks the wrong Santiago is worse than a hard error, because the number looks precise while being useless. That is why the API accepts explicit airport codes such as SCL and location codes such as CLSAI, and why the calculator now exposes those code paths directly instead of forcing every user through autocomplete.
Weight gets similar treatment. We normalize units, reject zero or negative cargo mass, and preserve the original unit in the trace record. For refrigerated sea cargo, the cargo type is kept with the request rather than inferred from the vessel, because reefer energy is a cargo-condition problem. A chilled 40-foot container and a dry 40-foot container can sit on the same vessel and still deserve different handling in the calculation record.
Step 4: The Calculation
Example: 12 tonnes traveling 830 km by heavy truck at 62 g CO2e/tkm (WTW) = ~617 kg CO2e. The API breaks this into TTW (direct combustion) and WTT (upstream fuel production).
Step 5: Data Quality Tier
ISO 14083 defines three data quality tiers:
What an auditor can verify from one response
The thing that surprised me most when I started shipping this engine was how often the auditor only needs the JSON. Once the response carries the methodology version, the factor source, a stable calculation_id, and the engine version that ran the math, almost every assurance question is answerable from the payload alone. Three things in particular survive the audit:
- Reproducibility. The same input today and in 2028 returns the same number, provided you pin
factor_set: "glec_v3_2"on the request. When we ship a new factor table, oldcalculation_ids keep resolving against the original engine version — no silent recalculation. - Attribution. The
emission_factorfield names the value, the unit, and the source ("GLEC Framework v3.2"). The auditor cross-walks back to the published Smart Freight Centre row without asking us for anything. - Tier transparency. The response says which tier produced the number. A Tier 1 factor flagged as such is more defensible at audit than a Tier 3 claim that quietly degraded to Tier 1 because primary data was missing.
I wrote this engine because the closest competing implementations I had reviewed would not survive a CSRD assurance walk-through. The fields above are the ones I would want as the auditor on the other side of the table. For a longer take on the ecosystem and where each vendor places those fields differently, see the comparison post.
How we fail closed
A calculation API should be boring under pressure. When geocoding is unavailable, the API does not invent coordinates; it returns an error with the field that failed. When a requested vessel type is not valid for the selected mode, the response names the valid choices. When a primary-data carrier feed is stale, we downgrade the data quality tier and state that downgrade in the result. Those behaviours are not nice extras. They are what stop a dashboard from mixing precise numbers with guessed ones.
The same principle applies to latency. If a downstream route service is slow, we would rather return a controlled timeout than block the checkout flow for seconds and encourage a customer to cache bad defaults. Most calls finish fast; the handful that do not should be obvious, retryable, and traceable. That is the difference between an emissions widget and infrastructure a forwarder can put into a quote path.
The API
POST /api/v1/calculate
// Request
{
"origin": "Rotterdam, Netherlands",
"destination": "Munich, Germany",
"mode": "road",
"weight": 12000
}
// Response
{
"emissions": {
"wtw": 617.5,
"ttw": 524.9,
"wtt": 92.6,
"unit": "kgCO2e"
},
"distance_km": 830,
"emission_factor": {
"value": 62.0,
"unit": "gCO2e/tkm",
"source": "GLEC Framework v3.2"
}
}The response carries WTW and TTW breakdowns, the route distance, and the exact emission factor used. Auditors can verify the math from this payload alone — no proprietary lookup table to ask for.
Honest Limitations
Default factors are averages. A 20-year-old bulk carrier and a brand-new dual-fuel container ship get the same Tier 1 factor. That's the trade-off between accessibility and precision. If you need carrier-specific accuracy, you'll need Tier 3 primary data.
We also do not yet ship first-party Python or Node SDKs — Q3 2026 is the internal target. Today the integration is REST against the spec at /docs. And carbon credit purchase is not in scope for the engine; we measure emissions, offset providers are a separate question.
Inspect a real response
Run a Rotterdam–Munich shipment and look at the JSON. Every factor, distance, and assumption ships with the payload — see the methodology for how each one is selected.