City Memory API

Every Belgian municipality — official names in Dutch, French and German, NIS codes, province and region, WGS84 centroid, bounding box, surface area, which municipalities border which, and boundary geometry as GeoJSON.

It is free, public and needs no key. Every endpoint is a static file on a CDN, which is why there are no quotas, no rate limits and no sign-up — and also why there are no query parameters. Fetch a collection and filter it yourself, or fetch the province you care about.

565 municipalities, 11 provinces, 3 regions. Built from an OpenStreetMap extract of .

Start here

curl https://city-memory.pages.dev/api/v1/municipalities.json

One response, 565 municipalities, no geometry — around 250 kB. It is the file to reach for first, and for most uses the only one you need.

One municipality, with its boundary

curl https://city-memory.pages.dev/api/v1/municipalities/21004.json

A GeoJSON Feature, so it goes straight into Leaflet, MapLibre or QGIS without unwrapping. 21004 is the NIS code for Brussels; every municipality has one and it is the stable key across the whole API.

All the shapes at once

curl https://city-memory.pages.dev/api/v1/geo/belgium.geojson

A FeatureCollection of all 565 boundaries, simplified hard enough to send in one response. For detail, take /geo/provinces/{id}.geojson instead — those are simplified about forty times less.

Endpoints

Base URL: https://city-memory.pages.dev/api/v1

PathWhat it gives you
/municipalities.json Every municipality, without geometry
All 565 in one response, with names, codes, centroid, bbox and area but no boundary. About 250 kB. Fetch this once and filter it locally.
/municipalities/{nis}.json One municipality, with its boundary
A GeoJSON Feature: the summary fields under `properties`, and the boundary under `geometry` at roughly 10 m fidelity.
/provinces.json The eleven provinces
Brussels is counted as a province here, as the game does.
/provinces/{id}.json One province and all its municipalities
Includes the full summary of every municipality in it.
/regions.json The three regions
Flanders, Wallonia and Brussels-Capital.
/regions/{id}.json One region and all its municipalities
/search.json A name index for autocomplete
Every name in all three languages, lowercased and accent-folded, so a client can match user input without normalising anything itself.
/geo/belgium.geojson All 565 boundaries as one FeatureCollection
Simplified hard enough to send in one response. Use the province files when you need detail.
/geo/provinces/{id}.geojson One province's boundaries as a FeatureCollection
Simplified about forty times less than the national file.
/geo/regions/{id}.geojson One region's boundaries as a FeatureCollection

The full description is in openapi.json (OpenAPI 3.1), and index.json is a discovery document listing every endpoint.

What a municipality looks like

{
  "nis": "21004",
  "name": "Bruxelles / Brussel",
  "names": {
    "nl": "Brussel",
    "fr": "Bruxelles",
    "de": "Brüssel"
  },
  "officialLanguage": "both",
  "province": {
    "id": "brussels",
    "name": "Brussel / Bruxelles"
  },
  "region": {
    "id": "brussels",
    "name": "Brussel / Bruxelles"
  },
  "centroid": [
    4.351062,
    50.855125
  ],
  "bbox": [
    4.313768,
    50.796345,
    4.437066,
    50.913905
  ],
  "areaKm2": 32.97,
  "parts": 1,
  "neighbourCount": 16,
  "osm": {
    "relation": "relation/58274",
    "wikidata": "Q239"
  }
}
nis
The five-digit NIS/INS code Belgian administrations use. The stable identifier here.
name
The name the municipality uses itself: Dutch in Flanders, French in Wallonia, German in the German-speaking Community, both in Brussels.
centroid
[longitude, latitude], WGS84, and guaranteed to fall inside the municipality — so you can pin a marker on it even for a shape shaped like a horseshoe.
bbox
[west, south, east, north], WGS84.
areaKm2
Surface area, computed from the boundary on a sphere.
parts
How many disjoint pieces the municipality is made of. Usually 1. Baarle-Hertog is 26.
neighbourCount
How many municipalities share a border. The detail endpoint lists them by name.

Using it from a browser

Every endpoint sends Access-Control-Allow-Origin: *, so fetch it directly:

const res = await fetch('https://city-memory.pages.dev/api/v1/search.json');
const { entries } = await res.json();

// terms are lowercased and accent-folded, so "liege" finds Liège
const hits = entries.filter(e => e.terms.some(t => t.startsWith('liege')));

Stability

The path carries the version. Anything published under /api/v1/ keeps its shape: fields may be added, but existing ones will not change meaning or disappear. A breaking change becomes /api/v2/. The data behind it is refreshed when the OpenStreetMap extract is rebuilt, and generatedAt tells you when that was.

Licence and attribution

The data comes from OpenStreetMap and stays under the Open Database License. In practice:

The code behind this site is MIT. Attribution for City Memory itself is welcome but not required.

What this API is not