From a credit model to a published ladder.
The bigger change is not the parameters, it is the metering. Google prices map loads per session and offsets usage against a monthly credit; we price tiles and requests, published, with no credit to model around.
- Per-request pricing you can compute before the invoice
- Tiles billed per tile — usually cheaper for long sessions
- No SKU matrix: ten services, ten rates
- EU data residency available without an enterprise agreement
The swap
Host and auth header. Everything below is the parameter map.
- https://maps.googleapis.com?key=YOUR_KEY
+ https://api.apinavi.com
+ Authorization: Bearer $APINAVI_KEYParameter map
Geocoding
| Google Maps | ApiNavi | Note |
|---|---|---|
| GET /maps/api/geocode/json?address= | GET /v1/geocode?q= | — |
| GET /maps/api/geocode/json?latlng= | GET /v1/revgeocode?at= | — |
| components=country:DE | in=countryCode:DEU | ISO alpha-3 rather than alpha-2. |
| results[].formatted_address | items[].address.label | — |
| results[].geometry.location | items[].position | lat/lng keys are the same. |
| results[].place_id | items[].id | Identifiers are not interchangeable; re-resolve saved places once. |
Routes & places
| Google Maps | ApiNavi | Note |
|---|---|---|
| POST /directions/v2:computeRoutes | GET /v1/routes | — |
| routes[].legs[].distanceMeters | routes[].sections[].summary.length | — |
| routes[].duration | routes[].sections[].summary.duration | Seconds in both, without the trailing s. |
| POST /places:autocomplete | GET /v1/autosuggest | — |
| GET /maps/api/distancematrix/json | POST /v1/matrix | — |
| Map load (per session) | Tile requests | Metering differs: we bill tiles, not map loads — usually cheaper for long sessions, dearer for one-glance views. |
Where it is not a drop-in
Map loads versus tiles
A session that pans and zooms a lot costs more here; a page with one static glance costs less. The calculator has both shapes as presets.
Coordinate order
Google returns geometry.location as an object; so do we. But our GeoJSON output is lng-first per the spec — check whichever path you take.
Place identifiers
place_id values do not transfer. Anything you have stored needs a one-off re-resolve by coordinates or address.
Street-level imagery
We have no equivalent of Street View. If your product leans on it, keep that piece where it is.
How teams usually do it
- 01
Shadow
Send a copy of production traffic to both providers for a week. No user-facing change.
- 02
Diff
Compare field by field on the endpoints you actually use. Most teams find two or three real differences, not twenty.
- 03
Split
Move 5%, then 50%, watching error rate and latency per region.
- 04
Cut
Flip the rest, keep the old key alive for a fortnight, then rotate it out.
Dual-run mode
Point a percentage of traffic at both providers and diff the responses. The console shows field-level disagreement rates per endpoint, so you cut over on evidence rather than on a spot check.
Leaving later
The same tables read in reverse, and an export endpoint returns your saved geofences, styles and batch results in open formats. A migration guide that only points inwards is a warning sign, not a feature.
Cutover checklist
- Rate limits raised on the new key before the split, not after
- Spend cap set for the first full month
- Saved place identifiers re-resolved if you store them
- Polyline decoder confirmed against a known route
- Coverage checked for the countries in the long tail of your traffic
- Old key rotated out and removed from secrets