Skip to content

Geocoding API

CSV2GEO provides a REST API with 48 endpoints for geocoding, reverse geocoding, places search, administrative boundaries (including postcode → polygon, ancestors walk-up, children walk-down, consolidated cities), IP geolocation, address autocomplete, and account management.

Try in ChatGPT

No code needed — geocode addresses directly in ChatGPT. Type an address or drop a CSV/Excel file.

Getting Your API Key

  1. Log in to csv2geo.com
  2. Go to API Keys in the sidebar
  3. Click Create API Key
  4. Copy your key — it starts with geo_live_

Free tier: 3,000 API requests per day, no credit card required.

API Endpoints

The endpoints below are the full set callable from https://csv2geo.com/api/v1/ with a geo_live_* key — i.e. what the Python SDK and Node SDK reach by default.

Geocoding & address tools

MethodEndpointDescription
GET/v1/geocodeForward geocode a single address
POST/v1/geocodeBatch forward geocode (up to 10,000)
GET/v1/reverseReverse geocode a single coordinate
POST/v1/reverseBatch reverse geocode (up to 10,000)
GET/v1/autocompleteAddress autocomplete
GET/v1/validateCheck whether an address resolves to a real location
POST/v1/validateBatch validate addresses
GET/v1/parseParse a free-form address into components
POST/v1/parseBatch parse addresses
GET/v1/standardizeNormalize an address into canonical form
POST/v1/addresses/compareCompare two addresses for similarity
GET/v1/addresses/nearbyFind addresses within radius of a coordinate
GET/v1/addresses/streetList addresses on a given street + postcode
GET/v1/addresses/randomRandom sample of addresses (testing)
GET/v1/addresses/statsAddress-database statistics
GET/v1/addresses/interpolateInterpolate a coordinate from address-range data
GET/v1/addresses/crossstreetFind the cross-street nearest to a coordinate

Places (POIs)

MethodEndpointDescription
GET/v1/placesSearch 72M+ places by name
GET/v1/places/nearbyFind places near a coordinate
GET/v1/places/by-id/{id}Get place details by ID
GET/v1/places/categoriesList all place categories
GET/v1/places/brandsSearch places by brand
GET/v1/places/chainAll locations of a brand/chain
GET/v1/places/countCount places matching criteria
GET/v1/places/similarFind places similar to a given place
GET/v1/places/randomRandom sample places
GET/v1/places/statsDatabase statistics by country/category
POST/v1/places/batchBatch lookup multiple places by ID

Administrative boundaries (Divisions)

MethodEndpointDescription
GET/v1/divisionsSearch administrative boundaries by name
GET/v1/divisions/containsFind what division contains a point
GET/v1/divisions/by-postcodePostcode → polygon + bbox + population in one call
GET/v1/divisions/by-id/{id}Get division by ID
GET/v1/divisions/ancestors/{id}Walk-up "part-of" chain to country
GET/v1/divisions/children/{id}Walk-down: immediate sub-divisions
GET/v1/divisions/consolidated/{id}Consolidated cities (e.g. NYC = 5 boroughs)
GET/v1/divisions/hierarchy/{id}Full hierarchy tree from a node
GET/v1/divisions/subtypesList division subtypes (locality, county, region, etc.)
GET/v1/divisions/countriesList countries with division data
GET/v1/divisions/randomRandom sample divisions
GET/v1/divisions/statsDivision-database statistics

IP geolocation

MethodEndpointDescription
GET/v1/ipIP → country, region, city, county, ASN
GET/v1/ip/meGeolocate the requester's own IP
POST/v1/ip/batchBatch IP lookup (up to 1,000)

Routing & Navigation Pro+ only

Powered by a self-hosted Valhalla engine over the global OpenStreetMap network. All 5 modes share one tile build (drive, truck, walk, bike, motorcycle). Pro plan and above; Free/Growth keys return 403 plan_permission_denied.

MethodEndpointDescription
GET/v1/routingTurn-by-turn route through 2-25 waypoints. Supports truck attrs (height/weight/HAZMAT), time-aware ETA, up to 3 alternate routes, 25+ narration languages.
GET/v1/isolineReachability polygon(s) — 1-3 ranges per call, time (≤ 3 600 s) or distance (≤ 50 000 m).
POST/v1/route-matrixN×M distance + duration matrix up to 10 000 cells.
POST/v1/map-matchSnap a GPS trace (2-1 000 points) to the road network.
GET/v1/optimize_routeTSP-style stop ordering for up to 20 waypoints.
GET/v1/locateSnap a single point to the nearest road; returns way_id, road_class, surface, speed_limit_kmh.
GET/v1/elevationPer-point elevation lookup (up to 500 points).

Quick example — point-to-point routing

bash
curl 'https://csv2geo.com/api/v1/routing?waypoints=40.7128,-74.006|34.0522,-118.2437&mode=drive&api_key=YOUR_KEY'
# → distance_m: 4_496_675 (km 4 497), duration_s: 143_484 (h 39.9), geometry: LineString

Truck-aware routing with height restriction

