Guides
Tutorials
Calculate Emissions from Freight Shipping

Intermodal Freight Transportation

Climatiq allows you to calculate the carbon emissions for shipping freight around the world using multiple modes of transport (intermodal) such as by sea, air, road or rail. This guide will show you how to use the intermodal freight endpoint and explain some concepts. For more detailed documentation, go to the API reference.

⚠️
Subscription plan required
This is a paid feature. Please see our pricing page for more details.

Introduction

The endpoint automatically:

  • selects emission factors for the regions, vehicles and load you are transporting from the GLEC framework.
  • calculates the distance between the start and end location of the shipment.
  • finds the port, railway terminal or airport that is closest to your locations, for transfer between different transport modes.

All emission factors used are from the Global Logistics Emissions Council(GLEC) framework (opens in a new tab).

To estimate rail leg distances, we utilize data from OpenStreetMap (opens in a new tab), which we obtain under the Open Database License (opens in a new tab).

If you prefer a video introduction, here is a 15 minute quickstart guide:

Current Limitations

The intermodal endpoint has a few limitations:

  • You are currently allowed only three legs per API call by default. Contact Climatiq (opens in a new tab) to get this limit raised.
  • Rail transportation estimates are lower quality outside of Europe. The GLEC framework does not provide as granular emission factors, and we do not have actual railroad paths for all regions outside of Europe.

With that out of the way, let's dive into what a request to the intermodal endpoint could look like.

Example Request

curl --request POST \
--url https://api.climatiq.io/freight/v1/intermodal \
--header 'Authorization: Bearer API_KEY' \
--data '{
"route": [
{
"location": {
"query": "Hamburg"
}
},
{
"transport_mode": "road"
},
{
"transport_mode": "sea"
},
{
"transport_mode": "road"
},
{
"location": {
"query": "Las Vegas"
}
}
],
"cargo": {
"weight": 10,
"weight_unit": "t"
}
}'

That will take cargo from Hamburg to Las Vegas via sea shipping, finding road routes to the nearest harbour to each city first.

We won't look in-depth at the response in this guide, but it will include, among other things, the distance and CO2-equivalents for the entire trip, and each leg separately. You can see the full response in the API reference documentation.

Now, let's take a closer look at what a request can contain. The full details are available in the API reference, but we'll also look at it a bit here. The request contains cargo which is just a Weight unit type, representing the weight of the cargo. It also contains a route, which is the path the cargo is shipped.

Route

A route consists of two or more locations, and legs between these locations. It must start and end with a location, and there must be a leg between each location.

This is an example of the structure of a valid route:

<location>
<leg>
<location>
<leg>
<location>

In some cases (such as the example above) you are allowed to omit some locations and rely on automatic routing. See the section on automatic routing below for more details.

For now, let's take a quick look at legs and locations before diving into some more complex topics.

Leg

Each route has one or more legs. A leg is a transition between two locations. For a leg you can specify the transport_mode to be air, sea, road or rail. You may also specify details of the leg such as the vehicle type. See the API reference for more details of exactly what a leg can contain.

Location

A trip always has two or more locations. Locations contain two things - the location object that explains how to actually find the location, and a location_options Location Options object that tells Climatiq how to use the location, e.g. for automatic location correction. This location can be specified via free-text query, coordinates, and more.

Advanced Concepts

You know now the basic building blocks of the intermodal freight endpoint, but there are a few advanced concepts that might be nice to know about.

Transition Points

Some types of transport have fixed start and end points, such as air travel that must be from airport to airport or rail transport that must be from railway station to railway station.

The general term Climatiq uses for airports, railway stations and sea ports are "transition points". Transportation modes that have transition points are called "fixed transition point" A leg that is between two fixed transition points, such as a rail, sea or air leg is called a "fixed transition point leg"

Automatic Routing

In some cases when travelling via fixed-transition point transport modes, you may omit some locations and rely on Climatiq doing automatic routing for you. As Climatiq has a list of transition points for each of these transport modes, it can automatically select the closest location for these queries.

As an example, the below route expresses the route: "I want to ship this from Hamburg to Miami over sea, using road to connect to the closest ports"

{
"route": [
{ "location": { "query": "Hamburg" } },
{ "transport_mode": "road" },
{ "transport_mode": "sea" },
{ "transport_mode": "road" },
{ "location": { "query": "Miami" } }
]
}

