Migrating from Google Maps: what changes and what does not
Google made the Directions, Distance Matrix and Places APIs legacy on 1 March 2025: frozen feature sets, no new Cloud projects allowed to enable them, and volume discounts capped at the 100,000-call tier. Anyone rebuilding on the Routes API that replaced them will also find it has no truck mode at all. This post maps our endpoints against Google's honestly, including where we are weaker, and every fact below is dated 26 July 2026. Google's terms change; check the current wording yourself before you rely on any of this.
Why teams are looking at this migration now
Legacy status is not the same as switched off. The old Directions, Distance Matrix and Places APIs keep answering calls for projects that already had them enabled, but they get no new features, no architectural improvements, and their volume discount tops out at the 100,000+ tier that the newer Routes API and Places API (New) both exceed. New Cloud projects cannot enable the legacy APIs at all. If you are starting a project today you are pushed onto Routes API and Places API (New) whether you planned to move or not, and that is the point at which the gaps below start to matter.
The Routes API has no truck mode
Google's Routes API defines exactly five travel modes: DRIVE, BICYCLE, WALK, TWO_WHEELER and TRANSIT. There is no TRUCK, no dimensional routing, and no dangerous-goods costing. WALK, BICYCLE and TWO_WHEELER are still beta. If your product routes lorries, that half of the API surface does not exist for you.
The routeModifiers avoidance flags do not exclude either. avoidTolls, avoidHighways and avoidFerries each read "avoids ... where reasonable, giving preference to routes not containing ..." in Google's own reference. They bias the route away from tolls, highways or ferries; they do not guarantee the route has none. A driver who cannot legally use a toll road, or a 44-tonne artic that cannot use a height-restricted bridge, needs a hard constraint, not a preference.
MapMap's truck profile takes the opposite approach: declared vehicle dimensions and an ADR hazmat/tunnel-code profile are enforced in costing, not applied as a bias afterwards. POST /route with costing: "truck" and an adr block, or GET /route/v1/truck/{coordinates} with height, width, length, weight, hazmat and tunnel_code query params, both refuse edges the vehicle cannot legally use. Full reference: truck and ADR routing.
Endpoint mapping
| Google Maps Platform | MapMap | Notes |
|---|---|---|
Routes API computeRoutes, or the legacy Directions API | GET /route/v1/{profile}/{coordinates} or POST /route | Profiles: driving, truck, bus, bicycle, walking, scooter, motorcycle. Response is OSRM-shaped, not Google-shaped |
Routes API computeRouteMatrix, or the legacy Distance Matrix API | POST /matrix | One JSON response, durations in seconds and distances in metres, null for unreachable pairs. No element-by-element streaming |
| Places API / Places API (New) | GET /geocode, GET /geocode/reverse | Resolves names and addresses from OpenStreetMap. Not a places-richness product; see the gap list below |
| Directions API waypoint optimisation, or Google's separate route-planning product for multi-stop fleets | POST /optimise (alias /optimize) | Multi-vehicle VRP; truck and ADR constraints shape the plan |
Maps JavaScript API (google.maps.Map) | MapLibre GL via @mapmap/maps, or a style.json URL directly | Vector tiles you render, not a hosted renderer |
Coordinate order is the first bug you will hit
Google is lat,lng everywhere: {lat, lng} objects, origin=lat,lng query strings. MapMap follows the OSRM and GeoJSON convention, lon,lat, in URLs, location arrays and geocoding results (POST /route request bodies use named {lat, lon} keys, which is the one place we keep named fields rather than an ordered pair). Audit every coordinate pair you pass across the boundary; this is the single most common first bug in a Google port and it fails silently, plotting a real point in the wrong country rather than throwing an error.
The response shapes do not match, so budget for an adapter
Google's Routes API returns routes[].legs[].steps[] with duration strings like "1234s", polyline.encodedPolyline, and HTML-formatted instructions; the legacy Directions API returns {text, value} pairs and overview_polyline. Neither looks like the other, and neither looks like ours. MapMap's compatible endpoint answers in the OSRM envelope: routes[].distance in metres and duration in seconds as plain numbers, geometry as an encoded polyline (geometries=geojson for GeoJSON, polyline6 for six-digit precision; five-digit is the default), and legs/steps in OSRM's structure. If you already run an OSRM client library, pointing it at our endpoint is usually less work than adapting your existing Google parser.
What you can do with a response once you have it
This is where the two platforms differ most, and it rarely gets a line in a migration guide. Google's terms cap how long you may cache what their API gives you: latitude/longitude values from geocoding may be cached for up to 30 consecutive calendar days and must then be deleted, place IDs may be kept indefinitely, and bulk download, scraping, pre-fetching and indexing of Google Maps content are all prohibited outright. Google's terms also prohibit using Google Maps content to train, test, validate or fine-tune a machine learning or AI model.
MapMap's agent data rights manifest commits to the opposite for responses we have already sent you: no caching time limit, no storage ban, no indexing ban and no training ban, ever, for calls already delivered under a given version of that manifest. The one boundary that does not move is upstream: content derived from OpenStreetMap stays under ODbL, which is OpenStreetMap's licence, not ours to waive, so public redistribution still needs attribution.
What does not port: no substitute exists
Do not promise parity here; there is nothing to point at.
- Places richness. Reviews, ratings, photos, opening hours and place details are a Google Places product. Our geocoding resolves names and addresses from OpenStreetMap; it is not a business-data product.
- Street View. Nothing comparable.
- Traffic-aware routing. Google's traffic-aware travel modes use live probe data. MapMap routes on the road network without live traffic.
- Global coverage on the hosted gateway. Google is worldwide by default. Our hosted coverage is territory-based (
GET /territorieslists what is live); self-hosting covers anywhere you build a territory for.
If your product leans on any of these, keep that piece on Google and migrate the rest. The two platforms coexist fine side by side.
Map rendering: google.maps.Map to MapLibre
- const map = new google.maps.Map(document.getElementById("map"), {
- center: { lat: 52.6, lng: -1.5 },
- zoom: 6,
- });
- new google.maps.marker.AdvancedMarkerElement({ map, position: { lat: 51.5, lng: -0.13 } });
+ import maplibregl from "maplibre-gl";
+ const map = new maplibregl.Map({
+ container: "map",
+ style: "https://api.mapmap.ai/tiles/uk/style.json?api_key=snk_…",
+ center: [-1.5, 52.6], // lon, lat
+ zoom: 6,
+ });
+ new maplibregl.Marker().setLngLat([-0.13, 51.5]).addTo(map);
The container needs an explicit CSS height, same as Google's renderer required. google.maps.InfoWindow becomes maplibregl.Popup. Google's cloud-based map styling becomes a MapMap theme (seventeen palette slots plus per-layer overrides), built in Studio or through the MCP style tools. Attribution changes shape too: Google's logo and terms requirements go away, and "© OpenStreetMap contributors" (linked to openstreetmap.org/copyright) takes their place on anything you render or republish; compiled MapMap styles carry it structurally.
What it costs
A Google API key needs a Cloud project, a billing account with a card on file, and per-API enablement. A MapMap snk_ key is one call, card-free:
curl -fsS -X POST "https://api.mapmap.ai/v1/keys" \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "accept_tos": true}'
That key covers every endpoint; there is no per-API enablement to repeat. Standard calls (car, bicycle, pedestrian routing, matrix, isochrone, map matching, geocoding, tiles) start at 0.05p; truck and ADR calls start at 1p and draw 20 included calls from the free tier. Fifty thousand calls a month are free once the key's email is verified, commercial use included, and everything runs on prepaid credit rather than a card on file: no credit means a 402 or 429, never a surprise invoice. Machine-readable pricing: /pricing.json.
Try it
Full endpoint reference: API reference (append .md for the raw file an agent can read directly). Coordinate order, units and the error model: conventions. If you use a coding agent to do the port, the mapmap-migrate-from-google-maps skill in mapmap-agent-skills carries this same mapping as machine-readable knowledge it can act on directly.
