Skip to content
Navo24 Navo24
GETAPI key

River route

GETapi.navo24.com/v1/distance/route

Barge route over inland waterways with mode=RIVER, plus road to and from the river port when the points are off the water. The example is Rotterdam to Basel up the Rhine on 2026-10-17: 825.8 km, 17 locks, almost all upstream, with the Rhine low water note for October. A road chain comes back as the alternative.

Query parameters

fromstringrequired

Any form from the Locations table. UN/LOCODEs of river ports resolve to the river port.

tostringrequired

Any form from the Locations table.

modestringrequired

RIVER (or INLAND, INLAND_WATERWAY, IWW, BARGE). Road is added for the access legs.

alternativesboolean

Other feasible chains in alternatives[]. Default true for ROAD, RAIL, AIR and /multimodal.

handlingboolean

Add terminal handling at each transfer: port 24 h, rail terminal 12 h, airport 12 h, river port 18 h. Default true.

pathboolean

Geometry per section as [lat, lng] pairs. Road sections also give ferry_paths as lines.

datestring

Departure date YYYY-MM-DD for the seasonal river rules. Default today (UTC). Only river legs depend on it.

seasonalboolean

false switches the seasonal river rules off: no closures, no slow-downs, no seasonal_notes. Default true.

Response schema

19 fields

Nested exactly as the JSON is. Open a branch to read its fields; hover a name for the full dot-path.

dataobject
from / dataobject
toobject

The resolved points: kind (port, airport, country, address, coordinates), name, locode or iata, country_code, lat, lng.

transport_modes[]array

The modes you allowed.

routeobject
labelstring

Chain type: Sea, Rail, Air, Road, River (road, barge, road) or Sea + River (sea to a river-mouth gateway, then barge).

transport_modes[]array

The modes the chain actually uses, in order.

summaryobject
distanceobject

Total km and nm for the chain.

durationobject

Total hours and days. duration.hours = moving_hours + handling_hours.

cost_indexnumber

Relative cost in thousands of km-equivalents at SEA 1, RIVER 1.8, RAIL 3, ROAD 6, AIR 40 per km. For ranking, not a price.

sections[]array

Legs in order: transport_mode, from, to, distance, duration, path. SEA legs add speed_knots, via, eca and passages. ROAD legs add driving_hours and ferry_paths. RIVER legs add the fields below.

speed_kmhnumber

RIVER: average speed over ground for this leg, current and locks included.

currentobject

RIVER: km sailed with the current (downstream_km), against it (upstream_km) and on still water such as canals, lakes and tidal reaches (slack_water_km).

locksinteger

RIVER: lock sites passed. lock_hours is the time they add, already inside duration.

waterways[]array

RIVER: named waterways on the leg, longest first, as name, km and class (CEMT class in Europe).

seasonal[]array

RIVER: seasonal rules that touch this leg on the requested date, with the km affected.

attributionstring

RIVER: credit line for the waterway data this leg was built from. Show it wherever you display the leg.

transfers[]array

Each change of mode: at (port, rail terminal or airport), from_mode, to_mode, hours.

estimatedboolean

true when a road leg was estimated from straight-line distance because road routing was briefly unavailable.

alternatives[]array

Other feasible chains, same shape, in the order set by optimize.

datestring

Present when RIVER is allowed: the date the seasonal rules were applied for.

seasonal_notes[]array

Seasonal river rules that changed the answer: id, kind (closure, ice_risk, low_water), note, typical_window, source, then time_factor for a slow-down or reopens_about for a closure, and effect: no_route (the river chain is gone), detour (it goes round the closed stretch) or slower.

Errors

A failure answers with an HTTP error status and { "error": { "code", "message" } }. Branch on the code, and log the message.

invalid_request400

A parameter is missing or malformed: an unknown mode, speed_knots outside 3 to 40, an unknown passage in avoid, a pol/pod that is not a sea port, or a date that is not YYYY-MM-DD.

