Track freight cost indicators from official data

The API has no container freight rate quotes. It does have indicators that move with freight costs: the US diesel price, Brent, Canadian truck and rail freight price indexes, and World Bank port traffic and shipping connectivity.

Search the catalogue for freight series

The catalogue is the place to look for freight series. A search returns tables and series templates from Statistics Canada and the World Bank, and the source field tells you which publisher a result belongs to.

curl, search the catalogue for freight
curl -s "https://api.narwhalapi.com/v1/economics/catalogue?q=freight&limit=2" \
  -H "Authorization: Bearer $NARWHAL_API_KEY"
Response
{
  "results": [
    {
      "id_template": "statcan:v{vector}",
      "source": "statcan",
      "title": "Freight Rail Services Price Index, quarterly (Statistics Canada table 18-10-0181-01)",
      "frequency": "quarterly",
      "country": "CAN",
      "first_period": "2018-Q1",
      "last_period": "2026-Q3"
    },
    {
      "id_template": "statcan:v{vector}",
      "source": "statcan",
      "title": "Freight Rail Services Price Index, monthly (Statistics Canada table 18-10-0212-01)",
      "frequency": "monthly",
      "country": "CAN",
      "first_period": "2018-01",
      "last_period": "2026-10"
    }
  ]
}

Each result is a table or a series template, with frequency, first_period and last_period. The id_template for Statistics Canada is statcan:v{vector}. A table in the catalogue is not a series. You read a series with a vector number copied from the table page on the Statistics Canada site, and there is no route that lists a table's vectors. The guide to a Statistics Canada table by its id shows the steps.

Read a freight price index

The truck transportation vector statcan:v1490434186 comes from the for-hire motor carrier table. Its observations route takes start and end as months.

curl, truck freight price index
curl -s "https://api.narwhalapi.com/v1/economics/catalogue/series/observations?id=statcan:v1490434186&start=2026-04&end=2026-06" \
  -H "Authorization: Bearer $NARWHAL_API_KEY"
Response
{
  "id": "statcan:v1490434186",
  "title": "Canada;Truck transportation",
  "frequency": "monthly",
  "unit": "extended",
  "unit_label": "Index, 2021=100",
  "seasonal_adjustment": "not_stated",
  "attribution": "Contains information licensed under the Open Government Licence - Canada. Source: Statistics Canada. Values normalised by Narwhal.",
  "licence_url": "https://open.canada.ca/en/open-government-licence-canada",
  "fetched_at": "2026-11-03T02:22:02Z",
  "observations": [
    {
      "period": "2026-04",
      "value": "133.9",
      "released_on": "2026-08-31"
    },
    {
      "period": "2026-05",
      "value": "133.3",
      "released_on": "2026-08-31"
    },
    {
      "period": "2026-06",
      "value": "131.9",
      "released_on": "2026-08-31"
    }
  ],
  "next_cursor": null
}

The title is Canada;Truck transportation, the unit_label is Index, 2021=100, and each observation has a period, a value and a released_on date. Keep released_on apart from period. The values of May and June 2026 were published on the same day, so the series runs behind the calendar.

Read shipping and container indicators

Two annual World Bank series cover shipping. Searching for container returns port traffic in TEU, and searching for shipping returns the liner shipping connectivity index. Replace the {country} slot in the id_template with a lower case three letter code.

curl, search the catalogue for container
curl -s "https://api.narwhalapi.com/v1/economics/catalogue?q=container&limit=2" \
  -H "Authorization: Bearer $NARWHAL_API_KEY"
Response
{
  "results": [
    {
      "id_template": "wdi:is.shp.good.tu/{country}",
      "source": "wdi",
      "title": "Container port traffic (TEU: 20 foot equivalent units)",
      "frequency": "annual",
      "unit_label": "Container port traffic (TEU: 20 foot equivalent units)"
    }
  ]
}
curl, container port traffic for Singapore
curl -s "https://api.narwhalapi.com/v1/economics/catalogue/series/observations?id=wdi:is.shp.good.tu/sgp&start=2023&end=2024" \
  -H "Authorization: Bearer $NARWHAL_API_KEY"
Response
{
  "id": "wdi:is.shp.good.tu/sgp",
  "title": "Container port traffic (TEU: 20 foot equivalent units), Singapore",
  "country": "SGP",
  "frequency": "annual",
  "unit_label": "Container port traffic (TEU: 20 foot equivalent units)",
  "attribution": "World Bank, World Development Indicators, CC BY 4.0. Values normalised by Narwhal.",
  "observations": [
    {
      "period": "2023",
      "value": "39010000"
    },
    {
      "period": "2024",
      "value": "41124100"
    }
  ]
}

