Move off the Google Geocoding API

A local server that answers in Google's format. Your code keeps its requests and its parsing; only the base URL changes, and no address leaves your machine.

New Leave a paid API Server, Docker Python JavaScript

The change in your code

terminalCLI
$ gridpin serve usa.bin --port 8080
$ curl "http://127.0.0.1:8080/maps/api/geocode/json?address=1600+Pennsylvania+Ave+NW,+Washington,+DC"
$ curl "http://127.0.0.1:8080/maps/api/geocode/json?latlng=38.8977,-77.0365"
geocode.pyPython
import requests

# before: BASE = "https://maps.googleapis.com"
BASE = "http://127.0.0.1:8080"

r = requests.get(f"{BASE}/maps/api/geocode/json",
                 params={"address": "1600 Pennsylvania Ave NW, Washington, DC", "key": "not-needed"})
top = r.json()["results"][0]
top["geometry"]["location"]        # {'lat': 38.8976751, 'lng': -77.036547}
top["geometry"]["location_type"]   # 'ROOFTOP'
geocode.jsNode
// before: const BASE = 'https://maps.googleapis.com';
const BASE = 'http://127.0.0.1:8080';

const q = new URLSearchParams({ address: '1600 Pennsylvania Ave NW, Washington, DC' });
const { status, results } = await (await fetch(`${BASE}/maps/api/geocode/json?${q}`)).json();
if (status === 'OK') console.log(results[0].geometry.location);
clients.pygeopy, googlemaps
from geopy.geocoders import GoogleV3
GoogleV3(api_key="not-needed", domain="127.0.0.1:8080", scheme="http").geocode("1600 Pennsylvania Ave NW, Washington, DC")

import googlemaps
googlemaps.Client(key="AIzaNotNeeded", base_url="http://127.0.0.1:8080").geocode("1600 Pennsylvania Ave NW, Washington, DC")

Checked on November 7, 2026 with geopy 2.5.0 and googlemaps 4.10.0 against the United States file. A key, language and region are accepted and have no effect.

Which field means what

Google fieldHere
statusOK, ZERO_RESULTS, and INVALID_REQUEST with HTTP 400
geometry.locationthe answer's point
geometry.location_typeROOFTOP a stored point of the house; RANGE_INTERPOLATED between two houses; GEOMETRIC_CENTER the street; APPROXIMATE the neighbour's point, a postcode or a town
partial_matchtrue when the engine itself says check it (weak) or it answered with a neighbour
address_componentsstreet_number, route, locality, administrative_area_level_1 where the file knows it, country as a code, postal_code
place_idour own, stable within one file release; not usable with Google
geometry.viewporta box by precision, for framing a map
componentsroute, locality, administrative_area, postal_code narrow the query; country of another file gives ZERO_RESULTS

What the same traffic costs

Queries a monthGoogle Geocoding APIGridPin, per query
10,000$0$0
100,000$450$0
500,000$2,050$0
1,000,000$3,550$0
5,000,000$9,550$0
10,000,000$11,450$0

Google's list prices for the Geocoding API, read November 7, 2026 (Google's page dated November 3, 2026): 10,000 free calls a month, then $5.00 per 1,000 up to 100,000, $4.00 to 500,000, $3.00 to 1,000,000, $1.50 to 5,000,000 and $0.38 beyond. Your machine is not free; the file is. See how to cut the bill.

What does not carry over

  • One country per process, and only the countries of the release: run one server per country.
  • Addresses only: no shops or landmarks by name, no autocomplete, no Places.
  • Quality differs by country: see the measured tables before you switch.
  • No bounds, postcode_localities or XML output; plus_code needs with=codes (new in 0.9.0).
  • GridPin is not affiliated with Google; the format is followed so that existing code keeps working.

The server itself: gridpin serve.