location_not_found404

The location is well formed but we cannot place it: an unknown code, or an address the geocoder does not find.

no_route422

No route joins the two points with the modes and passages you allowed, for example SEA only between two inland cities. When a seasonal river closure is the cause, the message names each closure, its typical window and the date it usually reopens.

geocoder_unavailable503

Free-text address lookup is briefly down. Codes and coordinates keep working.

How river time is counted

PartRule
Speed through water12.5 km/h on rivers, 10 km/h on canals.
CurrentSigned per stretch: EURIS up and down speeds in Europe, elsewhere HydroRIVERS flow direction with a strength of 1 to 5 km/h by discharge, 35 % of that on dammed cascades, zero on canals, lakes and tidal reaches.
Operating factorMoving time ×1.1. Speed over ground never below 3 km/h.
Locks2,746 lock sites on the graph. 0.75 h each, 1.25 h in North America (USACE LPMS).
DirectionThe path is chosen on direction-neutral time; the hours reported are for your direction. Rotterdam to Basel is about 112 h upstream, Basel to Rotterdam about 76 h.
Handling18 h at each river port where the cargo changes mode (handling=false removes it).

Sources and licences

The waterway graph is built from these datasets and refreshed at night from OpenStreetMap, with a check and rollback. Each RIVER section carries its own attribution line, and /health lists them under river.sources. Show the attribution when you display river legs.

DatasetLicence and attribution line
Europe: EURIS Inland Fairway Graph v0.2.1 (Zenodo 10.5281/zenodo.18313951)CC BY 4.0. Fairway data: EURIS / European RIS authorities, graph by the EURIS fairway graph authors (CC BY 4.0)
USA: USACE / BTS NTAD National Waterway NetworkUS public domain. U.S. Army Corps of Engineers, Bureau of Transportation Statistics NTAD
Rest of world and locks: OpenStreetMap via OverpassODbL 1.0. (c) OpenStreetMap contributors, https://www.openstreetmap.org/copyright
Rest of world: HydroRIVERS v1.0, WWF HydroSHEDSFree incl. commercial use, with attribution. HydroRIVERS, WWF HydroSHEDS, www.hydrosheds.org
Rest of world: Natural Earth 10m riversPublic domain. Made with Natural Earth
curl 'https://api.navo24.com/v1/distance/route?from=NLRTM&to=CHBSL&mode=RIVER&date=2026-10-17' \
  -H "Authorization: Bearer tmcp_YOUR_API_KEY"
