# Extract open map data for an area

> Index of the TerraLab docs for agents: [llms.txt](https://terra-lab.ai/docs/llms.txt). Every docs page is also served as markdown: add .md to its URL.

OpenStreetMap and Overture layers for any area: buildings, roads, addresses, points of interest, land use, water and more, as GIS files.

| | |
| --- | --- |
| REST | `POST https://mcp.terra-lab.ai/v1/tools/extract_open_data` |
| MCP tool | `extract_open_data` on `https://mcp.terra-lab.ai/mcp` |
| Group | Map data |

## Request

```bash
curl -X POST https://mcp.terra-lab.ai/v1/tools/extract_open_data \
  -H "Authorization: Bearer $TERRALAB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"theme":"buildings","area":{"bbox":[2.34,48.857,2.343,48.859]},"formats":["shapefile"]}'
```

```python
import os
import requests

response = requests.post(
    "https://mcp.terra-lab.ai/v1/tools/extract_open_data",
    headers={"Authorization": f"Bearer {os.environ['TERRALAB_API_KEY']}"},
    json={
        "theme": "buildings",
        "area": {
            "bbox": [2.34, 48.857, 2.343, 48.859],
        },
        "formats": ["shapefile"],
    },
    timeout=120,
)
response.raise_for_status()
print(response.json()["structuredContent"])
```

```javascript
const response = await fetch('https://mcp.terra-lab.ai/v1/tools/extract_open_data', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TERRALAB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "theme": "buildings",
    "area": {
      "bbox": [
        2.34,
        48.857,
        2.343,
        48.859
      ]
    },
    "formats": [
      "shapefile"
    ]
  }),
});
const data = await response.json();
console.log(data.structuredContent);
```

Other valid request bodies:

```json
{"theme":"pois","area":{"place":"Annecy","radius_m":500},"kind":"pharmacy"}
```

```json
{"theme":"divisions","area":{"place":"Bretagne, France"},"level":"county","formats":["shapefile"]}
```

## Parameters

A JSON object in the request body; in an MCP client, the arguments of the tool call.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `theme` | string | Yes | The data layer. One of `"buildings"`, `"places"`, `"roads"`, `"addresses"`, `"divisions"`, `"landuse"`, `"pois"`, `"waterways"`, `"water_areas"`, `"power"`, `"boundaries"`, `"railways"`, `"routes"`, `"transit_stops"`, `"protected_areas"`. |
| `area` | object | Yes | The area: a bbox, or a place (name, address or coordinates) with an optional radius in metres. The place the user asks about, not the user's own location. |
| `area.bbox` | array of number | No | [west, south, east, north] in decimal degrees (WGS 84). Exactly 4 items. |
| `area.place` | string or object | No | A place name or address, or a point. |
| `area.radius_m` | number | No | Radius around the place in metres. From 1 to 100000. |
| `formats` | array of string | No | Download formats. A GeoPackage is always included. Default `["geojson"]`. |
| `level` | string | No | For the divisions theme: the administrative level to keep. region = French région, US state, German Land; county = French département, US county; municipality = commune, town or city. With a named place, a division of that name at this level is returned alone, and lower levels are kept only inside the named place ("the departments of Brittany": place Brittany, level county). One of `"country"`, `"region"`, `"county"`, `"municipality"`. |
| `kind` | string or array of string | No | Keep only some kinds of feature, matched against their OpenStreetMap tag value in English: pharmacy, school, supermarket, restaurant, hospital, farmland, forest, vineyard. One kind, or several in one call (["forest", "meadow", "grass"]). Leave out for all of the theme. |

## Response

`structuredContent` holds the result, `content` the same result as text for a model, and `isError` is `true` when the tool refused the request or failed; then `structuredContent.code`, `message` and `hint` say what to change.

```json
{
  "structuredContent": {
    "sources": [{ "name": "...", "licence": "...", "url": "..." }],
    "downloads": [{ "label": "...", "format": "...", "url": "...", "name": "..." }]
  },
  "content": [{ "type": "text", "text": "..." }],
  "isError": false
}
```

Every result lists its `sources` with their licence. File results come as `downloads`: each link builds its file when opened.

## Errors

A missing key answers `401`, an empty balance `402`, too many calls `429`. A call that fails or finds nothing is not counted. See [Errors and rate limits](https://terra-lab.ai/docs/errors).

## Description for agents

The text the server gives an agent to decide when to call this tool:

> Use this when the user wants map data or GIS layers for a place or an area anywhere in the world, such as the data of a city, a town, a neighbourhood or a site: buildings, roads, addresses, points of interest (shops, schools, pharmacies), land use, waterways, water areas, railways, transit stops, power lines, protected areas, administrative divisions and boundaries, places or routes. The area is a place, a place with a radius, or a bbox. Returns the count, sample attributes, a map and a GIS file (GeoJSON, KML, Shapefile zip or CSV) with its licence. One extract holds at most 20,000 features: for a town centre use a radius of about 1 km, for dense cities less. For one kind of place (pharmacies, schools, supermarkets) or land (forest, vineyards), set kind: the limit then counts that kind only, so a whole city usually fits. For administrative boundaries (a commune, the departments of a region, a country) use divisions with level and the place name, without a radius. One theme per call: extract the layers the user asks for; when they ask for the data of a place without naming a layer, or what data exists for a project, name the useful themes and let them choose before extracting several. Data: Overture Maps and OpenStreetMap. Never use the user's current location unless they type it. Give the place as the user names it (place name, address or coordinates): this tool locates it, so find_places is not needed first. Download links build their file when opened; no file is saved. Never pass these links to open_gis_file: list every format the user needs in formats, in this one call.


Source: https://terra-lab.ai/docs/api/extract_open_data · Updated 2026-10-27
