Bulk and breakbulk emissions all modes, v3 Fuel switch, V3 Emission new endpoint, and Milk Run fuels support
π September 2025
It may have been summer, but we clearly didnβt take much of a break βοΈ!
This release brings a packed set of updates across our APIs:
- bulk and breakbulk emissions calculations for all modes in the Shipment API v2.1.
- Expanded fuels support in the Milk Run API v2.
- Correct ECA fuel switch in the Fuel API v3.
- A brand-new Emission API in v3 collection.
- Improvements and fixes in the Vessel API.
π Overview
π± Carbon Emissions APIs
β¨ New features in /shipment/v2/report/co2
/shipment/v2/report/co2
π Bulk & breakbulk emissions supported for all modes
You can now calculate emissions for bulk and breakbulk orders on any mode: sea
, road
, inland_water
, rail
and air
, using the /shipment/v2/report/co2
.
Example of a bulk shipment including rail, sea and road legs:
{
"orders": [
{
"type": "bulk",
"weight": 300
}
],
"transportChainElements": [
{
"type": "hub",
"hubType": "WAREHOUSE"
},
{
"type": "leg",
"from": "FRPAR",
"to": "FRLIO",
"mode": "rail"
},
{
"type": "leg",
"from": "FRMRS",
"to": "CNSHA",
"mode": "sea"
},
{
"type": "leg",
"from": "CNSHA",
"to": "CNLYG",
"mode": "road"
}
]
}
{
"parameters": {
"orders": [
{
"weight": 300.0,
"type": "bulk"
}
]
},
"co2e": {
"total": 429554,
"wtt": 90127,
"ttw": 339427,
"intensity": 0.08228
},
"transportChainElements": [
{
"type": "hub",
"location": {
"locode": "FRPAR",
"iata": "PAR",
"coordinates": [
2.332535,
48.84664
],
"city": "Paris Airports",
"country": "France",
"region": "North Europe"
},
"parameters": {
"hubType": "WAREHOUSE"
},
"properties": {
"dataType": "default",
"source": "user_input",
"hubType": "warehouse",
"orders": [
{
"weight": 300.0,
"type": "bulk",
"co2e": {
"total": 13650,
"wtt": 2730,
"ttw": 10920
}
}
]
},
"co2e": {
"total": 13650,
"wtt": 2730,
"ttw": 10920
}
},
{
"type": "leg",
"from": {
"locode": "FRPAR",
"iata": "PAR",
"coordinates": [
2.332535,
48.84664
],
"city": "Paris Airports",
"country": "France",
"region": "North Europe"
},
"to": {
"locode": "FRLIO",
"iata": "LYS",
"coordinates": [
5.081111,
45.725556
],
"city": "Lyon Saint-ExupΓ©ry Airport",
"country": "France",
"region": "Mediterranean/Black Sea"
},
"tradeLane": "North Europe to-from Mediterranean",
"mode": "rail",
"parameters": {},
"properties": {
"dataType": "default",
"distance": {
"sfd": {
"total": 481712
},
"used": {
"total": 481712,
"source": "daf"
}
},
"model": {
"name": "sfd-direct-emissionfactors"
},
"orders": [
{
"weight": 300.0,
"type": "bulk",
"co2e": {
"total": 2717,
"wtt": 1416,
"ttw": 1301,
"intensity": 0.0188
}
}
]
},
"co2e": {
"total": 2717,
"wtt": 1416,
"ttw": 1301,
"intensity": 0.0188
}
},
{
"type": "hub",
"location": {
"locode": "FRLIO",
"iata": "LYS",
"coordinates": [
5.081111,
45.725556
],
"city": "Lyon Saint-ExupΓ©ry Airport",
"country": "France",
"region": "Mediterranean/Black Sea"
},
"parameters": {},
"properties": {
"dataType": "default",
"source": "auto_generated",
"hubType": "transhipment_site",
"orders": [
{
"weight": 300.0,
"type": "bulk",
"co2e": {
"total": 390,
"wtt": 78,
"ttw": 312
}
}
]
},
"co2e": {
"total": 390,
"wtt": 78,
"ttw": 312
}
},
{
"type": "leg",
"from": {
"locode": "FRMRS",
"iata": null,
"coordinates": [
5.34005236625671,
43.3317317962646
],
"city": "Marseille",
"country": "France",
"region": "Mediterranean/Black Sea"
},
"to": {
"locode": "CNSHA",
"iata": null,
"coordinates": [
122.06550521343334,
30.61798396262171
],
"city": "Shanghai",
"country": "China",
"region": "North East Asia"
},
"tradeLane": "Asia to-from Mediterranean",
"mode": "sea",
"parameters": {},
"properties": {
"dataType": "default",
"distance": {
"sfd": {
"total": 16321106
},
"used": {
"total": 18769272,
"source": "daf",
"seca": 3396691
}
},
"model": {
"name": "sfd-direct-emissionfactors"
},
"vessel": {
"imo": null,
"name": "GLEC Representative Vessel",
"minTeu": null,
"maxTeu": null,
"minDwt": 0,
"maxDwt": 9999,
"fuelType": "vlsfo"
},
"tradeLane": "Asia to-from Mediterranean",
"orders": [
{
"weight": 300.0,
"type": "bulk",
"co2e": {
"total": 207860,
"wtt": 36262,
"ttw": 171598,
"intensity": 0.04245
}
}
]
},
"co2e": {
"total": 207860,
"wtt": 36262,
"ttw": 171598,
"intensity": 0.04245
}
},
{
"type": "hub",
"location": {
"locode": "CNSHA",
"iata": null,
"coordinates": [
122.06550521343334,
30.61798396262171
],
"city": "Shanghai",
"country": "China",
"region": "North East Asia"
},
"parameters": {},
"properties": {
"dataType": "default",
"source": "auto_generated",
"hubType": "transhipment_site",
"orders": [
{
"weight": 300.0,
"type": "bulk",
"co2e": {
"total": 390,
"wtt": 78,
"ttw": 312
}
}
]
},
"co2e": {
"total": 390,
"wtt": 78,
"ttw": 312
}
},
{
"type": "leg",
"from": {
"locode": "CNSHA",
"iata": null,
"coordinates": [
122.06550521343334,
30.61798396262171
],
"city": "Shanghai",
"country": "China",
"region": "North East Asia"
},
"to": {
"locode": "CNLYG",
"iata": null,
"coordinates": [
119.424457550049,
34.7475471496582
],
"city": "Lianyungang",
"country": "China",
"region": "North East Asia"
},
"tradeLane": "Intra NE Asia",
"mode": "road",
"parameters": {},
"properties": {
"dataType": "default",
"distance": {
"sfd": {
"total": 599188
},
"used": {
"total": 599188,
"source": "daf"
}
},
"model": {
"name": "sfd-direct-emissionfactors"
},
"region": "Asia",
"truck": {
"minSize": 0.0,
"maxSize": 3.5,
"loadFactor": null,
"emptyRunning": null,
"fuelType": "petrol",
"combinedEmptyRunningLoadFactor": 0.24
},
"orders": [
{
"weight": 300.0,
"type": "bulk",
"co2e": {
"total": 204547,
"wtt": 49562,
"ttw": 154984,
"intensity": 1.13791
}
}
],
"carrier": null
},
"co2e": {
"total": 204547,
"wtt": 49562,
"ttw": 154984,
"intensity": 1.13791
}
}
]
}
New fuels in /asset/v2/run/co2
/asset/v2/run/co2
Report milk run emissions with full fuel coverage
The list of fuels supported in the Run API (/asset/v2/run/co2
) has been expanded to match the same set available in the Shipment API (/shipment/v2/report/co2
). This update makes it possible for 3PLs, asset-based freight forwarders, and logistics providers designing milk run operations to report emissions more accurately, based on the actual fuel used.
Newly added fuels include:
CNG
, LNG
, HVO
, BIOCNG
, BIOLNG
, BIODIESEL
, HYDROGEN_GASEOUS_FCV
, ELEC
, and a wide range of biodiesel blends (B1
, B2
, B5
, B7
, B10
, B20
, B30
, B50
).
π§βπ» V3 APIs - beta
β¨ New endpoint /v3/routes/{id}/emission
/v3/routes/{id}/emission
You can now retrieve carbon emissions for any route in v3, with the new Emissions endpoint.
This endpoint supports all route types (shortest
, historical
, schedule
, and proforma
).
βοΈ How it works
- Request a route via
/v3/routes
.
β Youβll get back arouteId
. - Use the
routeId
to call/v3/routes/{id}/emission
.
β Youβll receive total emissions, leg-level breakdowns, and intensity values.
This flow applies consistently across route types:
shortest
: emissions estimated for a direct and optimized path (with or without IMO given).historical
: emissions based on AIS-derived vessel traces.schedule
: emissions based on upcoming carrier schedules.proforma
: emissions averaged across multiple potential vessels per service per leg, with statistics (min
,max
,average
,standardDeviation
) available.
β¨ Features
- Always includes by-leg breakdowns (
wtw
,wtt
,ttw
, andintensity
). - Supports COβe only, but scalable to all pollutants in the future.
- Default: one single emissions value (
emissionPoint
) returned. Forproforma
routes, it corresponds to theaverage
across vessels in the service. - Optional: detailed statistics with
?emissionType=statistics
, returningmin
,max
,average
andstandardDeviation
. Forproforma
routes, these values reflect the variation in vessel performances across the service, helping your procurement team to assess not only the emissions average but also the potential range of outcomes. For other route types, statistics do not apply (all values are equal, deviation = 0).
Example
- First, get a route via
/v3/routes
:
{
"type": "schedule",
"mode": "sea",
"carrier": {
"scac": "CMDU"
},
"from": "CNSHA",
"to": "LBBEY",
"departureDate": "2025-09-08"
}
[
{
"object": "route",
"id": "JLKhPgjlq3Y",
"type": "schedule",
"from": {
"locode": "CNSHA",
"city": "Shanghai",
"country": "CN",
"region": "North East Asia",
"geometry": {
"type": "Point",
"coordinates": [
122.06550521343334,
30.61798396262171
]
}
},
"to": {
"locode": "LBBEY",
"city": "Beirut",
"country": "LB",
"region": "Mediterranean/Black Sea",
"geometry": {
"type": "Point",
"coordinates": [
35.5318330108041,
33.9101654064168
]
}
},
"departure": {
"dateTime": {
"dateTime": "2025-09-13T12:00:00Z",
"timestamp": 1757764800000
},
"type": "dateTime"
},
"arrival": {
"dateTime": {
"dateTime": "2025-10-02T14:00:00Z",
"timestamp": 1759413600000
},
"type": "dateTime"
},
"duration": {
"days": 19,
"seconds": 1648800
},
"carriers": [
{
"id": 21,
"name": "CMA CGM",
"scac": "CMDU"
}
],
"distance": {
"meters": 27989222
},
"distanceInSeca": {
"meters": 4037275
},
"legs": [
{
"mode": "sea",
"from": {
"locode": "CNSHA",
"city": "Shanghai",
"country": "CN",
"region": "North East Asia",
"geometry": {
"type": "Point",
"coordinates": [
122.06550521343334,
30.61798396262171
]
}
},
"to": {
"locode": "LBBEY",
"city": "Beirut",
"country": "LB",
"region": "Mediterranean/Black Sea",
"geometry": {
"type": "Point",
"coordinates": [
35.5318330108041,
33.9101654064168
]
}
},
"departure": {
"dateTime": {
"dateTime": "2025-09-13T12:00:00Z",
"timestamp": 1757764800000
},
"type": "dateTime"
},
"arrival": {
"dateTime": {
"dateTime": "2025-10-02T14:00:00Z",
"timestamp": 1759413600000
},
"type": "dateTime"
},
"duration": {
"days": 19,
"seconds": 1648800
},
"carriers": [
{
"id": 21,
"name": "CMA CGM",
"scac": "CMDU"
}
],
"distance": {
"meters": 27989222
},
"distanceInSeca": {
"meters": 4037275
},
"calls": [
{
"locode": "CNSHA",
"city": "Shanghai",
"country": "CN",
"region": "North East Asia",
"geometry": {
"type": "Point",
"coordinates": [
122.06550521343334,
30.61798396262171
]
}
},
{
"locode": "CNSHK",
"city": "Shekou Pt",
"country": "CN",
"region": "North East Asia",
"geometry": {
"type": "Point",
"coordinates": [
113.904994726181,
22.464892928223
]
}
},
{
"locode": "SGSIN",
"city": "Singapore",
"country": "SG",
"region": "South East Asia",
"geometry": {
"type": "Point",
"coordinates": [
103.735244750977,
1.25566798448563
]
}
},
{
"locode": "EGALY",
"city": "El Iskandariya (Alexandria)",
"country": "EG",
"region": "Africa",
"geometry": {
"type": "Point",
"coordinates": [
29.8456554412842,
31.1581859588623
]
}
},
{
"locode": "LBBEY",
"city": "Beirut",
"country": "LB",
"region": "Mediterranean/Black Sea",
"geometry": {
"type": "Point",
"coordinates": [
35.5318330108041,
33.9101654064168
]
}
}
],
"service": {
"id": 1997,
"name": "OCEAN Alliance - Phoenician Express-BEX2"
},
"asset": {
"vessel": {
"imo": 9882499,
"name": "CMA CGM HERMES"
},
"type": "vessel"
}
}
]
}
]
- Then, retrieve the emissions using the route
id
retrieved (JLKhPgjlq3Y
), viav3/routes/{id}/emission
:
curl --request GET \
--url https://api.searoutes.com/v3/routes/JLKhPgjlq3Y/emission \
--header 'accept: application/json' \
--header 'x-api-key: YOUR API KEY'
{
"object": "emission",
"total": [
{
"emissionPoint": {
"pollutant": "co2e",
"wtt": {
"unit": "gram",
"value": 177719
},
"ttw": {
"unit": "gram",
"value": 1021279
},
"wtw": {
"unit": "gram",
"value": 1198998
},
"intensity": {
"unit": "kg/t.km",
"value": 0.00868
}
},
"type": "emissionPoint"
}
],
"byLeg": [
{
"index": 0,
"total": [
{
"emissionPoint": {
"pollutant": "co2e",
"wtt": {
"unit": "gram",
"value": 177719
},
"ttw": {
"unit": "gram",
"value": 1021279
},
"wtw": {
"unit": "gram",
"value": 1198998
},
"intensity": {
"unit": "kg/t.km",
"value": 0.00868
}
},
"type": "emissionPoint"
}
]
}
],
"properties": {
"shipment": {
"weight": 10000.0,
"reference": null,
"containerSizeTypeCode": "20GP",
"nContainers": 1.0,
"nTeu": 1.0
},
"route": "JLKhPgjlq3Y"
}
}
π§ Fixes & improvements
Fixed fuel switch in ECA zones in /v3/routes/{id}/fuel
/v3/routes/{id}/fuel
When a route enters an Emission Control Area (ECA), vessels must switch to a compliant fuel. Previously, the Fuel API was returning only one fuel grade for all routes. Weβve fixed the logic so the response now includes each fuel used with their respective totals and per-leg breakdowns.
Example:
{
"object": "fuel",
"data": {
"total": [
{
"fuelConsumption": {
"grade": "VLSFO",
"unit": "gram",
"value": 996239,
"mode": "sea"
},
"type": "fuelConsumption"
},
{
"fuelConsumption": {
"grade": "LSMDO",
"unit": "gram",
"value": 220069,
"mode": "sea"
},
"type": "fuelConsumption"
}
],
"byLeg": [
{
"index": 0,
"total": [
{
"fuelConsumption": {
"grade": "VLSFO",
"unit": "gram",
"value": 996239,
"mode": "sea"
},
"type": "fuelConsumption"
},
{
"fuelConsumption": {
"grade": "LSMDO",
"unit": "gram",
"value": 220069,
"mode": "sea"
},
"type": "fuelConsumption"
}
]
}
]
},
"properties": {
"shipment": {
"weight": 45000.0,
"reference": null,
"containerSizeTypeCode": "40HC",
"nContainers": 2.0,
"nTeu": 4.5
},
"route": "H16IFewBUNy"
}
}
NB: retrieving fuel data is only available for both schedule
and historical
route types (proforma
and shortest
route types are excluded).
π’ Vessel API suite
π§ Fixes & improvements
Improved vessel name matching in /vessel/v2/info
/vessel/v2/info
Previously, when querying /vessel/v2/info
with a vessel name, the API could return vessels that formerly had this name (in fka
for "formerly known as") before the vessel that currently uses it.
Weβve updated the logic so that results now prioritize vessels with the current name first.
Example: /vessel/v2/HOOGE/info
- Before: returned first
EAGLE II
(exHOOGE
) before the vessel currently namedHOOGE
. - Now: returns the vessel currently named
HOOGE
first β
This makes searches more intuitive when vessels have changed names over time.
[
{
"imo": 9944780,
"name": "HOOGE",
"vesselType": "container_ship",
"length": 171.9,
"width": 28.4,
"maxDraft": 9.7,
"dwt": 24423,
"gt": 18680,
"mmsi": 305524000,
"fka": null
},
{
"imo": 9301122,
"name": "EAGLE II",
"vesselType": "container_ship",
"length": 160.82,
"width": 25,
"maxDraft": 9.9,
"dwt": 16986,
"gt": 15633,
"mmsi": 538010031,
"fka": [
"HOOGE"
]
}
]
[
{
"imo": 9301122,
"name": "EAGLE II",
"vesselType": "container_ship",
"length": 160.82,
"width": 25,
"maxDraft": 9.9,
"dwt": 16986,
"gt": 15633,
"mmsi": 538010031,
"fka": [
"HOOGE"
]
},
{
"imo": 9944780,
"name": "HOOGE",
"vesselType": "container_ship",
"length": 171.9,
"width": 28.4,
"maxDraft": 9.7,
"dwt": 24423,
"gt": 18680,
"mmsi": 305524000,
"fka": null
}
]
More accurate to
locations in /vessel/v2/{imo}/eta
to
locations in /vessel/v2/{imo}/eta
Weβve improved how the API parses AIS destination
fields to extract the to
location.
Previously, depending on how the shipβs captain entered the string, the API sometimes picked the first locode instead of the intended last one, leading to inconsistent behavior, and incorrect to
values in certain cases.
We now execute a smarter parsing of common separators (>
, >>
, <>
, -
, /
, " TO "
, etc.).
Examples:
destination
=NLVLI>LTKLJ
βto
=JPYOK
β (separator>
correctly handled).destination
=JPYOK-CAPRR
β previouslyto
=JPYOK
β (separator-
was not handled)- β now correctly returns
to
=CAPRR
β . - see detailed example below:
vessel/v2/9290464/eta
- β now correctly returns
{
"info": {
"imo": 9290464,
"name": "NORWALK",
"length": 300.0,
"width": 42.8,
"mmsi": 636093305,
"maxDraft": 15.5
},
"position": {
"type": "Feature",
"properties": {
"timestamp": 1756306597000,
"speed": 29.6,
"cog": 71.2,
"heading": 72,
"draft": 12.7,
"eta": "2025-09-02T10:00:00Z",
"destination": "JPYOK-CAPRR"
},
"geometry": {
"type": "Point",
"coordinates": [
169.517547,
47.948903
]
}
},
"to": {
"etaFromAIS": 1756807200000,
"etaFromPredictedRoute": 1756812907000,
"distance": 4167500.0,
"location": {
"type": "Feature",
"properties": {
"name": "Prince Rupert",
"locode": "CAPRR"
},
"geometry": {
"type": "Point",
"coordinates": [
-130.337885822088,
54.3033533340315
]
}
}
}
}
{
"info": {
"imo": 9290464,
"name": "NORWALK",
"length": 300.0,
"width": 42.8,
"mmsi": 636093305,
"maxDraft": 15.5
},
"position": {
"type": "Feature",
"properties": {
"timestamp": 1756306597000,
"speed": 29.6,
"cog": 71.2,
"heading": 72,
"draft": 12.7,
"eta": "2025-09-02T10:00:00Z",
"destination": "JPYOK-CAPRR"
},
"geometry": {
"type": "Point",
"coordinates": [
169.517547,
47.948903
]
}
},
"to": {
"etaFromAIS": 1756807200000,
"etaFromPredictedRoute": 1756664770000,
"distance": 2948163.0,
"location": {
"type": "Feature",
"properties": {
"name": "Yokohama",
"locode": "JPYOK"
},
"geometry": {
"type": "Point",
"coordinates": [
139.702354431152,
35.4433536529541
]
}
}
}
}
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]!