API / MCP
Everything on this site comes from a public JSON API, and the same data is available to AI assistants through an MCP server. Both are free to use, need no key, and return the same numbers as the dashboard.
The data returned is © OpenStreetMap contributors, available under the Open Database License (ODbL). If you reuse or republish it, credit OpenStreetMap contributors as that page describes.
REST API
Plain HTTP GET with query parameters, JSON responses. Dates are UTC days
(YYYY-MM-DD, end inclusive); without them, endpoints cover the last 7 days.
- Base URL
/api/- OpenAPI schema
- /api/schema/ (YAML; JSON)
Example: top editors of the last 7 days
curl '/api/changesets/toplist/?dimension=editor'
Full reference below, with a "Try it out" button on every endpoint.
MCP server
A Model Context Protocol server, so an assistant such as Claude can answer questions like "which editors created the most buildings in France last month?" from this data.
- URL
-
/mcp - Transport
- Streamable HTTP (stateless, JSON responses)
- Authentication
- None
Each tool is one REST endpoint, with the same parameters, limits and answers. The tools are listed below.
Connect an assistant
Claude (web, desktop, mobile)
Settings → Connectors → Add custom connector, name it "OSM Monitor" and paste the URL above. Then enable it in a conversation from the tools menu.
Claude Code
claude mcp add --transport http osm-monitor /mcp
Other MCP clients
Most take a JSON entry like this one:
{
"mcpServers": {
"osm-monitor": {
"type": "http",
"url": "/mcp"
}
}
}
Questions to start with: "How many changesets were made last week, and with which editors?", "Which hashtags changed the most objects this month?", "What are the most edited objects in Germany this week?"
MCP tools
Read-only; the parameters and descriptions come from the REST API's reference.
summary
Changeset summary totals
total_changesets, total_objects, and avg_objects for a date range. Defaults to the last 7 days if no dates are given. Same as the REST API's GET /api/changesets/summary/
| Argument | Type | Description |
|---|---|---|
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
timeseries
Changeset volume over time
Time series of changeset volume, optionally split into up to 20 named series via group_by. Bucket width is auto-picked to target ~300 points for the given range (hourly for ranges up to ~12.5 days, daily beyond that) — override with interval=hour|day. interval=hour on a range wide enough to blow past the point budget is rejected (400) rather than silently truncated. The grain actually used is always reported back in the response's top-level interval field. Defaults to the last 7 days if no dates are given. group_by=action|object_type|feature splits objects changed by what the replication diffs say about each object (requires metric=objects; objects count on their changeset's day, so the series add up to the metric=objects total); those diffs only go back a few months, and the response's `objects_since` gives the first day covered (earlier days count nothing). With metric=objects, action/object_type/feature count only the matching objects (also from the diffs), e.g. group_by=contributor&action=modify: who modified the most. Same as the REST API's GET /api/changesets/timeseries/
| Argument | Type | Description |
|---|---|---|
action |
string | Count only the objects created, modified or deleted (from the replication diffs; objects count from `objects_since` only). One of: create, delete, modify |
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
feature |
string | Count only objects of this feature: the object's main tag key as in dimension=feature (building, highway, addr, ...; untagged; unknown for deletes). |
group_by |
string | Split into per-name series: contributor, editor, imagery, language, country, or hashtag (lower-cased; a changeset counts under each of its hashtags). With metric=objects also action (create/modify/delete), object_type (node/way/relation) or feature (the object's main tag key: building, highway, …; untagged; unknown for deletes). Omit for plain volume. One of: action, contributor, country, editor, feature, hashtag, imagery, language, object_type |
imagery |
string | Restrict to one imagery family (case-insensitive). |
interval |
string | Force the bucket width: hour or day. Omit to auto-pick based on range width (see description). One of: day, hour |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
metric |
string | count (changesets, default) or objects (objects changed). With group_by, also what the top 20 are ranked by. One of: count, objects |
object_type |
string | Count only nodes, ways or relations (from the replication diffs). One of: node, relation, way |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
toplist
Top changesets by dimension
Top N (default 20) contributors/editors/imageries/locales/countries/editor-versions/hashtags, ranked by changeset count or by objects changed, for a date range. Defaults to the last 7 days if no dates are given. dimension=editor_version requires an editor filter (created_by is unbounded across all editors, so it is only ever grouped within one already-selected editor family). dimension=action|object_type|feature ranks objects changed by what the replication diffs say about each object (requires metric=objects; the response's `objects_since` gives the first day those diffs cover). With metric=objects, action/object_type/feature count only the matching objects, e.g. dimension=contributor&action=modify (not with editor_version or hashtag). Same as the REST API's GET /api/changesets/toplist/
| Argument | Type | Description |
|---|---|---|
action |
string | Count only the objects created, modified or deleted (from the replication diffs; objects count from `objects_since` only). One of: create, delete, modify |
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
dimension required |
string | One of: contributor, editor, imagery, language, country, editor_version (requires an editor filter), hashtag (lower-cased; a changeset counts under each of its hashtags); with metric=objects also action (create/modify/delete), object_type (node/way/relation), feature (the object's main tag key; untagged; unknown for deletes). One of: action, contributor, country, editor, editor_version, feature, hashtag, imagery, language, object_type |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
feature |
string | Count only objects of this feature: the object's main tag key as in dimension=feature (building, highway, addr, ...; untagged; unknown for deletes). |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
limit |
integer | Number of results (default 20, max 1000). |
metric |
string | count (changesets) or objects (objects changed). Defaults to count. One of: count, objects |
object_type |
string | Count only nodes, ways or relations (from the replication diffs). One of: node, relation, way |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
size_distribution
Changeset size distribution
Histogram of changeset sizes (objects changed per changeset) in roughly logarithmic buckets, with changeset and object totals per bucket; exact p50/p90/p99/max sizes; and `top_1pct_objects_share`, the share of all objects changed by the largest 1% of changesets. Percentile = smallest size whose cumulative changeset count reaches that fraction. Defaults to the last 7 days if no dates are given. Same as the REST API's GET /api/changesets/distribution/
| Argument | Type | Description |
|---|---|---|
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
size_by_group
Changeset size by group
Exact p25/p50/p75/p90/p95 changeset sizes (objects changed per changeset), plus changeset and object totals, per group. by=contributor|editor|imagery|language|country returns the top N names by changeset count (untagged changesets left out); by=day returns every day of the range, in order. Defaults to the last 7 days if no dates are given. Same as the REST API's GET /api/changesets/distribution/breakdown/
| Argument | Type | Description |
|---|---|---|
by required |
string | One of: contributor, editor, imagery, language, country, day. One of: contributor, country, day, editor, imagery, language |
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
limit |
integer | Number of names for a dimension (default 10, max 50); ignored for day. |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
largest_changesets
Largest changesets
The N largest changesets of the range, by=objects (objects changed, default) or by=area (bounding box area in km², on a spherical Earth; changesets without a bbox left out). Ties are broken newest first. Defaults to the last 7 days if no dates are given. With by=objects, action/object_type/feature rank changesets by their matching objects only (from the replication diffs, from `objects_since`), given in each result's `objects` next to its whole `changes_count`. Same as the REST API's GET /api/changesets/largest/
| Argument | Type | Description |
|---|---|---|
action |
string | Count only the objects created, modified or deleted (from the replication diffs; objects count from `objects_since` only). One of: create, delete, modify |
by |
string | objects (default) or area. One of: area, objects |
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
feature |
string | Count only objects of this feature: the object's main tag key as in dimension=feature (building, highway, addr, ...; untagged; unknown for deletes). |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
limit |
integer | Number of changesets (default 20, max 100). |
object_type |
string | Count only nodes, ways or relations (from the replication diffs). One of: node, relation, way |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
map_cells
Changeset density by grid cell
Changeset count and objects-changed, bucketed into geohash-derived grid cells (see `lat_size_degrees`/`lon_size_degrees` in the response; each cell's `cell` is its geohash, usable with /api/changesets/geo/cell/), for a date range. Defaults to the last 7 days if no dates are given. resolution=fine requires `bbox` (the viewport to scope cells to) and returns a finer grid than the default resolution=coarse. Changesets with an unreliably large bounding box (see the view docstring) are excluded from `cells`. Same as the REST API's GET /api/changesets/geo/
| Argument | Type | Description |
|---|---|---|
bbox |
string | Viewport as "min_lon,min_lat,max_lon,max_lat". Required when resolution=fine. |
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
resolution |
string | coarse (default, global) or fine (requires bbox below). One of: coarse, fine |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
map_cell_changesets
Changesets in a map cell
Changesets of one /api/changesets/geo/ cell (a changeset belongs to the cell containing its bounding-box center, like the map counts), newest first, paginated with limit/offset; `has_more` says whether another page exists. Same filters and date range as /geo/, so the cell's `count` there is this list's total. Defaults to the last 7 days if no dates are given. Same as the REST API's GET /api/changesets/geo/cell/
| Argument | Type | Description |
|---|---|---|
cell required |
string | The cell's geohash (1-12 characters), as returned in /geo/'s `cell`. |
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
end_date |
string | Range end: a day (YYYY-MM-DD), included, or a timestamp, excluded: start_date=2026-10-09T11:00:00Z&end_date=2026-10-09T12:00:00Z is one hour, e.g. one point of an hourly timeseries. Defaults to today. Ranges that are not whole UTC days read raw data, so they suit short windows. |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
limit |
integer | Page size (default 50, max 200). |
offset |
integer | Changesets to skip (default 0). |
start_date |
string | Range start: a day (YYYY-MM-DD) or an ISO 8601 timestamp (UTC unless an offset is given), e.g. 2026-10-09T11:00:00Z. Defaults to 7 days before end_date. |
most_edited_objects
Most edited objects, last 7 days
The objects with the most edits over the last 7 days up to now (a fixed window: start_date/end_date are ignored), ranked by edits, ties by type and id. An edit is an object version after the first (a modify or a delete), from the replication diffs. The dimension filters apply to each edit's changeset. Per object: edits, distinct contributors and changesets, the last edit, the latest version, and its latest name tag ('' if none). Same as the REST API's GET /api/objects/most-edited/
| Argument | Type | Description |
|---|---|---|
contributor |
string | Restrict to one OSM username (case-insensitive). |
country |
string | Restrict to one country (ISO 3166-1 alpha-2, e.g. "FR"; case-insensitive), derived from the changeset's centroid. |
editor |
string | Restrict to one editor family (case-insensitive). |
imagery |
string | Restrict to one imagery family (case-insensitive). |
language |
string | Restrict to one language/locale, as recorded in the changeset (case-insensitive). |
limit |
integer | Number of objects (default 20, max 100). |
list_changesets
List changesets
Paginated list of ingested changeset records, newest first, with optional filters. Always bounded by a date range — defaults to the last 24 hours if start_date/end_date are omitted (there's no unfiltered "everything" mode; use /api/changesets/timeseries/, /summary/, or /toplist/ for aggregate questions over a large range). Same as the REST API's GET /api/changesets/
| Argument | Type | Description |
|---|---|---|
bbox |
string | Bounding box filter as "min_lon,min_lat,max_lon,max_lat". |
editor |
string | Exact editor family (e.g. "StreetComplete", "iD"). |
end_date |
string | Only changesets created on/before this day (YYYY-MM-DD, the whole day included) or before this timestamp (excluded). Defaults to now. |
hashtag |
string | Hashtag the changeset must include (from its #hashtags tag). |
imagery_family |
string | Normalised imagery family (case-insensitive), e.g. "Bing". |
imagery_raw |
string | Exact raw imagery string as found in the changeset's imagery_used tag. |
page |
integer | Page number. |
page_size |
integer | Results per page (default 100, max 1000). |
start_date |
string | Only changesets created on/after this day (YYYY-MM-DD) or timestamp (ISO 8601, UTC unless an offset is given). Defaults to 24 hours before now. |
user |
string | Exact OSM username. |
autocomplete
Autocomplete filter values
Up to 10 distinct known values for a filter field, matching a partial query — backs the dashboard's filter inputs. Same as the REST API's GET /api/autocomplete/
| Argument | Type | Description |
|---|---|---|
field required |
string | One of: contributor, editor, imagery, language, country. One of: contributor, country, editor, imagery, language |
q |
string | Partial value to match (case-insensitive, substring). |