Migrate · from self-hosted Pelias or Photon
Migrate from a self-hosted Pelias or Photon to geolith
geolith accepts the same parameters as Pelias: /v1/search, /v1/autocomplete, /v1/reverse, /v1/search/structured and /v1/place with text, size, layers, boundary.country and focus.point.*. Point your Pelias client at https://api.geolith.app and add a key. From Photon, map /api?q= to /v1/search?text=. On the India benchmark (20 Oct 2026) geolith scored 82.5 % on autocomplete against 42.5 % for Photon and 32.5 % for Pelias, from one 543 MB file with no OpenSearch.
Requests
Request mapping
Pelias GET /v1/search?text=…
→ GET /v1/search?text=…
Same.
Pelias GET /v1/autocomplete?text=…
→ GET /v1/autocomplete?text=…
Same.
Pelias GET /v1/reverse?point.lat=…&point.lon=…
→ GET /v1/reverse?point.lat=…&point.lon=…
Same.
Pelias size, layers, boundary.country, focus.point.*
→ Same names
size up to 40.
Pelias sources=osm,oa,wof
→ Not used
One source: geolith.
Pelias boundary.rect.* on search
→ Not supported
Use boundary.country or a focus point.
Photon GET /api?q=…
→ GET /v1/search?text=… or /v1/autocomplete?text=…
Photon lat=…&lon=… (bias)
→ focus.point.lat=…&focus.point.lon=…
Photon limit=…
→ size=…
Photon lang=…
→ lang=…
Self-hosted server; hosted API planned.
Photon osm_tag=amenity:cafe
→ categories=food or categories=cafe
Self-hosted server; hosted API planned.
Photon GET /reverse?lat=…&lon=…
→ GET /v1/reverse?point.lat=…&point.lon=…
| self-hosted Pelias or Photon | geolith | Note |
|---|---|---|
| Pelias GET /v1/search?text=… | GET /v1/search?text=… | Same. |
| Pelias GET /v1/autocomplete?text=… | GET /v1/autocomplete?text=… | Same. |
| Pelias GET /v1/reverse?point.lat=…&point.lon=… | GET /v1/reverse?point.lat=…&point.lon=… | Same. |
| Pelias size, layers, boundary.country, focus.point.* | Same names | size up to 40. |
| Pelias sources=osm,oa,wof | Not used | One source: geolith. |
| Pelias boundary.rect.* on search | Not supported | Use boundary.country or a focus point. |
| Photon GET /api?q=… | GET /v1/search?text=… or /v1/autocomplete?text=… | |
| Photon lat=…&lon=… (bias) | focus.point.lat=…&focus.point.lon=… | |
| Photon limit=… | size=… | |
| Photon lang=… | lang=… | Self-hosted server; hosted API planned. |
| Photon osm_tag=amenity:cafe | categories=food or categories=cafe | Self-hosted server; hosted API planned. |
| Photon GET /reverse?lat=…&lon=… | GET /v1/reverse?point.lat=…&point.lon=… |
Responses
Response mapping
Pelias features[].properties.label
→ features[].properties.label
Same.
Pelias properties.gid (osm:venue:node/1)
→ properties.gid (geolith:venue:<id>)
Re-fetch stored gids once.
Pelias properties.confidence, distance
→ properties.confidence, distance
Same names.
Photon properties.name
→ properties.name
Photon properties.city
→ properties.locality
Photon properties.state
→ properties.region
Photon properties.postcode
→ properties.postalcode
Photon properties.countrycode
→ properties.country_code
Photon properties.extent
→ feature bbox
| self-hosted Pelias or Photon | geolith | Note |
|---|---|---|
| Pelias features[].properties.label | features[].properties.label | Same. |
| Pelias properties.gid (osm:venue:node/1) | properties.gid (geolith:venue:<id>) | Re-fetch stored gids once. |
| Pelias properties.confidence, distance | properties.confidence, distance | Same names. |
| Photon properties.name | properties.name | |
| Photon properties.city | properties.locality | |
| Photon properties.state | properties.region | |
| Photon properties.postcode | properties.postalcode | |
| Photon properties.countrycode | properties.country_code | |
| Photon properties.extent | feature bbox |
Code
Before and after
const url = new URL('http://pelias.internal:4000/v1/autocomplete');
url.searchParams.set('text', 'shaniwar wa');
url.searchParams.set('focus.point.lat', '18.5204');
url.searchParams.set('focus.point.lon', '73.8567');
url.searchParams.set('sources', 'osm,oa');
const { features } = await (await fetch(url)).json();const url = new URL('https://api.geolith.app/v1/autocomplete');
url.searchParams.set('text', 'shaniwar wa');
url.searchParams.set('focus.point.lat', '18.5204');
url.searchParams.set('focus.point.lon', '73.8567');
url.searchParams.set('api_key', GEOLITH_PUBLISHABLE_KEY);
const { features } = await (await fetch(url)).json();Detail
Hosted or self-hosted
Use the hosted API at api.geolith.app, or keep running it yourself. A self-hosted geolith is one Rust binary and one static .glx file answered by HTTP range reads: no OpenSearch, no libpostal, no placeholder or point-in-polygon services.
- India benchmark, same machine: geolith 543 MB, one file; Pelias 1.0 GB plus supporting services; Photon 810 MB.
- Feature probes: geolith 24 of 25, Photon 19, Pelias 16.
- Errors keep the Pelias shape: an empty FeatureCollection with geocoding.errors.
Questions
Migrating from self-hosted Pelias or Photon: questions
- Will my Pelias client library work?
- Usually yes for search, autocomplete, reverse, structured and place: geolith accepts the same parameters as Pelias and returns the same GeoJSON shape. Add the API key and drop sources=.
- Can I keep self-hosting?
- Yes. geolith runs from one static .glx file with no database. See the self-hosting cost page and the docs.
Geocode your first address in a minute.
100,000 requests a month free. Commercial use with attribution. No card.