Guide

Overpass history queries: [date:], [diff:] and [adiff:]

Query OpenStreetMap as it was on a past date, or the changes between two dates, with the Overpass API.

Put [date:"2015-01-01T00:00:00Z"] in the settings block to run a query on the data of that day. [diff:"A","B"] returns what changed between two dates, and [adiff:"A","B"] returns the old and the new version of each change. The history starts on 12 September 2012. Diffs come as XML only. On overpass.ch, history queries are part of the Medium and Large plans.

The map at a past date

The cafés of central Zurich on 1 January 2015:

[out:json][date:"2015-01-01T00:00:00Z"];
nw(47.365,8.535,47.380,8.555)(if:t["amenity"]=="cafe");
out center;

The answer has 52 cafés; the same query without [date:] finds 116 today. It took 1.1 seconds. Everything after the settings block runs on the data of that date: tags, positions, the nodes of a way. Add out meta to see the version of each element, when it was made and by whom.

Changes between two dates

[diff:"START","END"] runs the query on both dates and returns one <action> for each element that differs: create for one that matches only at the end, delete for one that matches only at the start, modify for one that matches on both dates in another version. [adiff:] returns the same actions with the old and the new version of each element, so you can see what changed and whether a deleted element is gone from the map. Two actions from the restaurants of the Niederdorf in Zurich, from 2023 to 2025:

[out:xml][adiff:"2023-01-01T00:00:00Z","2025-01-01T00:00:00Z"];
nw(47.369,8.541,47.376,8.547)(if:t["amenity"]=="restaurant");
out meta center;
<action type="delete">
<old>
  <node id="955074361" lat="47.3743872" lon="8.5434905" version="5" timestamp="2017-09-16T14:12:10Z" user="mllr" …>
    <tag k="amenity" v="restaurant"/>
    <tag k="name" v="Kormasutra"/>
  </node>
</old>
<new>
  <node id="955074361" visible="false" version="7" timestamp="2023-04-24T19:55:28Z" user="paulbrunner" …/>
</new>
</action>
<action type="delete">
<old>
  <node id="343391110" lat="47.3731698" lon="8.5448295" version="8" timestamp="2017-12-15T13:43:01Z" user="d_berger" …>
    <tag k="amenity" v="restaurant"/>
    <tag k="name" v="Isebähnli"/>
  </node>
</old>
<new>
  <node id="343391110" visible="true" version="10" timestamp="2024-04-28T15:47:07Z" user="casperonbike" …/>
</new>
</action>

Both are deletions for the query. Kormasutra has visible="false": the node was deleted in April 2023. Isebähnli has visible="true": the node is still there, but no longer a restaurant. A version that does not match the query comes without tags; ask for it by id with [date:] to see what it became, here a bar. OpenStreetMap changes in an area reads such an answer in Python.

From 12 September 2012

The history begins with the data of 12 September 2012, when OpenStreetMap changed its licence. A date before that returns only the elements that nobody edited between that date and September 2012. The cafés of the box above:

DateCafés
1 January 20080
1 January 20109
13 September 201250
1 January 201552
1 January 202085
today116

Answers for dates from 13 September 2012 on are complete.

Versions of one element

timeline(node, 26863664); lists the versions of an element, and retro (date) { … } runs statements on another date inside a query. Together they give every version of an object: see version history of an OpenStreetMap object.

Good to know

  • [out:json] and [out:csv] cannot hold a diff. Overpass answers static error: The selected output format does not support the diff or adiff mode: see that error.
  • [adiff:] reports some elements that start to match the query as modify with an old version without tags; [diff:] reports the same elements as create. For the restaurants above, [diff:] has 8 create actions and [adiff:] 5.
  • Tag filters in square brackets are slow at a past date. ["amenity"="cafe"] took 3.7 seconds for the cafés above, (if:t["amenity"]=="cafe") 1.1 seconds for the same answer.
  • Area filters such as area["name"="Zürich"] use the boundary of today, also at a past date.
  • Relations at a past date are slow: the 27 relations of a box of 200 × 300 m took 26 seconds. Ask for nodes and ways when you can.
  • An answer for two dates in the past never changes. Store it instead of asking again.

On overpass.ch

The Medium and Large plans run history queries on the full planet; a query on a small area takes 1 to 2 seconds. Other plans get HTTP 403 history_not_in_plan. The history examples run each kind of query live, with its result on a map and in a table.

https://overpass-api.de/api/interpreter
→ https://api.overpass.ch/v1/YOUR_API_KEY/interpreter