Replace Mapbox geocodingfor city search
Find cities by name or by position, and store every result at no extra price.
30,000 requests a month free, with commercial use. No card needed.
| Service | City suggestions | Reverse lookup | Free plan |
|---|---|---|---|
| Onde Growth | $29 | $29 | 30,000 a month |
| Mapbox permanent geocoding | about $4,500 | about $4,500 | None |
Public prices on 2026-11-03.
What the price table leaves out
-
Free results you may keep
You may store every result of the Onde Free plan. Mapbox gives free geocoding requests only for temporary results, which you may not cache.
-
IDs that stay the same
An Onde city ID stays the same in every later dataset, and a retired ID returns its replacement when one exists.
-
Private search text
We do not store the search text or the positions that you send. You can tell your users the same.
Keep Mapbox for maps and addresses
Mapbox draws maps and finds street addresses. Onde finds cities and districts only, and your app can show them on any map. Keep Mapbox where you need an address, and move the city search to Onde.
Try the live API
curl "https://api.onde.earth/v1/cities/autocomplete?q=kyoto" \
-H "Authorization: Bearer $ONDE_KEY" const url = 'https://api.onde.earth/v1/cities/autocomplete'
const query = new URLSearchParams({ q: 'kyoto', key: 'onde_pk_...' })
const response = await fetch(`${url}?${query}`)
const { data } = await response.json() const url = 'https://api.onde.earth/v1/cities/autocomplete'
const query = new URLSearchParams({ q: 'kyoto' })
const response = await fetch(`${url}?${query}`, {
headers: { Authorization: `Bearer ${process.env.ONDE_KEY}` }
})
const { data } = await response.json() import os
import requests
response = requests.get(
"https://api.onde.earth/v1/cities/autocomplete",
params={"q": "kyoto"},
headers={"Authorization": f"Bearer {os.environ['ONDE_KEY']}"},
)
data = response.json()["data"] {
"data": [
{
"id": "city_39sy1dm2dj",
"name": "Kyoto",
"localName": "京都市",
"type": "city",
"parentCityId": null,
"country": {
"code": "JP",
"name": "Japan"
},
"region": {
"id": "region_yjwfrtj0fe",
"isoCode": "JP-26",
"name": "Kyoto"
},
"coordinates": {
"latitude": 35.02107,
"longitude": 135.75385
},
"population": 1463723,
"timeZone": "Asia/Tokyo",
"isCapital": false,
"disputed": false,
"match": "exact"
}
],
"meta": {
"dataset": "2026-11-17"
}
} curl "https://api.onde.earth/v1/cities/reverse?latitude=35.02&longitude=135.75" \
-H "Authorization: Bearer $ONDE_KEY" const url = 'https://api.onde.earth/v1/cities/reverse'
const query = new URLSearchParams({ latitude: '35.02', longitude: '135.75', key: 'onde_pk_...' })
const response = await fetch(`${url}?${query}`)
const { data } = await response.json() const url = 'https://api.onde.earth/v1/cities/reverse'
const query = new URLSearchParams({ latitude: '35.02', longitude: '135.75' })
const response = await fetch(`${url}?${query}`, {
headers: { Authorization: `Bearer ${process.env.ONDE_KEY}` }
})
const { data } = await response.json() import os
import requests
response = requests.get(
"https://api.onde.earth/v1/cities/reverse",
params={"latitude": "35.02", "longitude": "135.75"},
headers={"Authorization": f"Bearer {os.environ['ONDE_KEY']}"},
)
data = response.json()["data"] {
"data": {
"id": "city_39sy1dm2dj",
"name": "Kyoto",
"localName": "京都市",
"type": "city",
"parentCityId": null,
"country": {
"code": "JP",
"name": "Japan"
},
"region": {
"id": "region_yjwfrtj0fe",
"isoCode": "JP-26",
"name": "Kyoto"
},
"coordinates": {
"latitude": 35.02107,
"longitude": 135.75385
},
"population": 1463723,
"timeZone": "Asia/Tokyo",
"isCapital": false,
"disputed": false,
"distanceKm": 0.37023042894617736
},
"meta": {
"dataset": "2026-11-17"
}
} How we compare
- The Mapbox row uses permanent geocoding, because you may store Onde results.
- The prices are from the public pricing page on 2026-11-03.
- On 2026-11-04, temporary geocoding cost about $600 at 1 million requests a month, but Mapbox does not permit a cache of temporary results.
Try Onde next to Mapbox
- No card needed
- 30,000 requests a month free
- Commercial use on the Free plan