Move from Google
Keep the code that calls Google's Geocoding, Directions and Distance Matrix: change the base URL and the key. What each call becomes here, what differs, and what a month costs at both.
Base URLhttps://makani-vol.lamah.com
Change the URL and the key
Three Google web services have a compatible endpoint here: Geocoding (with reverse geocoding), Directions and Distance Matrix. Each takes Google's query parameters and answers in Google's JSON shape with Google's statuses, so the code that builds the request and reads the answer stays as it is.
Replace https://maps.googleapis.com/maps/api with this platform's base URL and the prefix of the service, and Google's key with a key from the console. The end of the path, such as geocode/json, is Google's.
- The key. Send it in the
x-api-keyheader.key=in the URL is accepted too, as Google's clients send it, but a key in a URL can end up in the logs of whatever the request passes through. The header is used when both are sent. - The country. Every request is for one country. Send its two-letter code as
region, or use a key limited to one country and send nothing. A request without a country answersINVALID_REQUEST. - The same rules as the platform's own endpoints. Key scopes, countries, the plan, requests a minute, quotas, caps and road closures apply as they do there, and a request is counted the same way.
Each call and its equivalent
The compatible endpoint is the quick move. The platform's own endpoint is the one to write new code against: it has more options, and its answers are smaller.
| Service | At Google | Compatible endpoint | The platform's own | Scope |
|---|---|---|---|---|
| Distance Matrix | GET /maps/api/distancematrix/json | GET /v1/routing/compat/google/distancematrix/json?origins=…&destinations=… | POST /v1/routing/matrix | routing:matrix |
| Directions | GET /maps/api/directions/json | GET /v1/routing/compat/google/directions/json?origin=…&destination=… | POST /v1/routing/directions | routing:route |
| Geocoding | GET /maps/api/geocode/json?address= | GET /v1/addresses/compat/google/geocode/json?address=… | GET /v1/addresses/search | addresses:search |
| Reverse geocoding | GET /maps/api/geocode/json?latlng= | GET /v1/addresses/compat/google/geocode/json?latlng=… | GET /v1/addresses/resolve | addresses:resolve |
Scopes are set on the key. The geocoding path asks addresses:search for an address and addresses:resolve for a latlng; one key can carry both.
Distance Matrix
origins and destinations are lat,lng points separated by |, up to 25 each and 100 pairs in a request. The code that reads rows[0].elements[0].distance.value stays as it is:
routing:matrixcurl "https://makani-vol.lamah.com/v1/routing/compat/google/distancematrix/json?origins=32.86,13.23&destinations=32.8872,13.1913&mode=driving&units=metric®ion=ly" \ -H "x-api-key: $MAKANI_API_KEY"Each answered pair is one unit of the routing matrix. What differs from Google, and how to ask less often, is in the Delivery fee quotes guide.
Directions
The answer has routes[0].legs[], one leg for each hop, each with distance, duration and steps[], and overview_polyline.points for the whole line. Every encoded line has five decimal places, as Google's, so your decoder stays as it is:
routing:routecurl "https://makani-vol.lamah.com/v1/routing/compat/google/directions/json?origin=32.8872,13.1913&destination=32.86,13.23®ion=ly" \ -H "x-api-key: $MAKANI_API_KEY"A request is one routing request, whatever the number of waypoints. What differs from Google:
- Coordinates only.
origin,destinationandwaypointsarelat,lng. Addresses, place ids and thevia:andenc:forms answerINVALID_REQUEST.start_addressandend_addressrepeat what you sent, andgeocoded_waypointscarries no place id. - Waypoints. Up to 20, visited in the order sent; more answers
MAX_WAYPOINTS_EXCEEDED.optimize:trueanswersINVALID_REQUEST:POST /v1/routing/optimizeorders stops. - One route.
alternativesis accepted and ignored:routesholds one route or none. - Travel modes.
driving(the default),walkingandbicycling.transit,arrival_time,transit_modeandtransit_routing_preferenceanswerINVALID_REQUEST. - No live traffic.
departure_time,traffic_modelandavoidare accepted and ignored.durationis the usual travel time, andduration_in_trafficis never returned. - Instructions.
html_instructionsis plain text in the request'slanguage, without<b>markup.maneuveris present where Google has a name for the turn. - Road closures. The route goes around the closures in effect. When no route can, the status is
ZERO_RESULTSanderror_messagesays why.
Geocoding and reverse geocoding
One path serves both, as at Google: address= searches the address registry, and latlng= returns the addresses nearest a point, within 1,000 meters. Each result has formatted_address, geometry.location, address_components, types and a place_id:
addresses:searchcurl "https://makani-vol.lamah.com/v1/addresses/compat/google/geocode/json?address=Street%20984&components=country:QA&language=en" \ -H "x-api-key: $MAKANI_API_KEY"A request is one address request. What differs from Google:
- The registry, not a map of the world. Results are addresses of this platform's registry in the country you name. A business or a landmark name finds nothing unless it is part of an address.
- The country.
components=country:LYandregion=lyboth name it. Any othercomponentsfilter answersINVALID_REQUEST. - Up to five addresses. A reverse lookup then lists the areas that contain the point, innermost first, so a point with no address near it still has a label. For such a result
geometry.locationis the point you sent andlocation_typeisAPPROXIMATE. - Address components hold the areas around the address and the country. Street, building and postal code are not split out: read them from
formatted_address. - The place id is this platform's id of the address, read with
GET /v1/addresses/{addressId}. It is not a Google place id, andplace_id=as a request parameter answersINVALID_REQUEST. - Ignored.
bounds,result_type,location_typeandextra_computations.plus_codeandpartial_matchare never returned. - Nothing found is
ZERO_RESULTS, and is counted like an empty search.
Statuses
Every refusal is HTTP 200 with a status other than OK, as Google answers, and error_message starts with this platform's error code. A refused request is not counted.
INVALID_REQUEST: a missing or unsupported parameter, or no country.REQUEST_DENIED: no key, a wrong key, a missing scope, or a country or a capability the key or the plan does not include.OVER_QUERY_LIMIT: the plan's requests a minute.OVER_DAILY_LIMIT: a daily cap, a quota, the plan's units, a budget or the balance.ZERO_RESULTS: no address matches, or there is no road route.NOT_FOUND: the country has no address registry yet.MAX_WAYPOINTS_EXCEEDED,MAX_DIMENSIONS_EXCEEDEDandMAX_ELEMENTS_EXCEEDED: too many points.UNKNOWN_ERRORwith HTTP 503 and aRetry-Afterheader: the service cannot answer now. Retry after that many seconds.
What has no equivalent
Some Google products are not replaced by a change of URL. Keep them at Google, or change the code:
- Places (place details, search by business name) is not available. Address search and address autocomplete find addresses, not businesses.
- Routes API (
computeRoutes,computeRouteMatrix) has no compatible endpoint: its client libraries are tied to Google's address. Replace the call withPOST /v1/routing/routeorPOST /v1/routing/matrix; the Delivery fee quotes guide shows how. - Maps SDKs and map tiles: the map component is replaced in the application.
- Transit, live traffic, avoiding tolls or ferries, and alternative routes are not served.
What a month costs
Type the requests of one month for each service. Google's side uses its published prices. This platform's side is read live from the price list and the plans, and shows the plan on which the month costs least:
Requests a month, reverse included
Requests a month
Elements a month: origins times destinations
At Google
- Geocoding
- USD 0.00
- Directions
- USD 0.00
- Distance Matrix
- USD 0.00
- Total a month
- USD 0.00
Here
Loading prices…
Google's prices as published on Oct 7, 2026.Google Maps Platform pricing
How the two are counted:
- At Google each service has its own free units a month, then a price per 1,000 that falls with volume. A Distance Matrix request counts one element for each pair of origin and destination.
- Here a plan includes a number of units for all services together. A request uses the number of units the price list gives its product, and what goes beyond the plan is charged per 1,000. The figure assumes an even mix of requests through the month.
- The case study button fills in one month of a real delivery application, anonymised: 50 to 100 orders a day, with Google as its only location provider. Its bill was Distance Matrix and nothing else, and it came from how often the application asked more than from the price: quoting only in the cart would have kept it inside Google's free units. The Delivery fee quotes guide shows how.
- A lower figure is not the only reason to move. A fixed plan price, a bill in your own currency, road closures and no card abroad are others. Compare with your own numbers.