GeoAPI.pt API
Free Portuguese geography API with no key: districts, municipalities, parishes, postcodes and reverse geocoding, with census figures and boundary GeoJSON. Tested example included.
Endpoint tested and returned HTTP 200 on 2026-08-21
What is the GeoAPI.pt API?
GeoAPI.pt is a free, key-free API for Portuguese geography. It exposes districts, municipalities (concelhos) and parishes (freguesias) with boundary polygons and census data, and resolves postal codes and coordinates to the administrative units that contain them.
Portugal reorganised its parishes in 2013, merging more than a thousand of them, and a surprising amount of software still carries the old list. GeoAPI.pt is built on the current official boundaries from the Carta Administrativa Oficial de Portugal, and pairs them with census results from both 2011 and 2021 — which makes it as much a demographic source as a geographic one.
Two endpoints carry a much tighter quota than the rest, and it is worth knowing before you design around them. The postcode lookup at `/cp/{code}` and the reverse geocoder at `/gps/{lat},{lon}` are limited to five requests per IP per day; the administrative endpoints used in the example below are unmetered. The reverse geocoder is remarkable when you do spend a call on it — alongside district, municipality and parish it returns altitude, current weather, land use and the official flood and wildfire risk ratings for the point.
Quick facts
- Base URL
https://json.geoapi.pt- Authentication
- No API key or account. Open-source project built on official Portuguese public data; free for any use.
- Rate limit
- Administrative endpoints are unmetered. The `/cp/` postcode lookup and `/gps/` reverse geocoder allow only five requests per IP per day (`RateLimit-Policy: 5;w=86400`).
- Pricing
- Free and open source.
- CORS
- Enabled — callable directly from browser JavaScript
- Official docs
- Read the docs
How to use the GeoAPI.pt API
Every request below was executed against the live API on 2026-08-21, and the response shown is the real body it returned — not an illustration.
1. List the parishes of a Portuguese municipality
GET https://json.geoapi.pt/municipio/Lisboa/freguesias
curl 'https://json.geoapi.pt/municipio/Lisboa/freguesias'const res = await fetch("https://json.geoapi.pt/municipio/Lisboa/freguesias");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);import requests
res = requests.get("https://json.geoapi.pt/municipio/Lisboa/freguesias", timeout=20)
res.raise_for_status()
print(res.json()){
"nome": "Lisboa",
"dtmn": "1106",
"codigoine": "1106",
"freguesias": [
"Ajuda",
"Alcântara",
"Alvalade",
"Areeiro",
"Arroios",
"Avenidas Novas",
"Beato",
"Belém",
"Benfica",
"Campo de Ourique",
"Campolide",
"Carnide",
"Estrela",
"Lumiar",
"Marvila",
"Misericórdia",
"Olivais",
"Parque das Nações",
"Penha de França",
"Santa Clara",
"Santa Maria Maior",
"Santo António",
"São Domingos de Benfica",
"São Vicente"
],
"geojsons": {
"municipio": {
"type": "Feature",
"properties": {
"Area_T_ha": 10018.2,
"Area_EA_ha": 10018.2,
"centros": {
"centro": [
-9.16213785,
38.7383962
],
"centroide": [
-9.160301560291737,
38.76797773265803
],
"centroDeMassa": [
-9.156771788090566,
38.73767450573927
],
"centroMedio": [
-9.160364427773281,
38.76790858777329
],
"centroMediano": [
-9.160301560291737,
38.76797773265803
]
},
"Dicofre": "1106",
"Concelho": "Lisboa",
"Distrito": "Lisboa"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-9.2379429,
38.6825838
],
[
-9.2296004,
38.6800327
],
[
-9.2217543,
38.6806015Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
municipio | path | Optional | Municipality name, accents optional. `/municipio/{name}` returns its full record. Lisboa |
freguesias | path | Optional | Appended to a municipality path to list its parishes. freguesias |
cp | path | Optional | `/cp/{XXXX-XXX}` resolves a full postal code. Rate limited to five calls per day. 1000-001 |
gps | path | Optional | `/gps/{lat},{lon}` reverse-geocodes a point. Also five calls per day. 38.7223,-9.1393 |
distrito | path | Optional | `/distrito/{name}` returns a district and the municipalities inside it. Lisboa |
json | query | Optional | `?json=1` forces JSON when calling the geoapi.pt host; the json. subdomain always returns JSON. 1 |
Response fields
nomestring- Municipality name.
codigoine / dtmnstring- INE municipality code — the official statistical identifier, and the safe join key.
freguesiasarray- Names of the parishes in the municipality, using the post-2013 boundaries.
geojsons.municipioobject- GeoJSON Feature for the municipality boundary, with `[longitude, latitude]` coordinate pairs.
geojsons.municipio.properties.centrosobject- Five different centre definitions — geometric centre, centroid, centre of mass, mean and median centre. They differ by kilometres for coastal municipalities.
Area_T_ha / Area_EA_hafloat- Total and effective area in hectares.
censos2011 / censos2021object- Census figures for the unit, on the full municipality endpoint.
(on /cp/) Distrito, Concelho, Localidadestring- District, municipality and locality for a postal code, plus street `partes` and geocoded `pontos`.
What you can build with the GeoAPI.pt API
- Build a district → municipality → parish selector with current boundaries
- Validate that a Portuguese address names a parish that still exists
- Draw municipality or parish boundaries on a map from the bundled GeoJSON
- Attach 2021 census figures to Portuguese regional analysis
- Resolve a coordinate to its parish, altitude and official risk ratings
Common errors and how to fix them
429 on /cp/ or /gps/
Those two endpoints allow five requests per IP per day.
Fix: Cache results permanently — postcodes barely change — and read `RateLimit-Remaining` to see how many calls you have left before you spend them.
404 with an `erro` message
The municipality or parish name did not match, or a query parameter is not valid for that path.
Fix: The error body names the offending parameter. Accents are optional in names, but the spelling must otherwise be exact.
Response is dominated by geometry
Boundary polygons run to thousands of coordinate pairs.
Fix: Request the narrower path you actually need, such as `/municipio/{name}/freguesias`, rather than the full municipality record.
Parish list disagrees with an older dataset
Not an error — Portugal merged its parishes in 2013.
Fix: GeoAPI.pt uses current boundaries. If you are joining to pre-2013 data you need a mapping table, not a different API.
GeoAPI.pt API — frequently asked questions
Is GeoAPI.pt free?
Yes, free and open source with no key or account. Most endpoints are unmetered; the postcode and reverse-geocoding endpoints are capped at five requests per IP per day.
Can I look up a Portuguese postal code?
Yes, at `/cp/{XXXX-XXX}`. It returns district, municipality, locality, the street sections covered by the code and geocoded address points — but it is one of the two rate-limited endpoints, so cache what you get.
Which parish boundaries does it use?
The current ones, from the official Carta Administrativa Oficial de Portugal. Portugal merged more than a thousand parishes in 2013, so results will not line up with older lists.
Why does the response contain five different centre points?
Because they answer different questions. The centroid of a municipality with a long coastline or a river estuary can fall outside its own boundary, so the API also gives centre of mass, mean and median centres — pick the one that suits how you are labelling the map.
Tools that pair with this API
GeoJSON Validator
Validate GeoJSON against RFC 7946 and get the exact JSON path of every problem: unclosed rings, swapped coordinates, missing properties and more.
GeoJSON to CSV Converter
Flatten a GeoJSON FeatureCollection into a CSV table with one row per feature, a centroid for lines and polygons, and every property as a column.
JSON Formatter
Format, beautify and minify JSON online with 2-space, 4-space or tab indentation. Sort keys alphabetically and catch syntax errors instantly — free and private.
GeoAPI.pt is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-21; always check the official documentation before relying on this API in production, as terms and limits can change.