Guide · Python

Geocode addresses in Python

Geocode one address or a whole list in Python with requests, keep the accuracy type, and append Census or district fields in the same call.

One address

import requests

KEY = "YOUR_KEY"
r = requests.get("https://api.geocode.net/v1/geocode",
                 params={"q": "1600 Pennsylvania Ave NW, Washington, DC", "fields": "census,cd"},
                 headers={"X-API-Key": KEY})
r.raise_for_status()
best = r.json()["results"][0]
print(best["location"], best["accuracy_type"])
# {'lat': 38.897675, 'lng': -77.036545} rooftop

Every result carries accuracy_type. Treat rooftop and range_interpolation as usable for mapping and routing; treat place, zip, county and state as "we only know the area" and handle them separately.

A list of addresses

Batch takes up to 10,000 addresses per request and returns them in input order, one unit each. Strings and structured objects can be mixed.

addresses = ["1600 Pennsylvania Ave NW, Washington DC",
             {"street": "1 Loockerman Plz", "city": "Dover", "state": "DE"}]
r = requests.post("https://api.geocode.net/v1/geocode/batch",
                  json={"addresses": addresses, "fields": "timezone"},
                  headers={"X-API-Key": KEY})
for item in r.json()["results"]:
    hit = item["results"][0] if item["results"] else None
    print(item["query"], "->", hit and hit["formatted"], hit and hit["accuracy_type"])

The X-Gw-Units response header says how many units the call used.

Into a DataFrame

import pandas as pd

df = pd.read_csv("customers.csv")
chunks = [df["address"].tolist()[i:i + 10000] for i in range(0, len(df), 10000)]
rows = []
for chunk in chunks:
    r = requests.post("https://api.geocode.net/v1/geocode/batch", json={"addresses": chunk},
                      headers={"X-API-Key": KEY})
    for item in r.json()["results"]:
        hit = item["results"][0] if item["results"] else {}
        rows.append({"lat": hit.get("location", {}).get("lat"), "lng": hit.get("location", {}).get("lng"),
                     "accuracy_type": hit.get("accuracy_type")})
df = pd.concat([df, pd.DataFrame(rows)], axis=1)
df.to_csv("customers_geocoded.csv", index=False)

You may store the output indefinitely. The index is built from public-domain sources, so there is no cache-expiry rule to track.

Errors

Non-2xx responses carry one shape: {"error": "bad_request", "message": "…", "param": "q"}. Rate limit is 20 requests a second per key; a batch call counts as one request.

Ready to geocode for real?

10,000 free lookups a month, every append included, no card.