Singapore handled 39010000 TEU in 2023 and 41124100 in 2024. The liner shipping connectivity series for Singapore, wdi:is.shp.gcnw.xq/sgp, has a last_period of 2021, so it ends well before the port traffic series. Check last_period for each country you use.

Put the indicators in one script

  1. Fetch the fuel prices The weekly diesel price comes from the physical series route, and Brent from the live spot route. Diesel is USD per US gallon and Brent is USD per barrel.
  2. Fetch the indexes and port traffic The helper reads the last two observations of each catalogue series and computes the change between them. It retries on a 503.
  3. Print each change with its unit and period The units differ, so the script prints the unit_label and both periods with every figure.
    Python, freight cost indicators
    import os
    import time
    import requests
    
    API = "https://api.narwhalapi.com"
    HEAD = {"Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}"}
    
    def get(path, **params):
        for _ in range(3):
            r = requests.get(API + path, params=params, headers=HEAD, timeout=15)
            if r.status_code != 503:
                break
            time.sleep(5)
        r.raise_for_status()
        return r.json()
    
    diesel = get("/v1/commodities/physical/series/fuel-eia-usa-on-highway-diesel/latest")
    print("diesel", diesel["period_start"], diesel["price"], diesel["currency"], "per", diesel["unit"])
    
    brent = get("/v1/commodities/spot/BRENT/USD")
    print("brent", brent["timestamp"], brent["price"], brent["currency"], "per", brent["unit"])
    
    def last_two(series_id, start, end):
        body = get("/v1/economics/catalogue/series/observations", id=series_id, start=start, end=end)
        a, b = body["observations"][-2:]
        change = 100 * (float(b["value"]) / float(a["value"]) - 1)
        return body["unit_label"], a, b, change
    
    indicators = [
        ("Canada truck freight price index", "statcan:v1490434186", "2026-01", "2026-06"),
        ("Canada freight rail price index", "statcan:v1138753427", "2026-06", "2026-10"),
        ("Singapore container port traffic", "wdi:is.shp.good.tu/sgp", "2023", "2024"),
    ]
    for name, series_id, start, end in indicators:
        unit, a, b, change = last_two(series_id, start, end)
        print(f"{name} ({unit}): {a['period']} {a['value']} -> {b['period']} {b['value']} ({change:+.1f}%)")
IndicatorFrequencyLatest change shown
US on-highway dieselWeekly6.352 USD per gallon, week of 2026-10-26
Brent spotLive104.9254 USD per barrel at 2026-11-03T02:34:00Z
Canada truck freight price indexMonthly133.3 to 131.9, May to June 2026, -1.1%
Canada freight rail price indexMonthly144.7 to 148.5, September to October 2026, +2.6%
Singapore container port trafficAnnual39010000 to 41124100 TEU, 2023 to 2024, +5.4%

None of these is a price per container. They show direction: fuel costs, the price carriers charge in Canada by truck and rail, and how much container traffic a port handled.

Read the indicators together

  • Diesel and Brent say what carriers pay for fuel. Diesel is weekly and Brent is a live quote.
  • The freight price indexes say what carriers charged in Canada. They arrive monthly, with a lag that differs by table, so use them to confirm a trend.
  • Port traffic and shipping connectivity describe a country's container activity by year. Use them for background on a trade lane, not for a current price.
  • Write down the unit of each figure. An index with a base year, a price per gallon and a count of TEU cannot be added or averaged together.

A dashboard can show the five lines side by side as long as each carries its own period and unit label.

Is there a container freight rate in the API?

No. There are no container freight rate quotes. Use the indicators above for context, and keep a rate from your forwarder or carrier for the price of a shipment. The container shipping calculator is a load planner for fitting goods into containers and has no rates.

Why do the series have different frequencies?

They come from different publishers. Diesel is weekly, the Statistics Canada indexes are monthly and the World Bank shipping series are annual. Do not chart them on one time axis without labelling each frequency and its last_period.

Can I use these indicators outside Canada and the US?

The two freight price indexes are for Canada and the diesel series is for the United States. The World Bank shipping series take a country code, so test the country and read last_period before you build on it. A first read of a World Bank series can return 503 with the code upstream_busy, and a retry a few seconds later worked for the series tested.

Published .

Next steps