# Extract a hosted dataset 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.

A hosted dataset from the TerraLab catalogue cut to an area: a GeoTIFF or a vector file with its licence, or only the statistics.

| | |
| --- | --- |
| REST | `POST https://mcp.terra-lab.ai/v1/tools/extract_dataset` |
| MCP tool | `extract_dataset` on `https://mcp.terra-lab.ai/mcp` |
| Group | Data catalog |

## Request

```bash
curl -X POST https://mcp.terra-lab.ai/v1/tools/extract_dataset \
  -H "Authorization: Bearer $TERRALAB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dataset":"esa_worldcover","area":{"place":"Nakuru, Kenya","radius_m":5000}}'
```

```python
import os
import requests

response = requests.post(
    "https://mcp.terra-lab.ai/v1/tools/extract_dataset",
    headers={"Authorization": f"Bearer {os.environ['TERRALAB_API_KEY']}"},
    json={
        "dataset": "esa_worldcover",
        "area": {
            "place": "Nakuru, Kenya",
            "radius_m": 5000,
        },
    },
    timeout=120,
)
response.raise_for_status()
print(response.json()["structuredContent"])
```

```javascript
const response = await fetch('https://mcp.terra-lab.ai/v1/tools/extract_dataset', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TERRALAB_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "dataset": "esa_worldcover",
    "area": {
      "place": "Nakuru, Kenya",
      "radius_m": 5000
    }
  }),
});
const data = await response.json();
console.log(data.structuredContent);
```

Other valid request bodies:

```json
{"dataset":"esa_worldcover","area":{"place":"Gare de Montpellier Saint-Roch","radius_m":2000},"summary":true}
```

```json
{"dataset":"cod_ab_idn","area":{"place":"Bandung, Indonesia","radius_m":10000},"variables":{"LEVEL":"3"}}
```

## Parameters

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

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `dataset` | string | No | A dataset id from find_datasets, such as "esa_worldcover", "ghs_pop", "cod_ab_idn". Up to 80 characters. |
| `area` | object | No | 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. |
| `variables` | object | No | Values for the dataset's variables, as find_datasets lists them: {"LEVEL": "2"}, {"RETURN_PERIOD": "100"}, {"YEAR": "2015"}. |
| `summary` | boolean | No | Rasters: return the class shares or statistics only, without a file. Default `false`. |
| `formats` | array of string | No | Vectors: extra download formats. A GeoPackage is always included. |

## 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 a dataset from the TerraLab catalogue cut to an area, as a GIS file or as numbers: "ESA WorldCover for 5 km around Nakuru as a GeoTIFF". Give dataset (an id from find_datasets) and area (a place with radius_m, or a bbox). Rasters: a GeoTIFF on the dataset's own grid, licence in the file and in a zip, plus class shares or min, max and mean (summary true: numbers only). Vectors: a GeoPackage (GeoJSON, KML, Shapefile or CSV on request) with the feature count. Limits: 4,000 x 4,000 pixels (8 million for 64-bit data) or 20,000 features per call; a larger area gets area_too_large with a radius that fits, never a partial file. Some datasets need variables (admin level, year, return period): find_datasets lists them. Quote the licence and attribution in the answer. Not for OpenStreetMap or Overture (extract_open_data), elevation (get_elevation) or satellite images (get_satellite_image). Never use the user's current location unless they type it. 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_dataset · Updated 2026-10-27