Locations can be omitted on either end of a sea, air or rail journey if the following criteria are met:

  1. The fixed-transition point journey has a road leg before or after
  2. There is a location immediately before/after that road leg

Automatic Location Correction

If a location is adjacent to a fixed-transition point leg, Climatiq automatically makes a correction to the proper port, airport or railway station.

This means that if you send the following route in a request:

{
"route": [
{ "location": { "query": "Amsterdam" } },
{ "transport_mode": "sea" },
{ "location": { "query": "Miami" } }
]
}

Climatiq will correctly route between the Amsterdam and the Miami harbour, even though the Location Amsterdam might actually mean the city center, and not the Amsterdam harbour. This is because Climatiq will automatically adjust a location slightly if it needs it to match with a transition point needed for an adjacent leg. The maximum distance it will correct is called the tolerance_km - which is the tolerance for how precise your location is.

However, if the distance to the fixed-transition point is too large, Climatiq will not automatically correct the location. As an example, if you put in the following route

{
"route": [
{ "location": { "query": "New York" } },
{ "transport_mode": "air" },
{ "location": { "query": "Copenhagen" } }
]
}

You will get an error like this:

{
"error": "bad_request",
"error_code": "invalid_input",
"message": "Location 'New York, NY, United States' was not close enough to the closest transition point for the air leg. Closest transition point is: 'Newark Liberty International Airport(40.692501,-74.168701)'. Distance between the points is 13.839174000000002km"
}

This is because the closest airport is farther away than tolerance_km and there are two ways to interpret your request:

  1. "I want this flown out of the nearest airport from New York"
  2. "I have this in the center of New York, and I need it driven out to the airport, and then flown"

Climatiq will choose the first option, if the transition point and your location are less than tolerance_km away from each other. Otherwise, you will have to specify which of the two behaviours you're looking for.

  • If you want the first option you can set the tolerance_km on the Location Options object, to tell how many kilometers away from your specified location to seek for a fixed-transition point location.
  • If you want the second option, you can add a road leg between the first location and the air leg.

You may also disable automatic location correction by setting the flag override_transition on the Location Options object to true, informing Climatiq not to attempt to look for a nearby fixed transition point, and assume that the location you have specified is a transition point.

The way this routing is built up allows you to do some rather powerful things, which we'll see in Examples below.

Examples

Here are some examples of routes using automatic routing and location tolerances. Let's take the base route of someone shipping goods from Berlin to Miami over sea.

As Berlin doesn't have a seaport, we'll need to specify a road leg to the nearest port, like this:

{
"route": [
{ "location": { "query": "Berlin" } },
{ "transport_mode": "road" },
{ "transport_mode": "sea" },
{ "location": { "query": "Miami" } }
]
}

This will route from Berlin to the nearest port, which is in Poland.

But perhaps we know that we're actually shipping out from a harbour close to Hanover, in which case we could create the following route, which will route from Berlin to a harbour close to Hanover. Due to the tolerance_km being set, the location Hanover will actually find the closest harbour to Hanover within 200km. The route will not necessarily go through Hanover itself.

{
"route": [
{ "location": { "query": "Berlin" } },
{ "transport_mode": "road" },
{ "location": { "query": "Hanover" }, "location_options": { "tolerance_km": 200 } },
{ "transport_mode": "sea" },
{ "location": { "query": "Miami" } }
]
}

If you know that you're actually going through Hanover - as perhaps your goods are being repackaged there, your route could look like this.

{
"route": [
{ "location": { "query": "Berlin" } },
{ "transport_mode": "road" },
{ "location": { "query": "Hanover" } },
{ "transport_mode": "road" },
{ "transport_mode": "sea" },
{ "location": { "query": "Miami" } }
]
}

If you have are using a transition point that we don't know about, because you've built a temporary dock for a construction project in Southend-on-Sea (which doesn't have a port) and you're bringing in small barges from Rotterdam:

{
"route": [
{ "location": { "query": "Rotterdam" } },
{
"transport_mode": "sea",
"leg_details": {
"vessel_type": "bulk_carrier",
"tonnage": "lt_10dwkt",
"fuel_source": "hfo"
}
},
{
"location": { "query": "Southend-on-Sea" },
"location_options": { "override_transition": true }
}
]
}