Skip to content
Developers

Routing

Routes, turn-by-turn directions, distance matrices, the best order for stops, reachable areas and road closures.

Base URLhttps://makani-vol.lamah.com

Before you start

Routing needs a plan that includes it and a key with a routing scope: routing:route for everything except the matrix (routing:matrix) and road closures (routing:read).

  • Points are { latitude, longitude }.
  • countryCode is required on every routing request. It applies the country's road closures, is checked against the countries your key and your plan allow, and is recorded on usage. A request without it answers 400 VALIDATION_FAILED.
  • costing is the way of travel: auto by default, or bicycle, bus, motor_scooter, motorcycle, pedestrian, taxi or truck.
  • language (ar, en) is the language of directions and of road closure names.

Route

A road route between two points, through up to 20 stops in via. The answer has distanceMeters, durationSeconds and shape, a polyline at six decimal places. closures.avoided lists the road closures the route went around.

POST/v1/routing/routeScoperouting:route
curl -X POST "https://makani-vol.lamah.com/v1/routing/route" \  -H "x-api-key: $MAKANI_API_KEY" \  -H "content-type: application/json" \  -d '{    "countryCode": "QA",    "from": {      "latitude": 25.2854,      "longitude": 51.531    },    "to": {      "latitude": 25.3548,      "longitude": 51.4816    }  }'

Turn-by-turn directions

The same route with every maneuver, banner text and voice instruction, in the OSRM route format that navigation libraries read. Send heading (degrees) on a reroute so the route keeps to the side of the road the vehicle is on.

In Flutter, the navigation package asks for directions itself and guides on the device: snapping, step advance, rerouting, voice and the camera.

POST/v1/routing/directionsScoperouting:route
curl -X POST "https://makani-vol.lamah.com/v1/routing/directions" \  -H "x-api-key: $MAKANI_API_KEY" \  -H "content-type: application/json" \  -d '{    "countryCode": "QA",    "from": {      "latitude": 25.2854,      "longitude": 51.531    },    "to": {      "latitude": 25.3548,      "longitude": 51.4816    },    "language": "en"  }'

Distance matrix

Distances and durations from every source to every target, up to 2,500 pairs in one request. A pair with no route does not fail the request: its cell has distanceMeters: null, durationSeconds: null and a reason. Each cell carries distanceMeters and durationSeconds, the units a route answers in; distance (kilometers) and time are still sent and are deprecated.

answeredCells is what the request is billed: one unit per answered pair.

POST/v1/routing/matrixScoperouting:matrix
curl -X POST "https://makani-vol.lamah.com/v1/routing/matrix" \  -H "x-api-key: $MAKANI_API_KEY" \  -H "content-type: application/json" \  -d '{    "countryCode": "QA",    "sources": [      {        "latitude": 25.2854,        "longitude": 51.531      }    ],    "targets": [      {        "latitude": 25.3548,        "longitude": 51.4816      },      {        "latitude": 25.3212,        "longitude": 51.5301      }    ]  }'

Best stop order

Puts 2 to 25 stops in the order that takes the least time and returns the route through them. order holds indexes into your stops, in visiting order, and legs has one entry per hop. Without to the trip returns to from; for a one-way trip send the last stop as to.

Each stop is one unit.

POST/v1/routing/optimizeScoperouting:route
curl -X POST "https://makani-vol.lamah.com/v1/routing/optimize" \  -H "x-api-key: $MAKANI_API_KEY" \  -H "content-type: application/json" \  -d '{    "countryCode": "QA",    "from": {      "latitude": 25.2854,      "longitude": 51.531    },    "stops": [      {        "latitude": 25.3212,        "longitude": 51.5301      },      {        "latitude": 25.2632,        "longitude": 51.5561      },      {        "latitude": 25.2919,        "longitude": 51.4963      }    ]  }'

Reachable area

The area that can be reached from origin within each contour, as GeoJSON. Send one to four contours, each { minutes } (60 at most) or { kilometers } (50 at most). The answer has one feature per contour, in request order, with coordinates longitude first.

Each contour is one unit.

POST/v1/routing/isochroneScoperouting:route
curl -X POST "https://makani-vol.lamah.com/v1/routing/isochrone" \  -H "x-api-key: $MAKANI_API_KEY" \  -H "content-type: application/json" \  -d '{    "countryCode": "QA",    "origin": {      "latitude": 25.2854,      "longitude": 51.531    },    "contours": [      {        "minutes": 10      },      {        "kilometers": 5      }    ]  }'

Road closures

When a road is closed, routes go around it from the second the closure starts. To draw the closed roads on your own map, read them as GeoJSON lines. This endpoint is never charged. status is active (default) or scheduled, bbox is minLongitude,minLatitude,maxLongitude,maxLatitude, and at answers for another moment.

GET/v1/routing/closuresScoperouting:read
curl "https://makani-vol.lamah.com/v1/routing/closures?countryCode=QA&bbox=51.4%2C25.2%2C51.6%2C25.4&language=en" \  -H "x-api-key: $MAKANI_API_KEY"

When a closure leaves no way through, a route request is refused with one of two errors. details.closures names the closures, and details.messages has the message in Arabic and English:

  • 422ROUTE_BLOCKED_BY_CLOSURENo route avoids the road closures in the way.
  • 422ROUTE_ENDPOINT_ON_CLOSED_ROADThe origin, the destination or a stop is itself on a closed road. details.endpoint says which.

Snap a recorded trace to the road

Send 2 to 2,000 recorded GPS points in order and get the road they followed as shape.

POST/v1/routing/traceScoperouting:route
curl -X POST "https://makani-vol.lamah.com/v1/routing/trace" \  -H "x-api-key: $MAKANI_API_KEY" \  -H "content-type: application/json" \  -d '{    "countryCode": "QA",    "points": [      {        "latitude": 25.2854,        "longitude": 51.531      },      {        "latitude": 25.2861,        "longitude": 51.5296      }    ]  }'

When there is no answer

When routing is unavailable, a request fails with 503 ROUTING_UNAVAILABLE and a Retry-After header; it is never charged. For a route or a matrix you can send allowEstimate: true to get a straight-line estimate instead: it is marked estimateDegraded: true, has no shape, and is not charged.

  • 400VALIDATION_FAILEDA parameter is missing or invalid. details.errors lists each failing field with its messages, and message joins them.
  • 400COUNTRY_CODE_CONFLICTThe path, the query and the body name different countries. Send one countryCode.
  • 403API_KEY_COUNTRY_DENIEDThe key is not enabled for this country, whether the request names it in the path, the query or the body.
  • 422ROUTE_NOT_FOUNDThere is no road route between the points.
  • 422TRACE_NOT_MATCHEDThe recorded points do not follow any road.
  • 400MATRIX_SIZE_INVALIDThe matrix has no pair, or more than 2,500.
  • 400OPTIMIZE_STOPS_INVALIDFewer than 2 stops, or more than 25.
  • 400ISOCHRONE_CONTOURS_INVALIDNot one to four contours, or a contour without exactly one of minutes and kilometers.
  • 503ROUTING_UNAVAILABLERouting cannot answer now. Wait Retry-After seconds. Never charged.