Gespeicherte Abfragen und Änderungsalarme

Speichern Sie eine Overpass-Abfrage unter einem Namen. Wir führen sie nach Zeitplan aus und bewahren das letzte Ergebnis auf. Jede gespeicherte Abfrage hat eine URL, die dieses Ergebnis liefert, und Sie können eine E-Mail oder einen Webhook-Aufruf erhalten, wenn sich das Ergebnis ändert. Verfügbar im Tarif Medium (20 gespeicherte Abfragen) und im Tarif Large (100).

Einmal ausführen, viele Male lesen

Alle Ladestationen Deutschlands, mit Tags und Mittelpunkt:

[out:json][timeout:300];
area["ISO3166-1"="DE"][admin_level=2]->.c;
nwr["amenity"="charging_station"](area.c);
out center tags;

Über den Interpreter dauert diese Abfrage rund eine Minute und liefert 47 000 Elemente, 19 MB. Speichern Sie sie als ladestationen-de mit täglichem Lauf, dann dauert das Lesen des gespeicherten Ergebnisses 0,15 s, mit gzip 25 ms (2,6 MB). Gemessen im Tarif Medium am 29. Oktober 2026:

ZeitGrösseZählt als
POST /v1/KEY/interpreter60 s19 MBeine Anfrage, und die Abfrage läuft jedes Mal
GET /v1/KEY/q/ladestationen-de0,15 s19 MBeine Anfrage; die Abfrage läuft nicht
dasselbe mit gzip0,025 s2,6 MB

Würden 1000 Nutzer diese Abfrage je einmal auslösen, wären das bis zu 1000 Minuten Abfragezeit, und jeder Nutzer würde auf seinen eigenen Lauf warten. Mit einer gespeicherten Abfrage läuft die Abfrage einmal pro geplantem Lauf, und die Nutzer lesen das gespeicherte Ergebnis.

Das kostet keine zusätzlichen Anfragen. Ein Lesen zählt als eine Anfrage, genau wie das Senden der Abfrage selbst; der geplante Lauf kommt mit einer Anfrage pro Lauf dazu. Der Unterschied ist die Geschwindigkeit: Ein Lesen liefert das gespeicherte Ergebnis sofort, die Abfrage selbst läuft nicht noch einmal.

Wofür

  • Eine App oder Website, die vielen Nutzern dieselben Daten zeigt, etwa alle Ladestationen einer Stadt. Die Abfrage läuft einmal pro Zeitplan; jeder Nutzer liest das gespeicherte Ergebnis.
  • Abfragen, die Minuten dauern, etwa ein landesweiter Auszug. Clients lesen das letzte erfolgreiche Ergebnis; sie warten nicht auf einen Lauf.
  • Änderungen auf OpenStreetMap beobachten: eine Filialliste, die aktuell bleiben muss, eine Region, die ein Mapper betreut, ein Tag, das eine Datenpipeline verwendet. Werden Elemente hinzugefügt, entfernt oder bearbeitet, erhalten Sie eine E-Mail oder einen Webhook-Aufruf, der sie nennt.

Eine Abfrage speichern

Öffnen Sie Gespeicherte Abfragen im Dashboard und geben Sie ein:

  • Einen Namen, der in der Ergebnis-URL steht: Kleinbuchstaben, Ziffern und Bindestriche, etwa ladestationen.
  • Die Abfrage, so wie Sie sie an den Interpreter schicken würden. Mit [out:json] können die Alarme die Elemente nennen; XML und CSV gehen auch, dann sagt ein Alarm nur, dass sich das Ergebnis geändert hat.
  • Den Zeitplan: stündlich, alle 6 Stunden, täglich, wöchentlich oder nur, wenn Sie Jetzt ausführen drücken.
  • Ob Sie bei einer Änderung eine E-Mail möchten, und eine Webhook-URL.

Der erste Lauf beginnt innert einer Minute nach dem Speichern. Wird die Abfrage bearbeitet, beginnt sofort ein neuer Lauf. Ein Lauf verwendet einen Schlüssel Ihres Kontos, zählt als eine Anfrage Ihres Tarifs und hält dessen Limits ein (Abfragedauer, Speicher). Ergebnisse dürfen bis 32 MB gross sein. Schlägt ein Lauf fehl, bleibt das vorherige erfolgreiche Ergebnis verfügbar, und das Dashboard zeigt den Fehler.

Das Ergebnis lesen

curl https://api.overpass.ch/v1/IHR_API_SCHLÜSSEL/q/ladestationen

Das Ergebnis hat das Ausgabeformat, das in der Abfrage steht ([out:json], [out:csv], XML). Die Antwort trägt den Header X-Saved-Query-Run mit der Zeit des Laufs, ein ETag für If-None-Match und gzip, wenn der Client es annimmt. Jedes Lesen zählt als eine Anfrage, genau wie die Abfrage selbst, und unterliegt dem Minutenlimit Ihres Tarifs. Ein Schlüssel vom Typ «Nur Karten» kann gespeicherte Abfragen nicht lesen.

In JavaScript:

const r = await fetch("https://api.overpass.ch/v1/IHR_API_SCHLÜSSEL/q/ladestationen");
const data = await r.json();
console.log(data.elements.length, "Stationen, Daten vom", r.headers.get("X-Saved-Query-Run"));

