🚒 Bulk & breakbulk emissions, and other improvements

πŸ“… June 2025

This release introduces support for bulk and breakbulk emissions calculations, a well-expected addition to our Shipment API. Alongside this, we’ve rolled out several fixes and enhancements to improve the accuracy and reliability of emissions modeling, ocean routing logic, vessel data, and support APIs.


πŸ“š Overview


🌱 Carbon Emissions APIs

✨ New features in /shipment/v2/report/co2

πŸ†• Bulk & breakbulk emissions supported (sea mode only)

You can now calculate emissions for bulk and breakbulk orders, using the /shipment/v2/report/co2 endpoint. If a vessel is provided:

  • The vessel is considered if its designation matches the shipment type:bulk is compatible with bulk ships;breakbulk is compatible with general cargo ships.
  • Emissions are refined based on the ship DWT (known in our DB).

To support transparency, vessel DWT range used in the emissions calculation is included in the response properties.

Example request

{
  "orders": [
    {
      "type": "bulk",
      "weight": 1000
    }
  ],
  "transportChainElements": [
    {
      "type": "leg",
      "from": "USLGB",
      "to": "DEHAM",
      "mode": "sea",
      "details": {
        "vessel": {
          "imo": "9544750"
        }
      }
    }
  ]
}
{
    "parameters": {
        "orders": [
            {
                "weight": 1000.0,
                "type": "bulk"
            }
        ]
    },
    "co2e": {
        "total": 127591,
        "wtt": 21930,
        "ttw": 105662,
        "intensity": 0.00846
    },
    "transportChainElements": [
        {
            "type": "leg",
            "from": {
                "locode": "USLGB",
                "iata": null,
                "coordinates": [
                    -118.21435,
                    33.75493
                ],
                "city": "Long Beach",
                "country": "United States",
                "region": "North America - West Coast"
            },
            "to": {
                "locode": "DEHAM",
                "iata": null,
                "coordinates": [
                    9.93855,
                    53.519272
                ],
                "city": "Hamburg",
                "country": "Germany",
                "region": "North Europe"
            },
            "tradeLane": "North Europe to-from North America WC",
            "mode": "sea",
            "parameters": {
                "details": {
                    "vessel": {
                        "imo": "9544750"
                    }
                }
            },
            "properties": {
                "dataType": "default",
                "distance": {
                    "sfd": {
                        "total": 15074581
                    },
                    "used": {
                        "total": 17335768,
                        "source": "daf",
                        "seca": 1619935
                    }
                },
                "model": {
                    "name": "sfd-direct-emissionfactors"
                },
                "vessel": {
                    "imo": 9544750,
                    "name": "ALYTUS",
                    "minTeu": null,
                    "maxTeu": null,
                    "minDwt": 35000,
                    "maxDwt": 59999,
                    "fuelType": "vlsfo"
                },
                "tradeLane": "North Europe to-from North America WC",
                "orders": [
                    {
                        "weight": 1000.0,
                        "type": "bulk",
                        "co2e": {
                            "total": 127591,
                            "wtt": 21930,
                            "ttw": 105662,
                            "intensity": 0.00846
                        }
                    }
                ]
            },
            "co2e": {
                "total": 127591,
                "wtt": 21930,
                "ttw": 105662,
                "intensity": 0.00846
            }
        }
    ]
}

What's not included in this release

  • Bulk and breakbulk calculations are not supported for any other mode than sea.
  • Breakbulk loaded on container vessels is not supported, as this requires a different calculation model.
  • Vessel input remains imo and/or name only, we don't support vessel dwt user input.

πŸ”§ Fixes & improvements in /shipment/v2/report/co2

βš™οΈ Improved compatibility between vessel and shipment type

We improved our vessel type validation based on the shipment type. Previously, some containerized shipments (fcl, lcl or parcel) matched not only with container vessels, but also general cargo ships, leading to inflated emissions due to the small TEU capacity.

We now default to fallback models when incompatibilities are detected, reducing overestimates and improving consistency.

πŸ›« Air freight: flight number route validation

We fixed an issue where flight numbers could generate unrealistic routes if they didn’t match the user’s from/to inputs. Now, when a user inputs a flight.Number, if its path doesn’t match the locations given even partially, the API falls back to direct routing. It avoids overestimated emissions due to detours and offers a better reliability.

Example

We now ignore flight data when the flight’s actual path doesn’t match either the from or to provided by the user. In such cases, the API falls back to a direct route using the default aircraft model, avoiding unrealistic detours and inflated emissions.

In the example below (CDG to LHR with flight AF345, which actually flies YUL β†’ CDG), the system created a detour:

  • CDG β†’ YUL (default emissions)
  • YUL β†’ CDG (modeled emissions, based on flight number aircraft)
  • CDG β†’ LHR (default emissions)

Total: 6.9 tons (overestimated).

With the fix, we now return a single direct leg with default aircraft data, resulting in 0.6 tons, much more realistic.