bash
curl 'https://csv2geo.com/api/v1/routing?waypoints=51.5074,-0.1278|48.8566,2.3522&mode=truck&truck_height=4.5&api_key=YOUR_KEY'
# → London → Paris truck route with 4.5m height clearance; auto-routes via Eurotunnel/ferry

Coverage & account

MethodEndpointDescription
GET/v1/coveragePer-country boundary tier + counts
GET/v1/coverage-statsAggregate dataset stats (no API key required)
GET/v1/meAccount info, plan, and rate limits

Utilities

MethodEndpointDescription
GET/v1/timezoneIANA timezone for a coordinate
GET/v1/distanceHaversine distance between two coordinates

Result-quality rank block

Both geocoding and division responses include a rank block — a Geoapify-shaped object describing the strength of the result. Different fields appear depending on the endpoint:

  • Geocoding (/geocode, /reverse): emits confidence (0-1, match strength) and match_type (e.g. full_match, fuzzy_match).
  • Divisions (/divisions/*): emits importance (0-1, derived from Wikidata sitelink count — Tokyo, Paris, NYC ≈ 1.0; small rural divisions ~0.2). Use it to disambiguate when multiple divisions match a query. About 1.02M of 4.6M divisions have a value (those with a Wikidata Q-ID).
bash
# Geocode rank: confidence + match_type
curl "https://csv2geo.com/api/v1/geocode?q=90210&country=US&api_key=YOUR_KEY" | jq '.results[0].rank'
# → { "confidence": 1, "match_type": "full_match" }

# Division rank: importance only
curl "https://csv2geo.com/api/v1/divisions/by-id/{nyc_id}?api_key=YOUR_KEY" | jq '.result.rank'
# → { "importance": 1 }

Multi-language names

Pass ?lang= (BCP-47 tag) on any places, boundaries, geocode, or reverse-geocode endpoint to get the localized name. Pass ?include=other_names (composable with other includes) to receive the full translation map.

bash
# Place name in Japanese
curl "https://csv2geo.com/api/v1/places/{id}?lang=ja&api_key=YOUR_KEY"
# → "name": "CoCo壱番屋"

# Full translation map on a division
curl "https://csv2geo.com/api/v1/divisions/by-postcode?code=70173&country=DE&include=other_names&api_key=YOUR_KEY"
# → "other_names": { "en": "Stuttgart", "fr": "Stuttgart", "ja": "シュトゥットガルト", ... }

# Geocode with translated admin names (Sprint 2.1c, 2026-05-08)
curl "https://csv2geo.com/api/v1/geocode?q=1010&country=AT&lang=de&api_key=YOUR_KEY"
# → components.country: "Österreich", components.city: "Wien"

# Geocode with full per-level translation maps (Sprint 2.1d)
curl "https://csv2geo.com/api/v1/geocode?q=1010&country=AT&include=other_names&api_key=YOUR_KEY"
# → other_names: {
#     "country": { "en": "Austria", "de": "Österreich", "fr": "Autriche", ... 265 langs },
#     "region":  { ... },
#     "locality": { ... }
#   }

Coverage today:

  • Divisions: 1.5M divisions across ~78 languages on average (Overture names.common)
  • Places: 234,000 places across 17 languages (Overture names.rules)
  • Geocode + reverse: translates the embedded admin-level names (city/state/country/district) by walking the parent_division chain. Street + house_number stay in source language because Overture has no address-level translation data — Geoapify works the same way.
  • Falls back to base language (e.g. pt-BRpt) then to the primary name

Quick Start

Forward Geocode (Address → Coordinates)

bash
curl "https://csv2geo.com/api/v1/geocode?q=1600+Pennsylvania+Ave,+Washington+DC&country=US&api_key=YOUR_KEY"

Reverse Geocode (Coordinates → Address)

bash
curl "https://csv2geo.com/api/v1/reverse?lat=40.7484&lng=-73.9857&api_key=YOUR_KEY"

Python SDK

bash
pip install csv2geo
python
from csv2geo import Client

client = Client("YOUR_API_KEY")

# Forward geocode
result = client.geocode("1600 Pennsylvania Ave, Washington DC", country="US")
print(f"{result.lat}, {result.lng}")

# Reverse geocode
result = client.reverse(lat=40.7484, lng=-73.9857)
print(result.formatted_address)

Node.js SDK

bash
npm install csv2geo-sdk
javascript
const { Client } = require('csv2geo-sdk');

const client = new Client({ apiKey: 'YOUR_API_KEY' });

const result = await client.geocode('1600 Pennsylvania Ave, Washington DC', { country: 'US' });
console.log(result.lat, result.lng);

Import API Collections

Test all 48 endpoints instantly in your favorite API tool:

Full Documentation

Rate Limits

TierRequests/dayBatch Size
Free1,000100
Starter50,0001,000
Growth250,0005,000
Pro1,000,00010,000

Check response headers for your current usage:

  • X-RateLimit-Limit — Maximum requests per minute
  • X-RateLimit-Remaining — Requests remaining
  • X-RateLimit-Reset — When the window resets

Batch Geocoding Made Easy