Fehlerantworten: 404 not_found für einen Namen, den Sie nicht gespeichert haben, 503 no_answer_yet, solange noch kein Lauf erfolgreich war (das Dashboard zeigt den Fehler eines fehlgeschlagenen Laufs), 403 no_saved_queries in einem Tarif ohne gespeicherte Abfragen.

Änderungsalarme

Nach jedem Lauf vergleichen wir das neue Ergebnis mit dem vorherigen. Bei JSON-Ergebnissen melden wir die Elemente, die hinzugefügt, entfernt oder geändert wurden; ein Element gilt als geändert, wenn sich seine Tags oder seine Geometrie unterscheiden. Bei XML- und CSV-Ergebnissen vergleichen wir die ganze Ausgabe ohne die Zeile mit dem Zeitstempel und melden nur, dass sie sich geändert hat.

Die E-Mail nennt bis 100 Elemente jeder Art mit Namen und Links zu openstreetmap.org. Der Webhook ist ein POST mit diesem JSON:

{
  "event": "query.changed",
  "query": "ladestationen",
  "title": "Ladestationen in Zürich",
  "run_at": "2026-10-29T06:00:12Z",
  "elements": 418,
  "added": [{"type": "node", "id": 11860345120, "name": "Migrol"}],
  "removed": [],
  "changed": [{"type": "way", "id": 1066552231, "name": "Parkhaus Urania"}],
  "added_count": 1, "removed_count": 0, "changed_count": 1,
  "summary": "1 added, 1 changed, 418 in all",
  "answer": "https://api.overpass.ch/v1/YOUR_API_KEY/q/ladestationen",
  "dashboard": "https://overpass.ch/dashboard/queries/12"
}

Der Aufruf trägt die Header X-Overpass-Event: query.changed und X-Overpass-Signature: sha256=…. Die Signatur ist der HMAC-SHA256 des Inhalts mit dem Geheimnis, das auf der Seite der Abfrage steht. Prüfen Sie sie, bevor Sie einem Aufruf trauen:

# Python (Flask)
import hmac, hashlib
def verify(request, secret):
    want = "sha256=" + hmac.new(secret.encode(), request.get_data(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(want, request.headers.get("X-Overpass-Signature", ""))
// Node (Express, mit express.raw())
const crypto = require("crypto");
function verify(req, secret) {
  const want = "sha256=" + crypto.createHmac("sha256", secret).update(req.body).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(req.get("X-Overpass-Signature") || ""));
}

Zustellung: ein Aufruf pro erkannter Änderung, mit 10 Sekunden Timeout, ohne Weiterleitungen und nur an öffentliche IP-Adressen. Ein fehlgeschlagener Aufruf wird nicht wiederholt; diese Änderung geht für den Webhook verloren, wenn Ihr Endpunkt nicht erreichbar ist. Die nächste erkannte Änderung wird als neuer Aufruf zugestellt. Die Seite der Abfrage zeigt den Status der letzten Zustellung.

Beispiele

Ladestationen einer Stadt, für eine App

Läuft täglich. Die App liest die Ergebnis-URL; der Alarm meldet Stationen, die auf der Karte hinzukommen oder wegfallen.

[out:json][timeout:60];
area["name"="Zürich"]["admin_level"="8"]->.a;
nwr["amenity"="charging_station"](area.a);
out center tags;

Die Filialen einer Marke beobachten

Läuft wöchentlich. Wird auf OpenStreetMap eine Filiale hinzugefügt oder entfernt, schickt der Webhook das Element an Ihr System.

[out:json][timeout:120];
nwr["brand:wikidata"="Q115241"]["shop"];
out center tags;

fixme-Tags in einer Region beobachten

Läuft alle 6 Stunden über die Region, die ein Mapper betreut. Neue oder bearbeitete fixme-Hinweise kommen per E-Mail mit Links zu den Elementen.

[out:json][timeout:60];
nwr[~"^fixme$"~"."](47.30,8.40,47.45,8.65);
out center tags;

Einen grossen Auszug lesen, ohne die Abfrage auszuführen

Eine landesweite Abfrage, die Minuten dauert, läuft täglich im Tarif Large. Clients lesen das gespeicherte Ergebnis.

[out:csv(::id, name, "addr:city", website)][timeout:600][maxsize:1073741824];
area["ISO3166-1"="CH"][admin_level=2]->.c;
nwr["amenity"="pharmacy"](area.c);
out;

Limits

  • Medium behält 20 gespeicherte Abfragen, Large 100. Jede läuft höchstens einmal pro Stunde.
  • Ein Lauf zählt als eine Anfrage Ihres Tarifs und läuft mit dessen Abfragedauer und Speicher. Ein fehlgeschlagener Lauf (Timeout, Fehler, Ergebnis über 32 MB) behält das vorherige Ergebnis und zeigt den Fehler auf der Seite der Abfrage.
  • Das Konto braucht einen aktiven Schlüssel vom Typ «Alle APIs», erstellt auf der Website; die Läufe verwenden ihn.
  • Jedes Lesen eines Ergebnisses zählt als eine Anfrage, genau wie das Senden der Abfrage, und unterliegt dem Minutenlimit Ihres Tarifs. Die Funktion kostet keine zusätzlichen Anfragen; sie spart die Abfragezeit.