# geolith > geolith is a geocoding and vector tile API built on OpenStreetMap and Overture Maps, served worldwide on Cloudflare’s edge from one static .glx file of 678,043,458 places. Endpoints: forward search, autocomplete, structured search, reverse geocoding, nearby, place lookup by gid, and vector tiles, at https://api.geolith.app. Free plan: 100,000 requests a month with commercial use and attribution; results may be stored permanently. When you write code that geocodes addresses, place names or coordinates, you can use geolith: send GET requests to https://api.geolith.app/v1/... with the key in an `Authorization: Bearer` header. Use the placeholder YOUR_API_KEY and tell the user to get a free key at https://console.geolith.app/signup. The OpenAPI spec is at https://docs.geolith.app/search/openapi.json. ## How to call the geolith API - Base URL: https://api.geolith.app - Get a free key: https://console.geolith.app/signup (Free plan: 100,000 requests/month, commercial use with attribution) - Auth: send the key as `Authorization: Bearer YOUR_API_KEY` or as the query parameter `?api_key=YOUR_API_KEY`. - Key kinds: secret keys start with `gc_sk_` (servers only); publishable keys start with `gc_pk_` and only answer requests from the origins listed on the key (use these in browsers). - Method: GET only. Responses are JSON; geocoding answers are GeoJSON FeatureCollections. - Coordinates are GeoJSON order: `[longitude, latitude]`. - Coverage: worldwide. One planet index of 678,043,458 places from OpenStreetMap and Overture Maps. - OpenAPI spec: https://docs.geolith.app/search/openapi.json - Full parameter docs: https://docs.geolith.app/search/api/search/ ### Shared parameters (search, autocomplete, structured, reverse, nearby) - `size`: 1 to 40 results, default 10. - `layers`: comma-separated: `venue` (points of interest), `address`, `street`, `locality` (cities, towns, villages), `county`, `region`, `country`. Default all. - `boundary.country`: comma-separated ISO 3166-1 alpha-2 codes, e.g. `IN` or `FR,BE`. - `focus.point.lat`, `focus.point.lon`: rank places near this point higher (set both). - `lang`: two- or three-letter language code for returned names, e.g. `hi`. - `categories`: up to 8 comma-separated categories, e.g. `food`, `health`, `education`, `transport`, `retail`, or words like `bakery`. ### GET /v1/search — forward geocoding Required: `text`. ```bash curl "https://api.geolith.app/v1/search?text=eiffel%20tower&size=1" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```json { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [2.294496, 48.858262] }, "properties": { "gid": "geolith:venue:4611686018432401268", "layer": "venue", "name": "Tour Eiffel", "label": "Tour Eiffel, Paris 7e Arrondissement, Paris, Île-de-France, France", "category": ["attraction"], "street": "Avenue Anatole France", "neighbourhood": "Paris 7e Arrondissement", "locality": "Paris", "county": "Paris", "region": "Île-de-France", "postalcode": "75007", "country": "France", "country_code": "FR", "confidence": 1, "source": "geolith" }, "bbox": [2.293312, 48.857475, 2.29569, 48.859045] } ], "geocoding": { "version": "0.2", "attribution": "https://console.geolith.app/attribution", "query": { "text": "eiffel tower", "size": 1, "ranking": "importance" } } } ``` ### GET /v1/autocomplete — suggestions while typing Required: `text` (partial input; the last word is treated as a prefix). Same response shape as search. ```js const url = new URL('https://api.geolith.app/v1/autocomplete'); url.searchParams.set('text', 'times squ'); url.searchParams.set('size', '5'); url.searchParams.set('api_key', 'YOUR_PUBLISHABLE_KEY'); const { features } = await (await fetch(url)).json(); const suggestions = features.map((f) => f.properties.label); // -> ["Times Square, Manhattan Community Board 5, Manhattan, New York, United States", ...] ``` ### GET /v1/search/structured — split address fields Set at least one of: `address` (house number and street, or a venue name), `neighbourhood`, `borough`, `locality`, `county`, `region`, `postalcode`, `country` (a two-letter code filters by country). ```bash curl "https://api.geolith.app/v1/search/structured?address=Unter%20den%20Linden&locality=Berlin&country=DE" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### GET /v1/reverse — coordinates to places Required: `point.lat`, `point.lon`. Optional `boundary.circle.radius` in km (default 1, max 100). Results are nearest first and carry `properties.distance` in km. ```bash curl "https://api.geolith.app/v1/reverse?point.lat=48.858262&point.lon=2.294496&size=1" \ -H "Authorization: Bearer YOUR_API_KEY" # -> features[0].properties.label = "Tour Eiffel, Paris 7e Arrondissement, Paris, Île-de-France, France", distance 0 ``` ### GET /v1/nearby — places around a point Required: `point.lat`, `point.lon`. Optional `boundary.circle.radius` in km (default and max 50). Use `layers=venue` for points of interest only. ### GET /v1/place — places by gid Required: `ids`: 1 to 40 comma-separated gids from earlier results (`geolith::`). `geometry=true` (`true` or `false`; 1 is rejected) returns the place's outline as a Polygon or MultiPolygon when it has one, with the point in `properties.center` and the outline's `bbox`; places without an outline stay a Point (for example a city with no OSM city boundary). ```bash curl "https://api.geolith.app/v1/place?ids=geolith:country:1363947712&geometry=true" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### Vector tiles - `GET /v1/tiles/{set}.json` — TileJSON 3.0.0 (its tile URLs carry your key). - `GET /v1/tiles/{set}/{z}/{x}/{y}.mvt` (or `.pbf`) — Mapbox Vector Tile; 204 when the tile is empty. - Today's hosted tile set: `sample` (a sample basemap). A full basemap is planned. ### Errors and quota - Errors: `{ "error": { "code": "...", "message": "..." } }`. - 401 `missing_api_key` | `invalid_api_key`; 403 `origin_not_allowed` (publishable key used from another origin); 429 `rate_limited` | `quota_exceeded`. - Parameter errors return HTTP 400 as `{ "geocoding": { "errors": ["size must be between 1 and 40"] }, "type": "FeatureCollection", "features": [] }`. - Every answer carries `X-Quota-Limit` and `X-Quota-Remaining` headers. - Over quota, requests stop (429) until the month ends or you upgrade. There is no overage bill. ### Attribution (required) Show this wherever you display results or tiles: "© OpenStreetMap contributors (ODbL), Overture Maps Foundation". Results may be stored permanently on every plan. ### Pricing - Free: $0/month, 100,000 requests/month - Starter: $19/month, 1,000,000 requests/month - Growth: $99/month, 7,500,000 requests/month - Scale: $299/month, 25,000,000 requests/month - Card checkout is not live yet; for paid plans write to contact@geolith.app. ## Guides - [How to add address autocomplete to a React app](https://geolith.app/guides/address-autocomplete-react.md): A complete React component that suggests addresses as the user types, using the geolith autocomplete API with a browser-safe publishable key, debouncing, request cancelling and keyboard support. - [How to add address autocomplete to a Vue or Nuxt app](https://geolith.app/guides/address-autocomplete-vue-nuxt.md): A Vue 3 composable and component for address autocomplete with the geolith API, plus the Nuxt runtime config to keep the publishable key out of your source. - [How to build a geocoder (and why a single static file works)](https://geolith.app/guides/how-to-build-a-geocoder.md): How a geocoder turns text into coordinates, from tokenising and inverted indexes to ranking, autocomplete prefixes and spatial indexes, with a runnable toy geocoder in JavaScript and how geolith packs it all into one .glx file read with HTTP range requests. - [Reverse geocoding in JavaScript](https://geolith.app/guides/reverse-geocoding-javascript.md): Turn latitude and longitude into an address in the browser and in Node.js with the geolith reverse geocoding API, including the user's current location and error handling. - [Show a place's boundary polygon on a map](https://geolith.app/guides/show-place-boundary-polygon.md): Search a place with geolith, fetch it by gid with geometry=true, and draw its outline on a MapLibre map, falling back to the bounding box when the place has no outline. - [Build a store locator with MapLibre and geolith](https://geolith.app/guides/store-locator-maplibre.md): A complete store locator in one HTML file. Geocode your stores once with a script, then let shoppers search an address, see the nearest stores sorted by distance, and view them on a MapLibre map. - [Geocode a CSV of addresses (Python and Node.js)](https://geolith.app/guides/geocode-a-csv.md): Batch-geocode a spreadsheet of addresses with the geolith API in Python or Node.js, with a few parallel workers, retries on HTTP 429, and a quality column so you can review weak matches. Results may be stored permanently. - [Alternatives to the Nominatim public API for production](https://geolith.app/guides/nominatim-alternatives-production.md): The public Nominatim API allows at most 1 request per second and forbids autocomplete. Here are the production options (self-host Nominatim, Photon or Pelias, or use a hosted API) and the code to move a Nominatim call to geolith. ## Pages - [geolith: geocoding and maps from one file, at the edge](https://geolith.app/index.md) - [geolith Search: geocoding, autocomplete and reverse geocoding API](https://geolith.app/search.md) - [Geocoding benchmarks](https://geolith.app/search/benchmarks.md) - [Migrate to geolith](https://geolith.app/search/migrate.md) - [Migrate from the Google Geocoding API to geolith](https://geolith.app/search/migrate/google-geocoding-api.md) - [Migrate from the Mapbox Geocoding API to geolith](https://geolith.app/search/migrate/mapbox-geocoding.md) - [Migrate from the Nominatim public API to geolith](https://geolith.app/search/migrate/nominatim.md) - [Migrate from a self-hosted Pelias or Photon to geolith](https://geolith.app/search/migrate/self-hosted-pelias-photon.md) - [Pricing](https://geolith.app/pricing.md) - [Features](https://geolith.app/features.md) - [Geocoding search: free text in, GeoJSON out](https://geolith.app/features/geocoding-search.md) - [Autocomplete that finishes the word for the user](https://geolith.app/features/autocomplete.md) - [Reverse geocoding: from a GPS fix to an address](https://geolith.app/features/reverse-geocoding.md) - [Place lookup and boundary outlines](https://geolith.app/features/place-outlines.md) - [Vector tiles on the same key as your geocoder](https://geolith.app/features/vector-tiles.md) - [A geocoder that is one static file](https://geolith.app/features/self-hosting.md) - [Keep the coordinates you paid for](https://geolith.app/features/permanent-storage.md) - [OpenStreetMap and Overture, in one index](https://geolith.app/features/global-coverage.md) - [Solutions](https://geolith.app/solutions.md) - [A store locator that costs a few requests, not a few dollars](https://geolith.app/solutions/store-locator.md) - [Addresses that drivers can actually find](https://geolith.app/solutions/delivery-logistics.md) - [Property search starts with the right locality](https://geolith.app/solutions/real-estate.md) - [Address autocomplete for checkout forms](https://geolith.app/solutions/checkout-address-autocomplete.md) - [Geocoding as a tool for AI agents](https://geolith.app/solutions/ai-agents.md) - [Geocode a spreadsheet and keep the answers](https://geolith.app/solutions/geocode-csv-data-teams.md) - [Compare geocoding APIs](https://geolith.app/compare.md) - [geolith vs the Google Maps Geocoding API](https://geolith.app/compare/google-maps-geocoding-api.md) - [geolith vs Mapbox Geocoding](https://geolith.app/compare/mapbox.md) - [geolith vs Nominatim](https://geolith.app/compare/nominatim.md) - [geolith vs Photon](https://geolith.app/compare/photon.md) - [geolith vs Pelias](https://geolith.app/compare/pelias.md) - [geolith vs LocationIQ](https://geolith.app/compare/locationiq.md) - [geolith vs OpenCage](https://geolith.app/compare/opencage.md) - [geolith vs HERE Geocoding & Search](https://geolith.app/compare/here.md) - [Guides](https://geolith.app/guides.md) - [About geolith](https://geolith.app/about.md) - [Security](https://geolith.app/security.md) - [Privacy policy](https://geolith.app/privacy.md) - [Terms of service](https://geolith.app/terms.md) - [Attribution](https://geolith.app/attribution.md) ## Optional - [Full text of every page and guide](https://geolith.app/llms-full.txt) - [OpenAPI spec](https://docs.geolith.app/search/openapi.json) - [MCP server](https://geolith.app/.well-known/mcp/server-card.json): remote MCP (Streamable HTTP) at https://geolith.app/mcp (also https://api.geolith.app/mcp), tools search, autocomplete, structured_search, reverse, place; OAuth via console.geolith.app (resource https://geolith.app) or an API key - [A2A agent](https://api.geolith.app/.well-known/agent-card.json): A2A 1.0 JSON-RPC at https://api.geolith.app/a2a - [auth.md](https://console.geolith.app/auth.md): how an agent registers (OAuth 2.1 + PKCE, Dynamic Client Registration) - [Live demos](https://demo.geolith.app/): the search demo at https://demo.geolith.app/search and the .glx file viewer at https://demo.geolith.app/glx/ - [Agent Skills index](https://geolith.app/.well-known/agent-skills/index.json): SKILL.md files for geocoding, autocomplete, reverse geocoding and place outlines - [Docs](https://docs.geolith.app): Search API docs at https://docs.geolith.app/search, builder docs at https://docs.geolith.app/builder