{
  "orders": [
    {
      "type": "parcel",
      "weight": 1000
    }
  ],
  "transportChainElements": [
    {
      "type": "leg",
      "from": "CDG",
      "to": "LHR",
      "mode": "air",
      "details": {
        "carrier": {
          "iata": "AF"
        },
        "flight": {
          "number": "345"
        }
      }
    }
  ]
}
{
    "parameters": {
        "orders": [
            {
                "weight": 1000.0,
                "type": "parcel"
            }
        ]
    },
    "co2e": {
        "total": 602318,
        "wtt": 103406,
        "ttw": 498912,
        "intensity": 1.73626
    },
    "transportChainElements": [
        {
            "type": "leg",
            "from": {
                "locode": "FRCDG",
                "iata": "CDG",
                "coordinates": [
                    2.55,
                    49.012798
                ],
                "city": "Charles de Gaulle International Airport",
                "country": "France",
                "region": "North Europe"
            },
            "to": {
                "locode": "GBLHR",
                "iata": "LHR",
                "coordinates": [
                    -0.461941,
                    51.4706
                ],
                "city": "London Heathrow Airport",
                "country": "United Kingdom",
                "region": "North Europe"
            },
            "tradeLane": "Intra North Europe",
            "mode": "air",
            "parameters": {
                "details": {
                    "flight": {
                        "number": "345"
                    },
                    "carrier": {
                        "iata": "AF"
                    }
                }
            },
            "properties": {
                "dataType": "default",
                "distance": {
                    "sfd": {
                        "total": 346906
                    },
                    "used": {
                        "total": 441906,
                        "source": "daf"
                    }
                },
                "model": {
                    "name": "gcd-direct-emissionfactors"
                },
                "flight": null,
                "carrier": null,
                "aircraft": {
                    "iata": null,
                    "icao": null,
                    "manufacturer": null,
                    "model": "GLEC short haul unknown flight representative aircraft.",
                    "type": "unknown"
                },
                "orders": [
                    {
                        "weight": 1000.0,
                        "type": "parcel",
                        "co2e": {
                            "total": 602318,
                            "wtt": 103406,
                            "ttw": 498912,
                            "intensity": 1.73626
                        }
                    }
                ]
            },
            "co2e": {
                "total": 602318,
                "wtt": 103406,
                "ttw": 498912,
                "intensity": 1.73626
            }
        }
    ]
}

🚨 Error messages: better context for multi-leg routing failures

The /shipment/v2/report/co2 now includes clear context in routing errors.
When a leg fails, the error points to the specific transportChainElements[x] index, making multi-leg debugging much easier thanks to its mapping.

Example

  • Old error message

"Origin and destination should be in the same region. Supported regions for Road are : Europe, North America, South America, Africa and Asia ", "We could not find a route between 1.4666666666666668,49.4 and 122.06550521343334,30.61798396262171 using sea with a 9.5m draft vessel with parameter allowIceAreas set to false."

  • New error message

"Error in transportChainElements[0] : Origin and destination should be in the same region. Supported regions for Road are : Europe, North America, South America, Africa and Asia ", "Error in transportChainElements[1] : We could not find a route between 1.4666666666666668,49.4 and 122.06550521343334,30.61798396262171 using sea with a 9.5m draft vessel with parameter allowIceAreas set to false."


🌍 Ocean Route APIs

πŸ”§ Fixes & improvements

🚨🚧 Error messages: clearer blocked area errors in /route/v2/sea

Previously, when a routing request failed due to one or more locations falling inside a blocked area, the error message returned was too generic: "Origin, destination or intermediate point of the route is in a blocked area." Our users couldn’t tell which point was causing the failure, nor which block area was responsible for it.

The /route/v2/sea endpoint now gives detailed feedback when a location is inside a blocked area: "Point passed at index '0' is in the following blocked areas: [11247]. Point passed at index '2' is in the following blocked areas: [21554].".

πŸ—ΊοΈ Gulf of Mexico ECA zone polygon

A routing issue revealed an inaccurate ECA polygon, that was excluding Brownsville Ship Harbor from it. We’ve updated it using IMO data. As a result, distance in and out this ECA zone, as well as emissions modeling, are now accurate.


🚒 Vessel API suite

πŸ”§ Fixes & improvements

πŸ”„ Vessel info endpoint improvements

The /vessel/v2/info endpoint has been improved with:

  • new fields: dwt, gt and vesselType;
  • a better coverage and data accuracy, thanks to our vessel database full refresh and daily update.

These changes ensure more reliable vessel enrichment and consistent outputs across endpoints.


🌐 Support APIs (Geocoding / Search)

πŸ”§ Fixes & improvements

🧭 Zipcode fix in /geocoding/v2/all

We’ve fixed an issue where some zipcode queries failed to return location data, even though equivalent string queries worked. For example:

  • Failing before: /geocoding/v2/all?postalCode=143-0006&countryCodes=JP
  • Succeeding: /geocoding/v2/all?query=Heiwajima&countryCodes=JP

This has now been corrected, zipcode queries return the expected location as intended.


πŸ“˜

You made it to the end of our changelog, thanks for reading πŸ‘πŸΌ

We'd love to hear your thoughts on these updates. Send us your feedback at [email protected]!