Response
{
  "data": {
    "from": {
      "kind": "port",
      "locode": "NLRTM",
      "name": "Rotterdam",
      "country": "Netherlands",
      "country_code": "NL",
      "lat": 51.90438,
      "lng": 4.44245
    },
    "to": {
      "kind": "river_port",
      "locode": "CHBSL",
      "name": "Basel (Rheinhafen)",
      "country_code": "CH",
      "lat": 47.59,
      "lng": 7.59
    },
    "transport_modes": [
      "RIVER",
      "ROAD"
    ],
    "optimize": "cost",
    "routing_mode": "short",
    "avoided": [],
    "route": {
      "label": "River",
      "transport_modes": [
        "RIVER"
      ],
      "summary": {
        "distance": {
          "km": 825.8,
          "nm": 445.9,
          "meters": 825800
        },
        "duration": {
          "hours": 111.6,
          "days": 4.65,
          "seconds": 401760
        },
        "moving_hours": 111.6,
        "handling_hours": 0,
        "speed_kmh": 7.4,
        "cost_index": 1.49
      },
      "sections": [
        {
          "transport_mode": "RIVER",
          "distance": {
            "km": 825.8,
            "nm": 445.9,
            "meters": 825764
          },
          "duration": {
            "hours": 111.6,
            "days": 4.65,
            "seconds": 401721
          },
          "speed_kmh": 7.4,
          "current": {
            "downstream_km": 1.3,
            "upstream_km": 783.5,
            "slack_water_km": 41.0
          },
          "locks": 17,
          "lock_hours": 12.8,
          "waterways": [
            {
              "name": "Rhein",
              "km": 503.0,
              "class": "CEMT VIc"
            },
            {
              "name": "Rhin",
              "km": 181.1,
              "class": "CEMT VIa"
            },
            {
              "name": "Boven-Rijn, Waal, Boven-Merwede, Beneden-Merwede en Noord",
              "km": 125.3,
              "class": "CEMT VIc"
            },
            {
              "name": "Nieuwe Maas, Nieuwe Waterweg en Maasmond",
              "km": 13.5,
              "class": "CEMT VIc"
            },
            {
              "name": "Koningshaven",
              "km": 1.9,
              "class": "CEMT VIc"
            },
            {
              "name": "IJsselhaven",
              "km": 0.7,
              "class": "CEMT Va"
            }
          ],
          "data_sources": [
            "euris",
            "link",
            "osm_locks"
          ],
          "attribution": "Fairway data: EURIS / European RIS authorities, graph by the EURIS fairway graph authors (CC BY 4.0); Locks (c) OpenStreetMap contributors, https://www.openstreetmap.org/copyright",
          "estimated": false,
          "seasonal": [
            {
              "id": "rhine_low",
              "kind": "low_water",
              "note": "Rhine low water season (Kaub gauge): part loads and low water surcharges",
              "typical_window": "01 Aug - 31 Oct",
              "source": "estimate: ELWIS / Kaub gauge, low water most years Aug - Oct (2018, 2022 severe)",
              "time_factor": 1.15,
              "km": 809.4
            }
          ],
          "from": {
            "kind": "port",
            "name": "Rotterdam",
            "country_code": "NL",
            "lat": 51.904383,
            "lng": 4.442447,
            "locode": "NLRTM"
          },
          "to": {
            "kind": "river_port",
            "name": "Basel (Rheinhafen)",
            "country_code": "CH",
            "lat": 47.59,
            "lng": 7.59,
            "locode": "CHBSL"
          }
        }
      ],
      "transfers": [],
      "estimated": false
    },
    "alternatives": [
      {
        "label": "Road",
        "transport_modes": [
          "ROAD"
        ],
        "summary": {
          "distance": {
            "km": 752.2,
            "nm": 406.2,
            "meters": 752200
          },
          "duration": {
            "hours": 7.8,
            "days": 0.33,
            "seconds": 28080
          },
          "moving_hours": 7.8,
          "handling_hours": 0,
          "speed_kmh": 96.44,
          "cost_index": 4.51
        },
        "sections": [
          {
            "transport_mode": "ROAD",
            "distance": {
              "km": 752.2,
              "nm": 406.1,
              "meters": 752181
            },
            "duration": {
              "hours": 7.8,
              "days": 0.32,
              "seconds": 28032
            },
            "driving_hours": 7.8,
            "estimated": false,
            "from": {
              "name": "Rotterdam",
              "locode": "NLRTM",
              "country_code": "NL",
              "lat": 51.90438,
              "lng": 4.44245,
              "kind": "port"
            },
            "to": {
              "name": "Basel (Rheinhafen)",
              "locode": "CHBSL",
              "country_code": "CH",
              "lat": 47.59,
              "lng": 7.59,
              "kind": "river_port"
            }
          }
        ],
        "transfers": [],
        "estimated": false
      }
    ],
    "date": "2026-10-17",
    "seasonal_notes": [
      {
        "id": "rhine_low",
        "kind": "low_water",
        "note": "Rhine low water season (Kaub gauge): part loads and low water surcharges",
        "typical_window": "01 Aug - 31 Oct",
        "source": "estimate: ELWIS / Kaub gauge, low water most years Aug - Oct (2018, 2022 severe)",
        "time_factor": 1.15,
        "effect": "slower"
      }
    ]
  },
  "meta": {
    "took_ms": 9
  }
}