How to List a Region’s Subdivisions as GeoJSON with consists-of

API or service
Boundaries API
Task
Region place ID → subdivisions as points or polygons
Examples
URLAI
Difficulty
Beginner
Time
10 min

List a region's subdivisions as GeoJSON

You have a country, a state, or a city and need the areas it is divided into: the states of a country, the districts of a state, or the boroughs of a city, as a list or as polygons. The Boundaries API consists-of endpoint takes the place ID of a boundary and returns the boundaries inside it, one level down or several levels down with sublevel.

This guide lists the subdivisions of Bavaria, Germany: its 7 administrative regions (Regierungsbezirke) and its 96 districts (71 Landkreise and 25 kreisfreie Städte), then compares the credits and response size of points and polygons. The examples use Germany because its administrative levels are mapped consistently in OpenStreetMap, the data source of the Boundaries API.

Task flow: region name → place ID → Boundaries API consists-of with sublevel → subdivisions as points or polygons.

Get the place ID of the region

consists-of needs the id of the region. Get it from the Geocoding API, searching by name with a result type:

https://api.geoapify.com/v1/geocode/search?text=Bayern&type=state&lang=de&format=json&limit=1&apiKey=YOUR_API_KEY

Reduced response:

{
  "results": [
    {
      "state": "Bayern",
      "result_type": "state",
      "place_id": "51528f7e45c8ce2640598324a24e2f794840f00101f901f4bb200000000000c0020a92030642617965726e"
    }
  ]
}

Other ways to get an ID:

  • From coordinates: the place_id of any feature returned by the Boundaries API part-of endpoint, for example the Bayern feature for a point in Munich. See How to Get a City Boundary as GeoJSON.
  • From a previous consists-of response: each subdivision has its own place_id, so you can go one level deeper with another request.

Use the place ID as it is; don't build it from an OpenStreetMap ID.

Request the subdivisions

Send the place ID to consists-of. Without other parameters, it returns the direct administrative subdivisions as center points:

https://api.geoapify.com/v1/boundaries/consists-of?id=51528f7e45c8ce2640598324a24e2f794840f00101f901f4bb200000000000c0020a92030642617965726e&apiKey=YOUR_API_KEY

For Bavaria, that is the 7 Regierungsbezirke: Oberbayern, Niederbayern, Oberpfalz, Oberfranken, Mittelfranken, Unterfranken, and Schwaben.

Add sublevel=2 to skip one level and get the subdivisions of the subdivisions:

https://api.geoapify.com/v1/boundaries/consists-of?id=51528f7e45c8ce2640598324a24e2f794840f00101f901f4bb200000000000c0020a92030642617965726e&sublevel=2&apiKey=YOUR_API_KEY

The response has 96 features: 71 Landkreise and 25 kreisfreie Städte, the number the Bavarian State Office for Statistics publishes. More results from the same requests, tested on November 5, 2026:

id of sublevel Features What they are admin_level
Deutschland 1 16 States (Länder) 4
Bayern 1 7 Administrative regions (Regierungsbezirke) 5
Bayern 2 96 Districts (Landkreise and kreisfreie Städte) 6
München 1 25 City districts (Stadtbezirke) 9

Reduced response, one of the 96 districts:

{
  "type": "Feature",
  "properties": {
    "name": "Landkreis Miesbach",
    "county": "Landkreis Miesbach",
    "state": "Bavaria",
    "datasource": {
      "sourcename": "openstreetmap",
      "raw": { "osm_id": 2168231, "admin_level": 6, "ref:nuts:3": "DE21F" }
    },
    "place_id": "514ef0b6a711a627405955cca1678ee14740f00101f901a715210000000000c002099203124c616e646b72656973204d69657362616368"
  },
  "geometry": { "type": "Point", "coordinates": ["…"] }
}

datasource.raw keeps the OpenStreetMap tags of each boundary. admin_level tells you which level a feature is at, and official codes such as ref:nuts:3 (DE21F) let you join the boundaries with statistics. Not every region has the same levels, so check admin_level when a result mixes levels, and keep the place_id of each subdivision for later requests.

Choose points or polygons

geometry decides what each feature contains. The default point returns a center point; geometry_1000, geometry_5000, and geometry_10000 return simplified polygons; the number is the documented accuracy in meters. Polygons cost extra credits and make the response much larger.

Credits are calculated per request: every 20 boundaries returned cost 1 credit, and every polygon adds 1 credit. For the 96 districts of Bavaria (sublevel=2), tested on November 5, 2026:

geometry Credits Response size
point (default) ceil(96 / 20) = 5 about 164 KB
geometry_10000 5 + 96 = 101 about 1.2 MB
geometry_5000 5 + 96 = 101 about 3.7 MB

A practical order:

  1. Request the subdivisions with geometry=point to show a list or let the user pick, for 5 credits.
  2. Request polygons only when you draw or analyze the areas. For a whole state on one screen, geometry_10000 is usually enough and keeps the response small.
  3. Store the result. Administrative boundaries change rarely, so a cached response saves credits on every later view.

The Boundaries API pricing and the Free plan's 3,000 credits per day apply.

Region subdivisions with an AI coding agent

Copy this prompt into Codex, Claude Code, Cursor, or another coding agent to list or draw the subdivisions of a region in your project.

Add region subdivisions to my project with the Geoapify Boundaries API.

Before you start
- Inspect the existing project first. Reuse its current framework, map library, HTTP client, caching, and conventions. Make the smallest necessary changes.
- Ask only what the project does not answer: which region the user starts from, how many levels down it needs, whether the subdivisions are listed or drawn, and whether requests run in a backend or use a restricted browser API key.
- Read the Geoapify API key from the project's environment configuration. Never hardcode, print, or log it.

Place ID
- Get the region's place_id from the Geocoding API (GET https://api.geoapify.com/v1/geocode/search with text, type such as state or city, and format=json), or from a Boundaries API part-of feature.

API request
- GET https://api.geoapify.com/v1/boundaries/consists-of with id, optional sublevel (1 = direct subdivisions, 2 = one level deeper), and geometry.
- Use geometry=point for lists; request polygons (geometry_10000 for a large region) only when drawing or analyzing.
- Credits: ceil(features / 20) plus 1 per polygon. Show the estimate before requesting polygons for large regions, and cache responses.

Result
- Read features[].properties: name, place_id, datasource.raw.admin_level, and official codes in datasource.raw (for example ref:nuts:3) when joining statistics.
- Group or filter by admin_level when a result mixes levels. Keep each subdivision's place_id to go deeper.
- If a map is used, add the FeatureCollection as a GeoJSON source and draw fills and outlines.

Errors
- Show the API message for HTTP 400 responses, retry 429 responses a limited number of times with backoff, and add a test with a mocked response of mixed admin levels.

Review the generated code against this guide. Check the place ID source, the sublevel value, the credit estimate for polygons, and the API-key handling.