API-Dokumentation osm.meyer-edv.cloud
Stand: 13.09.2026. Vollständige Referenz aller Endpunkte. Interaktive Kurzfassung mit Code-Beispielen: https://osm.meyer-edv.cloud/docs/
Grundlagen
Basis-URL ist https://osm.meyer-edv.cloud; Port 80 leitet dauerhaft auf HTTPS um. Alle
JSON-Endpunkte antworten in UTF-8, CORS ist für alle Origins offen. Ein API-Token ist derzeit
optional: Wird eines mitgegeben — als Header X-API-Token: osm_… oder als Query-Parameter
?token=osm_… — zählt der Server den Aufruf für Statistik und Abrechnung; ein ungültiges oder
deaktiviertes Token wird mit 401 abgelehnt, ganz ohne Token wird bedient, aber nicht gezählt.
Fehlgeschlagene Aufrufe (4xx/5xx) werden nie berechnet. Die drei Abrechnungsklassen sind
Navigation (/api/route), Entfernungsabfrage (/api/geocode, /api/reverse, /api/buildings)
und Kartenaufruf (/api/tile/…, /api/offline); die Preise je Klasse pflegt der Admin-Bereich.
Die direkt per Nginx durchgereichten Endpunkte /api/overpass und /api/elevation nehmen ein
Token entgegen, werten es aber nicht aus und tauchen nicht in der Zählung auf.
Kartenkacheln
GET /api/tile/{z}/{x}/{y}.png liefert eine 256×256-Rasterkachel (png256) im üblichen
Slippy-Map-Schema; z läuft von 0 bis 20. Abdeckung: ganz Europa. Eine noch nie angeforderte
Kachel beantwortet der Server zunächst mit 404 und stößt das Rendering im Hintergrund an — der
nächste Aufruf (nach Sekunden, bei niedrigen Zoomstufen auch länger) liefert das fertige PNG;
Clients wie Leaflet machen das automatisch richtig. Wer die Token-Zählung nicht braucht, kann
kacheln auch direkt über GET /tile/{z}/{x}/{y}.png beziehen (identischer Inhalt, ohne Zählung).
In Leaflet genügt L.tileLayer('https://osm.meyer-edv.cloud/api/tile/{z}/{x}/{y}.png', {maxZoom: 20}).
Geocoding
GET /api/geocode?q=<Text>&limit=<n>&lang=<de|en|fr|it> sucht weltweit nach Adressen, Orten und
POIs. q ist Pflicht, limit (Standard 5, Obergrenze 50) und lang (Standard en) sind optional.
Die Antwort ist {"results":[…]}; jedes Ergebnis enthält lat, lon, ein zusammengesetztes
display_name, type, osm_type, osm_id sowie unter properties alle Photon-Rohfelder
(street, housenumber, postcode, city, state, country …). Ohne q kommt 400. Wer das rohe
Photon-Format (GeoJSON) bevorzugt, nutzt den Durchgriff GET /photon/api?q=…&limit=…&lang=… —
das verwendet auch das Autocomplete der Web-Oberfläche.
GET /api/reverse?lat=<lat>&lon=<lon>&lang=<…> macht aus Koordinaten eine Adresse. lat und
lon sind Pflicht (sonst 400). Die Antwort ist ein flaches Objekt mit lat, lon, address,
street, housenumber, postcode, city, state, country und display_name; findet Photon
nichts, ist address null. Rohzugriff analog über GET /photon/reverse?lat=…&lon=….
Routing
POST /api/route (Content-Type application/json) berechnet eine Route. Der Body enthält from
und to als [lat, lon]-Arrays sowie wahlweise das Legacy-Feld mode ("car", "bicycle",
"pedestrian") oder — empfohlen — ein vehicle-Objekt mit einem von 19 Fahrzeugprofilen:
pedestrian, bicycle, cargo_bicycle, epac_25, speed_pedelec, e_kickscooter,
moped_l1e_b, motorcycle, light_quadricycle, heavy_quadricycle, mobility_device,
agricultural_vehicle, car_m1, car_with_trailer, van_n1, truck_3_5_7_5, truck_7_5_12,
truck_n3, bus_m2_m3. Für Lkw, Bus, Nutzfahrzeug und Gespann können je Anfrage konkrete
Fahrzeugwerte mitgegeben werden, die gegen die realen Streckenbeschränkungen (Brückenhöhen,
Gewichts- und Achslastgrenzen, Gefahrgut-Tunnelverbote) geprüft werden: height_m (1–4,5),
width_m (0,5–3), length_m (1–25,25), weight_t (0,05–60), axle_load_t (0,5–12),
axle_count (2–10), hazmat (bool), has_trailer plus trailer_mass_t (wird dem Gewicht
zugeschlagen; Maße bitte als Gespann-Gesamtwerte angeben) sowie top_speed_kmh (10–130) für
Klassen mit Geschwindigkeitsbezug. Für niederländische E-Steps existiert zusätzlich
type_approved: true (RDW-Whitelist-Bestätigung).
Beispiel:
{"from":[52.52,13.40], "to":[48.14,11.58],
"vehicle":{"profile":"truck_7_5_12","height_m":3.8,"weight_t":11.2,"hazmat":false}}
Die Antwort enthält distance (km), duration (Sekunden), geometry als Polylinie aus
[lat,lon]-Paaren (direkt in Leaflet/MapLibre zeichenbar), instructions (je Manöver
instruction, distance, time, type, street_names), summary sowie einen legal-Block:
Profil und Label, EU-Fahrzeugklasse, engine_support ("native" oder "approximation" mit
Begründung), die per Start/Ziel ermittelten Länder (grenznah approximativ), der
Verifikationsstatus (PRIMARY_SOURCE_VERIFIED, GOOD_NATIONAL_SOURCE, COMMISSION_COMPARISON,
LEGAL_STATUS_UNKNOWN), die angewandten Regeln mit Quelle (z. B. "eKFV §10; StVO §18"),
Mindestalter-, Versicherungs- und Helmangaben, Warnungen und ein Haftungshinweis.
Fehlerfälle: 400 bei fehlerhaftem Body oder unbekanntem Profil, 404 wenn keine Route existiert,
422 wenn die Rechtsprüfung blockiert — für rechtlich kritische Klassen (E-Tretroller, S-Pedelec,
Mobility Device, L7e) wird ein unbekannter Rechtsstatus nie als Erlaubnis behandelt (Beispiele:
privater E-Scooter in GB, E-Scooter in Litauen, NL-E-Step ohne type_approved) —, 502 wenn die
Routing-Engine nicht erreichbar ist. Abdeckung derzeit: Deutschland (Europa in Arbeit).
GET /api/vehicles liefert die vollständige Profilliste maschinenlesbar: je Profil label,
category, eu_class, engine_support, approximation_note, accepts_dimensions,
dimension_defaults, legally_critical — gedacht für Apps, die die Fahrzeugauswahl dynamisch
aufbauen. Der native Valhalla-Durchgriff bleibt unter /valhalla/… verfügbar (z. B.
POST /valhalla/route im Valhalla-JSON-Format).
Höhendaten
GET /api/elevation?locations=lat,lon|lat,lon|… liefert Geländehöhen aus dem
Copernicus-GLO-30-Modell (30-m-Raster), Abdeckung ganz Deutschland, bis 500 Punkte je Anfrage,
Punkte durch | getrennt. Antwort im opentopodata-Format:
{"results":[{"dataset":"copernicus30","elevation":31.5,"location":{"lat":53.95,"lng":12.245}}],"status":"OK"}.
Punkte außerhalb der Abdeckung erhalten elevation: null. Die Latenz liegt bei etwa 1,4 ms je
Position im Batch (500 Punkte über HTTPS in ~0,73 s); der Dienst ist damit für hochfrequente
Strecken- und Geländeabfragen ausgelegt.
OSM-Rohdaten (Overpass)
GET /api/overpass?data=<Overpass-QL> (POST mit demselben Parameter funktioniert ebenfalls)
führt vollständige Overpass-QL-Abfragen aus — Seeufer, Wälder, Felder, Gebäude, Nebenstraßen,
Haltestellen, Ortsnamen. Timeout 300 s, Body-Limit 4 MB. Für JSON-Antworten [out:json] in die
Abfrage aufnehmen. Beispiel:
curl -G --data-urlencode 'data=[out:json];way(23569785);out geom;' https://osm.meyer-edv.cloud/api/overpass.
Datenbestand derzeit Mecklenburg-Vorpommern mit täglichen Aktualisierungen; auf ganz Deutschland
erweiterbar.
Offline-Karten (MBTiles)
GET /api/offline/estimate?bbox=minlon,minlat,maxlon,maxlat&minzoom=<z>&maxzoom=<z> schätzt vor
dem Download: Antwort {tiles, est_bytes, est_mb, max_tiles, exceeds_limit}.
GET /api/offline?bbox=…&minzoom=…&maxzoom=…&name=<name> liefert die Region als
.mbtiles-Datei (SQLite, application/x-sqlite3, Content-Disposition attachment) — direkt nutzbar
in MapLibre, Leaflet.Offline, mobilen SDKs und OsmAnd. minzoom Standard 0, maxzoom Standard 12
(erlaubt 0–20), name wird Datei- und Layername. Obergrenze 200.000 Kacheln je Download (sonst
413 mit Angabe der Kachelzahl); die Header X-Tiles-Stored und X-Tiles-Requested melden, wie
viele Kacheln enthalten sind. Noch nicht gerenderte Kacheln werden während des Exports live
erzeugt (mit interner Warte-Wiederholung) — große Detail-Gebiete auf kaltem Cache dauern
entsprechend; vorgerenderte Bereiche exportieren schnell. Empfehlung: Übersicht (z0–11)
großflächig, Detailzooms (z12–16) nur für die tatsächlich benötigten Städte.
Gebäudegrundrisse
GET /api/buildings?bbox=minlon,minlat,maxlon,maxlat[&limit=…][&simplify=<m>] liefert
Gebäudepolygone als GeoJSON-FeatureCollection (Content-Type application/geo+json) direkt aus der
Europa-Datenbank (~248 Mio. Gebäude). Jedes Feature trägt die OSM-ID sowie unter properties
Gebäudetyp (building), name, housenumber, street, levels, height und area_m2
(Nullwerte werden weggelassen). Die Bounding-Box darf höchstens 0,25 Quadratgrad umfassen (etwa
eine mittlere Stadt, sonst 413), limit höchstens 20.000 Features, simplify (0–20 m)
vereinfacht die Polygone für kleinere Payloads. Der Header X-Feature-Count nennt die
Featurezahl. GET /api/buildings/count?bbox=… zählt vorab und antwortet mit {"count": n}.
WLAN-Ortung
POST /api/wifi/submit nimmt Beobachtungsbündel der Firmenhandys entgegen. Body:
{"items":[{"lat":…,"lon":…,"acc":…,"zeit":…,"aps":[{"mac":"aa:bb:…","rssi":-45},…]},…]} mit
höchstens 200 Einträgen je Bündel (sonst 400); acc ist die Messgenauigkeit in Metern (Einträge
über 30 m werden serverseitig verworfen), zeit die Beobachtungszeit in Millisekunden seit 1970
(wird übernommen, wenn sie nicht in der Zukunft und höchstens sieben Tage alt ist, sonst gilt die
Serverzeit), MACs werden auf Kleinschreibung normalisiert. Die Antwort
{"stored":n,"rejected":m,"relocated":k} kommt nur bei tatsächlich verbuchten Daten mit
Status 200 — jeder andere Status bedeutet „nicht angekommen", die App behält ihre Punkte und
sendet später erneut. rejected zählt Beobachtungen, die der Teleport-Guard abgewiesen hat: Ein
etablierter Zugangspunkt (ab drei Sichtungen) akzeptiert keine Position weiter als 2 km von
seinem gespeicherten Ort; erst fünfzehn konsistente Fernsichtungen am selben neuen Ort gelten als
echter Router-Umzug (relocated). Gespeichert werden ausschließlich MAC und gemittelte Position —
keine Netznamen.
POST /api/wifi/locate schätzt aus sichtbaren Netzen eine Position. Body:
{"aps":[{"mac":"…","rssi":-45},…]} (leer → 400). Sind bekannte Netze dabei, antwortet der
Server in ~20 ms mit {"lat":…,"lon":…,"accuracy":…,"basis":…} — accuracy ist die Streuung um
den signalstärkegewichteten Schwerpunkt in Metern (nie unter 50, bewusst konservativ), basis
die Zahl der verwendeten bekannten Netze. Ausreißer weiter als 3 km vom Median und Netze, die
über ein Jahr nicht gesehen wurden, fließen nicht ein. Kennt der Server kein einziges Netz, kommt
404 — der Normalfall direkt nach dem Einschalten; die App wartet dann auf GPS.
Live-Verkehrslage (Autobahnen)
GET /api/traffic liefert Staus, Sperrungen und Baustellen aller deutschen Bundesautobahnen aus
der offenen API der Autobahn GmbH des Bundes. Der Server pollt die Quelle alle fünf Minuten
(alle ~111 Autobahnen, drei Meldungsarten) und beantwortet Anfragen aus dem Cache — die Antwort
nennt updated_at/age_seconds und markiert sich bei Quellausfall mit stale: true, liefert
dann aber weiter den letzten Stand. Filter: bbox=minlon,minlat,maxlon,maxlat, type als
kommagetrennte Auswahl aus warning (Stau), closure (Sperrung), roadworks (Baustelle),
road (z. B. A2), blocked=true (nur Vollsperrungen), future=true (auch erst angekündigte
Maßnahmen; Standard sind nur aktive) sowie limit (Standard 5000, max. 20000). Jedes Item
enthält Straße, Typ, Titel/Untertitel, Koordinate, die Streckengeometrie als
[lat,lon]-Polylinie (direkt in Leaflet zeichenbar), Verzögerung in Minuten,
Durchschnittsgeschwindigkeit, Vollsperrungs-Flag und die amtliche Beschreibung.
format=geojson liefert stattdessen eine FeatureCollection. Der Endpunkt benötigt kein Token
und wird nicht gezählt. Abdeckung: nur Bundesautobahnen (Datenlage der Quelle). In der Web-Karte
ist die Verkehrslage über den Haken „Verkehrslage" zuschaltbar (Staus rot, Sperrungen dunkelrot,
Baustellen orange ab Zoom 8, Auto-Aktualisierung alle fünf Minuten).
Health
GET /api/health antwortet mit {"status":"ok","services":{…}} und eignet sich als
Monitoring-Ziel für das Gateway.
Admin-API
Alle Admin-Endpunkte liegen unter /admin/api/… und sind durch HTTP-Basic-Auth geschützt
(gleiche Zugangsdaten wie die Admin-Oberfläche unter /admin/). GET /admin/api/tokens listet
alle API-Tokens mit Zählern je Aufruftyp (gesamt, 24 h, 30 Tage) und errechneten Kosten;
POST /admin/api/tokens mit {"name":…,"owner":…,"notes":…} legt ein Token an und liefert den
Token-String genau einmal zurück; GET /admin/api/tokens/{id} liefert Detailstatistik inklusive
Tagesverlauf und der letzten 50 Aufrufe; PUT /admin/api/tokens/{id} mit {"active":true|false}
schaltet es, DELETE /admin/api/tokens/{id} löscht es. GET /admin/api/pricing liest und
PUT /admin/api/pricing setzt die Preise je Klasse
({"pricing":{"navigation":{"price_per_unit":0.01,"currency":"EUR"},…}}).
GET /admin/api/stats liefert Gesamtzähler, GET /admin/api/system den Systemstatus (Dienste,
Import-Fortschritt, aktive Render-Datenbank, Disk, RAM, Indexierungs-Flag) und
GET /admin/api/wifi/all alle erfassten WLAN-Zugangspunkte (MAC, Position, Sichtungen,
Erfassungszeit) für die Karte unter /admin/wifi.html.