Schnellstart
In 3 Schritten einsatzbereit:
1. API-Schlüssel anfordern
Registrieren Sie sich unter portal.napspan.com, um einen kostenlosen API-Schlüssel zu erhalten (14-Tage-Testphase, 1.000 Anfragen/Tag).
2. Erste Anfrage senden
curl -H "X-API-Key: YOUR_API_KEY" \ "https://api.napspan.com/api/v1/events?jurisdiction=DEU&limit=5"
3. Antwort verarbeiten
{
"data": [
{
"id": "de-evt-a100-001",
"type": "construction",
"sub_type": "roadwork",
"severity": "minor",
"title": "Roadworks on A100 Berlin",
"description": "Lane closure between Spandauer Damm and Kaiserdamm...",
"latitude": 52.5167,
"longitude": 13.2833,
"jurisdiction": "DE",
"start_time": "2026-03-23T07:00:00Z"
}
],
"total": 90,
"limit": 5,
"has_more": true
}OpenAPI-Spezifikation
Die vollständige maschinenlesbare API-Spezifikation — enthält ausschließlich Daten-Endpunkte (Ereignisse, Funktionen, Karte, Analytik, LKW-Korridor, Kraftstoffpreise, Metadaten). Erzeugen Sie damit Clients, importieren Sie die Spezifikation in Postman oder Insomnia oder nutzen Sie die interaktive Referenz.
Authentifizierung
Alle API-Anfragen erfordern einen API-Schlüssel. Übergeben Sie ihn über den X-API-Key-Header (empfohlen) oder den api_key-Query-Parameter.
curl -H "X-API-Key: sk_live_abc123" https://api.napspan.com/api/v1/events
curl "https://api.napspan.com/api/v1/events?api_key=sk_live_abc123"
Fehler & Rate-Limits
Die API liefert Standard-HTTP-Statuscodes zurück. Rate-Limit-Header sind in jeder Antwort enthalten.
| Status | Bedeutung |
|---|---|
| 200 | Erfolgreich |
| 400 | Fehlerhafte Anfrage (fehlende/ungültige Parameter) |
| 401 | Fehlender oder ungültiger API-Schlüssel |
| 403 | Tarif-Limit überschritten (Zuständigkeitsbereich, Funktionssperre, abgelaufene Testphase) |
| 429 | Rate-Limit überschritten — bitte nach Retry-After Sekunden erneut versuchen |
| 500 | Serverfehler — bitte erneut versuchen oder Support kontaktieren |
Jede Fehlerantwort enthält ein lesbares error-Feld. Ein 403 aufgrund einer Tarifgrenze enthält zusätzlich einen stabilen code, damit Ihre Integration darauf reagieren kann, ohne den Meldungstext auszuwerten — werten Sie code aus und zeigen Sie error an.
{
"error": "add a jurisdiction filter to this request, e.g. ?jurisdiction=DE-BY (up to 1 per request, comma-separated). The Free plan scopes queries to specific jurisdictions; a higher plan can query all jurisdictions at once.",
"code": "plan_jurisdiction",
"plan": "free",
"plan_name": "Free",
"upgrade_url": "https://portal.napspan.com/billing",
"docs_url": "/reference.html"
}
Codes: plan_jurisdiction, plan_batch_size, plan_event_time_range, plan_event_status, plan_archived_event, plan_inactive_features, plan_geojson, plan_analytics, plan_truck, trial_expired, subscription_expired. Bei anderen Fehlern fehlen diese Felder, behandeln Sie sie daher als optional.
Ereignisse
Verkehrsereignisse umfassen Vorfälle, Baustellen, Sperrungen, Wetterwarnungen, Beschränkungen und Sonderveranstaltungen in allen aktiven Zuständigkeitsbereichen.
GET /api/v1/events
| Parameter | Typ | Beschreibung |
|---|---|---|
| ids | string | Komma-getrennte Ereignis-IDs für die Stapelabfrage. Ist ids gesetzt, werden alle anderen Filter ignoriert und die Paginierung deaktiviert — die Antwort enthält stets alle Ergebnisse in einer Seite, unabhängig vom status. Begrenzt durch max_batch_size des Tarifs. |
| jurisdiction | string | Filter nach ISO-Länder-/Regionscode (z. B. DE, FR, AT) im Free-Tarif erforderlich. Abfragen eines Primärcodes erweitern sich automatisch auf alle Mitglieder seiner Gruppe, sofern eine existiert. |
| type | string | Filter nach Ereignistyp: incident, construction, closure, weather, special_event, advisory, restriction |
| severity | string | Filter: minor, moderate, major, critical |
| lat, lng, radius_km | number | Umkreissuche (z. B. lat=52.52&lng=13.40&radius_km=50) |
| bbox | string | Begrenzungsrahmen: minLng,minLat,maxLng,maxLat |
| limit | int | Ergebnisse pro Seite (Standard 100, Maximum je nach Tarif) |
| offset | int | Paginierungs-Offset |
curl -H "X-API-Key: $KEY" \ "https://api.napspan.com/api/v1/events?ids=de-evt-a9-001,fr-evt-a1-002,at-evt-a4-015"
# Ereignisse in der Nähe von Berlin, DE curl -H "X-API-Key: $KEY" \ "https://api.napspan.com/api/v1/events?jurisdiction=DEU&lat=52.52&lng=13.40&radius_km=100"
import requests resp = requests.get("https://api.napspan.com/api/v1/events", params={ "jurisdiction": "DE", "lat": 52.52, "lng": 13.40, "radius_km": 100 }, headers={"X-API-Key": KEY}) events = resp.json()["data"]
const res = await fetch( `https://api.napspan.com/api/v1/events?jurisdiction=DEU&lat=52.52&lng=13.40&radius_km=100`, { headers: { "X-API-Key": KEY } } ); const { data, total } = await res.json();
req, _ := http.NewRequest("GET", "https://api.napspan.com/api/v1/events?jurisdiction=DEU&lat=52.52&lng=13.40&radius_km=100", nil) req.Header.Set("X-API-Key", key) resp, _ := http.DefaultClient.Do(req)
{
"data": [
{
"id": "de-evt-a100-001",
"source_id": "EVT-2026-04521",
"source": "de",
"jurisdiction": "DE",
"type": "incident",
"severity": "major",
"status": "active",
"title": "Multi-vehicle collision on A100 westbound near Spandauer Damm",
"description": "Two right lanes blocked. Emergency services on scene.",
"affected_roads": ["A100"],
"direction": "westbound",
"lanes_affected": "2 of 4 lanes blocked",
"start_time": "2026-03-29T14:30:00Z",
"end_time": null,
"estimated_end_time": "2026-03-29T17:00:00Z",
"latitude": 52.5167,
"longitude": 13.2833,
"road_class": "motorway",
"last_updated": "2026-03-29T14:45:00Z",
"created_at": "2026-03-29T14:30:00Z"
}
],
"total": 42,
"limit": 100,
"offset": 0,
"has_more": false
}GET /api/v1/events/{id}
Einzelnes Ereignis nach ID. Liefert das vollständige Ereignis mit allen Metadatenfeldern zurück.
{
"id": "de-evt-a100-001",
"source_id": "EVT-2026-04521",
"source": "de",
"jurisdiction": "DE",
"type": "incident",
"severity": "major",
"status": "active",
"title": "Multi-vehicle collision on A100 westbound near Spandauer Damm",
"description": "Two right lanes blocked. Emergency services on scene.",
"location": { "type": "Point", "coordinates": [13.2833, 52.5167] },
"affected_roads": ["A100"],
"direction": "westbound",
"lanes_affected": "2 of 4 lanes blocked",
"start_time": "2026-03-29T14:30:00Z",
"end_time": null,
"estimated_start_time": null,
"estimated_end_time": "2026-03-29T17:00:00Z",
"source_created_at": "2026-03-29T14:28:55Z",
"source_updated_at": "2026-03-29T14:45:00Z",
"latitude": 52.5167,
"longitude": 13.2833,
"road_class": "motorway",
"metadata": { "vehicles_involved": 3 },
"last_updated": "2026-03-29T14:45:00Z",
"created_at": "2026-03-29T14:30:00Z",
"archived_at": null,
"archive_reason": null
}archive_reason ist null, solange das Ereignis aktiv ist. Sobald ein Ereignis archiviert wird, trägt es einen von zwei Werten:
observed— der Upstream-Feed lieferte eine erfolgreiche Antwort und das Ereignis war nicht mehr enthalten, also haben wir es regulär archiviert. Das ist der Normalfall.stale_sweep— der reguläre Archivierungspfad konnte das Ereignis nicht zurückziehen (Upstream-Antworten waren leer oder fehlerhaft) und ein Sicherheits-Sweep hat es nach etwapoll_interval × sweep_factor(Standardfaktor 15) ohne neue Beobachtung erzwungen archiviert. Behandeln Siearchived_atfür solche Datensätze als „vermutlich beendet bis"-Zeitstempel, nicht als exaktes Ende. Ein dauerhaft hoherstale_sweep-Anteil bei einer Quelle ist ein Signal, dass der Upstream-Feed Beendigungs-Records unzuverlässig liefert.
GET /api/v1/events/geojson Starter+
Gleiche Parameter wie /events, liefert eine GeoJSON-FeatureCollection zurück. Direkt verwendbar mit Leaflet, Mapbox oder jedem GeoJSON-fähigen Tool. Content-Type: application/geo+json.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [13.2833, 52.5167] },
"properties": {
"id": "de-evt-a100-001",
"source": "de",
"jurisdiction": "DE",
"type": "incident",
"severity": "major",
"status": "active",
"title": "Multi-vehicle collision on A100 westbound near Spandauer Damm",
"affected_roads": ["A100"],
"direction": "westbound",
"start_time": "2026-03-29T14:30:00Z"
}
}
]
}Funktionen
Funktionen (Features) sind Nicht-Ereignis-Daten: Kameras, Wetterstationen, Rastplätze, Schilder, LKW-Parkplätze, EV-Ladestationen und mehr. Alle Typen nutzen denselben Endpunkt — geben Sie einen einzelnen type an, oder verwenden Sie group, um alle Typen einer Kategorie auf einmal abzurufen (z. B. liefert group=trucking neun LKW-bezogene Typen in einer Anfrage).
GET /api/v1/features
| Parameter | Typ | Beschreibung |
|---|---|---|
| type | string | Funktionstyp (siehe Funktionstypen). Entweder type oder group ist erforderlich. |
| group | string | Funktionsgruppen-ID (siehe Funktionsgruppen). Bequeme Erweiterung auf alle Typen der Gruppe. Wenn zusammen mit radius_km verwendet, ist der Radius auf 200 km begrenzt — eine weitere Suche über alle Typen einer Gruppe lässt sich nicht rechtzeitig beantworten und liefert 400 statt einer Zeitüberschreitung. Für unbegrenzte Umkreissuchen einen einzelnen type abfragen. |
| jurisdiction | string | Filter nach Zuständigkeitscode. Abfragen eines Primärcodes erweitern sich automatisch auf alle Mitglieder seiner Gruppe, sofern eine existiert. |
| active | bool | true, um nur aktive Funktionen zurückzugeben |
| lat, lng, radius_km | number | Umkreissuche |
| bbox | string | Begrenzungsrahmen: minLng,minLat,maxLng,maxLat |
| starts_after, starts_before | string | Zeitfensterfilter auf den geplanten Beginn (fällt auf den tatsächlichen Beginn zurück). RFC3339 oder YYYY-MM-TT. |
| ends_after, ends_before | string | Zeitfensterfilter auf das geplante Ende. Zeitlich offene Einträge (bekannter Beginn, kein Ende) erfüllen ends_after, aber nie ends_before. |
| limit, offset | int | Paginierung |
Die Zeitfensterfilter gelten für zeitlich begrenzte Feature-Typen — future_construction, alerts, special_events, truck_restrictions und ähnliche. Werden beide Grenzen gesetzt, liefert die Abfrage alle Einträge, die sich mit dem Zeitraum überschneiden: ?starts_before=2026-09-01&ends_after=2026-08-01 gibt jeden Eintrag zurück, der im August 2026 zu irgendeinem Zeitpunkt aktiv ist. Features ganz ohne Datumsangaben werden aus Zeitfensterabfragen ausgeschlossen.
Hinweis zur Abdeckung: Bislang veröffentlicht keine NAPSPAN-Quelle geplante Start- und Enddaten. Diese Filter liefern daher derzeit bei jedem EU-Feature-Typ ein leeres Ergebnis. Die Parameter gehören zum gemeinsamen API-Vertrag und liefern automatisch Ergebnisse, sobald eine Quelle Zeitpläne veröffentlicht — bis dahin sollten Sie nicht mit EU-Daten aus diesen Filtern rechnen.
Jeder Datensatz enthält ein boolesches has_details-Feld. Bei true liefert die Quelle mehr Daten, als die Listenzeile mitführt — rufen Sie GET /features/{id}/details auf (oder bündeln Sie Aufrufe mit POST /features/details/batch weiter unten), um sie zu erhalten. Bei false enthält die Listenzeile bereits alles, was die Quelle für dieses (source, feature_type)-Paar veröffentlicht.
curl -H "X-API-Key: $KEY" \ "https://api.napspan.com/api/v1/features?type=cameras&jurisdiction=ESP&lat=40.42&lng=-3.70&radius_km=50"
curl -H "X-API-Key: $KEY" \ "https://api.napspan.com/api/v1/features?group=trucking&jurisdiction=DEU"
Die Form von properties variiert je nach feature_type. Die folgenden Beispiele zeigen die typischen Felder für die häufigsten Typen — wählen Sie einen Tab aus.
{
"data": [
{
"id": "de-cam-a8-muc-01",
"source": "de",
"jurisdiction": "DE",
"feature_type": "cameras",
"name": "A8 Munich Ost",
"latitude": 48.1391,
"longitude": 11.6754,
"road_name": "A8",
"direction": "eastbound",
"is_active": true,
"properties": {
"url": "https://verkehr.bayern.de/cameras/a8_muc_ost.jpg",
"video_url": null
},
"last_updated": "2026-03-29T14:50:00Z",
"has_details": true
}
],
"total": 2080, "limit": 100, "offset": 0, "has_more": true
}{
"data": [
{
"id": "at-wx-a4-vie",
"jurisdiction": "AT",
"feature_type": "weather_stations",
"name": "A4 Vienna Weather Station",
"latitude": 48.2082, "longitude": 16.3738,
"road_name": "A4",
"is_active": true,
"properties": {
"temperature": 12.4,
"wind_speed": 18.2,
"wind_direction": "NW",
"precipitation": "light_rain",
"road_surface": "wet",
"humidity": 78,
"visibility": 12.0
},
"last_updated": "2026-03-29T14:45:00Z",
"has_details": false
}
],
"total": 2150, "limit": 100, "offset": 0, "has_more": true
}{
"data": [
{
"id": "fr-dms-a4-paris-512",
"jurisdiction": "FR",
"feature_type": "signs",
"name": "A4 EB DMS at PR 12",
"latitude": 48.8566, "longitude": 2.4500,
"road_name": "A4",
"direction": "eastbound",
"is_active": true,
"properties": {
"message": "ACCIDENT 5 KM / 2 VOIES FERMÉES / RALENTISSEMENTS",
"posted_at": "2026-03-29T14:35:00Z",
"sign_type": "DMS"
},
"last_updated": "2026-03-29T14:50:00Z",
"has_details": true
}
],
"total": 3120, "limit": 100, "offset": 0, "has_more": true
}{
"data": [
{
"id": "nl-ev-amsterdam-a2-12",
"source": "ndw",
"jurisdiction": "NL",
"feature_type": "ev_charging",
"name": "Fastned Amsterdam Zuid",
"latitude": 52.3399, "longitude": 4.8732,
"is_active": true,
"properties": {
"network": "Fastned",
"connector_types": ["CCS2", "CHAdeMO", "Type2"],
"max_kw": 300,
"port_count": 8,
"access": "public",
"pricing": "€0.69/kWh"
},
"last_updated": "2026-03-15T00:00:00Z",
"has_details": true
}
],
"total": 42100, "limit": 100, "offset": 0, "has_more": true
}{
"data": [
{
"id": "de-bridge-a8-iller",
"source": "bast",
"feature_type": "bridge_clearances",
"name": "A8 Iller Viaduct",
"latitude": 48.21, "longitude": 10.05,
"is_active": true,
"properties": {
"min_vertical_clearance_m": 4.50,
"posting_status": "open",
"weight_limit_tons": null,
"year_built": 1972,
"structure_kind": "prestressed concrete",
"bridge_number": "BAST-7811-A8"
},
"last_updated": "2026-01-15T00:00:00Z",
"has_details": false
}
],
"total": 39800, "limit": 100, "offset": 0, "has_more": true
}{
"data": [
{
"id": "de-tp-a7-soltau",
"jurisdiction": "DE",
"feature_type": "truck_parking",
"name": "A7 Truck Parking Soltau-Ost",
"latitude": 52.99, "longitude": 9.83,
"is_active": true,
"properties": {
"capacity": 62,
"available": 12,
"availability_pct": 19,
"amenities": ["restrooms", "vending", "lighting"],
"observed_at": "2026-03-29T14:30:00Z"
},
"last_updated": "2026-03-29T14:50:00Z",
"has_details": false
}
],
"total": 580, "limit": 100, "offset": 0, "has_more": true
}GET /api/v1/features/types
Liefert jeden aktiven feature_type mit Gesamt- und Aktiv-Zählwerten. 2 Minuten gecacht. Nützlich, um eine UI-Auswahl auf tatsächlich vorhandene Datentypen zu beschränken.
[
{ "type": "cameras", "count": 8120, "active_count": 7842 },
{ "type": "weather_stations", "count": 2150, "active_count": 2098 },
{ "type": "signs", "count": 3120, "active_count": 2987 },
{ "type": "ev_charging", "count": 42100, "active_count": 42100 },
{ "type": "bridge_clearances", "count": 39800, "active_count": 39800 }
]GET /api/v1/features/groups
Liefert die 16-Gruppen-Funktionstaxonomie mit den zugehörigen Funktionstypen. Verwenden Sie das Feld id als group-Parameter bei /features. 1 Stunde lang gecacht. Die vollständige Tabelle finden Sie unter Funktionsgruppen.
[
{
"id": "imagery",
"name": "Imagery",
"description": "Live traffic camera feeds",
"sort_order": 1,
"feature_types": ["cameras"]
},
{
"id": "trucking",
"name": "Trucking & Commercial Vehicles",
"description": "Truck restrictions, routes, parking, inspections",
"sort_order": 8,
"feature_types": [
"truck_restrictions", "weight_restrictions", "bridge_clearances",
"truck_routes", "freight_corridors", "truck_parking",
"truck_rest_areas", "weigh_stations", "inspection_stations"
]
}
]GET /api/v1/features/{id}/details
Lazy-geladene Details für eine einzelne Funktion. Einige Quellen liefern in der Listenansicht nur kompakte Felder; dieser Endpunkt liefert das vollständige properties-Objekt sowie ein detail_available-Flag und einen cache-Hinweis (hit / miss / none / poll / error). Anhand des has_details-Feldes der Listenantwort lässt sich entscheiden, ob dieser Aufruf sinnvoll ist.
{
"data": {
"id": "de-cam-a8-muc-01",
"feature_type": "cameras",
"name": "A8 Munich Ost",
"latitude": 48.1391, "longitude": 11.6754,
"properties": {
"url": "https://verkehr.bayern.de/cameras/a8_muc_ost.jpg",
"video_url": "https://verkehr.bayern.de/cameras/a8_muc_ost.m3u8",
"views": [
{ "name": "Eastbound", "url": "https://verkehr.bayern.de/cameras/a8_muc_ost_eb.jpg" },
{ "name": "Westbound", "url": "https://verkehr.bayern.de/cameras/a8_muc_ost_wb.jpg" }
]
}
},
"detail_available": true,
"cache": "miss"
}POST /api/v1/features/details/batch
Details für viele Funktionen in einem Aufruf abrufen. Das Pro-ID-Caching ist identisch mit dem Einzelaufruf-Endpunkt (Redis-basiert, nach ID indiziert) — eine Stapelanfrage, die sich mit vorherigen Aufrufen überschneidet, verursacht für den Überlappungsteil keine zusätzlichen Kosten. Teilerfolge bleiben erhalten: Schlägt ein einzelner Upstream-Abruf fehl, wird in dessen Eintrag cache: "error" gesetzt, ohne dass die gesamte Anfrage scheitert; fehlende IDs erscheinen mit not_found: true. Die Stapelgröße ist durch max_batch_size des Tarifs begrenzt.
curl -X POST -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ -d '{"ids": ["de-cam-a8-muc-01", "de-cam-a9-nbg-04", "missing-id"]}' \ "https://api.napspan.com/api/v1/features/details/batch"
{
"count": 3,
"data": [
{
"id": "de-cam-a8-muc-01",
"data": { "id": "de-cam-a8-muc-01", "name": "A8 Munich Ost", "properties": { "url": "…", "views": ["…"] } },
"detail_available": true,
"cache": "hit"
},
{
"id": "de-cam-a9-nbg-04",
"data": { "id": "de-cam-a9-nbg-04", "name": "A9 Nürnberg Nord" },
"detail_available": true,
"cache": "miss"
},
{
"id": "missing-id",
"detail_available": false,
"cache": "",
"not_found": true
}
]
}LKW-Korridor Pro+
Finden Sie alle LKW-Beschränkungen entlang einer Route. Erzeugt einen gepufferten Korridor zwischen zwei Punkten und liefert jede Brückendurchfahrtshöhe, Gewichtsbeschränkung, LKW-Route und Restriktion zurück, die diesen schneidet. Verwendet PostGIS-Geo-Abfragen für eine präzise Großkreis-Pufferung.
GET /api/v1/truck/corridor
| Parameter | Typ | Beschreibung |
|---|---|---|
| from_lat Erforderlich | number | Ausgangs-Breitengrad |
| from_lng Erforderlich | number | Ausgangs-Längengrad |
| to_lat Erforderlich | number | Ziel-Breitengrad |
| to_lng Erforderlich | number | Ziel-Längengrad |
| buffer_km | number | Pufferabstand um Korridor (Standard 5, Maximum 50 km) |
| height | number | Fahrzeughöhe in Metern — filtert Durchfahrtshöhen darunter |
| weight | number | Fahrzeuggewicht in metrischen Tonnen — filtert Gewichtsgrenzen darunter |
| jurisdiction | string | Auf einen Zuständigkeitsbereich beschränken |
| limit | int | Maximale Ergebnisse (Standard 500, Maximum 2000) |
bridge_clearances, bridges, weight_restrictions, truck_restrictions, truck_routes, freight_corridors, truck_parkingcurl -H "X-API-Key: $KEY" \ "https://api.napspan.com/api/v1/truck/corridor?\ from_lat=48.14&from_lng=11.58&\ to_lat=47.81&to_lng=13.05&\ buffer_km=10"
{
"corridor": {
"from": [48.14, 11.58],
"to": [47.81, 13.05],
"buffer_km": 10,
"distance_km": 142.5
},
"data": [
{
"id": "de-bridge-a8-iller",
"feature_type": "bridge_clearances",
"name": "A8 Iller Viaduct",
"latitude": 48.21,
"longitude": 10.05,
"properties": {
"posting_status": "open",
"year_built": 1972,
"_distance_km": "2.31"
}
},
{
"id": "at-trk-a1-salzburg",
"feature_type": "truck_restrictions",
"name": "Salzburg West",
"properties": {
"restriction": "Section ban for trucks > 7.5 t on weekends",
"_distance_km": "0.45"
}
}
],
"total": 98,
"limit": 500
}GET /api/v1/truck/corridor/geojson Pro+ GeoJSON
Gleiche Abfrage, liefert GeoJSON FeatureCollection zurück. Verwenden Sie dies, um Korridor-Ergebnisse direkt auf einer Leaflet- oder Mapbox-Karte darzustellen.
// LKW-Korridor auf Leaflet-Karte darstellen const url = `https://api.napspan.com/api/v1/truck/corridor/geojson` + `?from_lat=48.14&from_lng=11.58&to_lat=47.81&to_lng=13.05&buffer_km=10`; fetch(url, { headers: { "X-API-Key": KEY } }) .then(r => r.json()) .then(geojson => { L.geoJSON(geojson, { pointToLayer: (f, ll) => L.circleMarker(ll, { radius: 6 }), onEachFeature: (f, layer) => { layer.bindPopup(`<b>${f.properties.name}</b><br>${f.properties.feature_type}`); } }).addTo(map); });
import requests resp = requests.get("https://api.napspan.com/api/v1/truck/corridor", params={ "from_lat": 48.14, "from_lng": 11.58, "to_lat": 47.81, "to_lng": 13.05, "buffer_km": 10 }, headers={"X-API-Key": KEY}) for feat in resp.json()["data"]: if feat["feature_type"] == "bridge_clearances": print(f"Bridge: {feat['name']} ({feat['properties'].get('posting_status', 'unknown')})")
{
"type": "FeatureCollection",
"corridor": {
"from": [48.14, 11.58],
"to": [47.81, 13.05],
"buffer_km": 10,
"distance_km": 142.5
},
"features": [
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [10.05, 48.21] },
"properties": {
"id": "de-bridge-a8-iller",
"feature_type": "bridge_clearances",
"name": "A8 Iller Viaduct",
"min_vertical_clearance_m": 4.50,
"posting_status": "open",
"_distance_km": "2.31"
}
}
]
}Analytik Pro+
Historische Analysen und Trends zu Ereignissen, Funktionen und Quell-Gesundheit. Alle Endpunkte erfordern den Pro- oder Enterprise-Tarif.
GET /api/v1/analytics/history/{id}
Lebenszyklus-Zeitleiste eines einzelnen Ereignisses — Erstellung, Schweregradänderungen, Spuränderungen, Endzeitänderungen, Archivierung.
[
{ "id": 1, "event_id": "de-evt-a100-001",
"change_type": "created",
"old_value": null, "new_value": "active",
"changed_at": "2026-03-29T14:30:00Z" },
{ "id": 2, "event_id": "de-evt-a100-001",
"change_type": "severity_change",
"old_value": "moderate", "new_value": "major",
"changed_at": "2026-03-29T14:35:00Z" }
]GET /api/v1/analytics/changes
Feed aktueller Änderungen über alle Ereignisse hinweg. Paginiert. Geeignet, um eine nachgelagerte Kopie des Ereigniszustands zu synchronisieren, ohne jedes Ereignis einzeln abzufragen.
{
"data": [
{ "id": 45, "event_id": "de-evt-a100-001",
"change_type": "severity_change",
"old_value": "moderate", "new_value": "major",
"jurisdiction": "DE",
"event_title": "Multi-vehicle collision on A100 westbound",
"changed_at": "2026-03-29T14:35:00Z" }
],
"total": 128, "limit": 100, "offset": 0, "has_more": true
}GET /api/v1/analytics/clearance
P50- / P95- / Durchschnitts-Räumungszeiten nach Zuständigkeitsbereich und Ereignistyp. Berechnet aus start_time → archived_at.
[
{ "jurisdiction": "DE", "event_type": "incident",
"total_events": 320,
"p50_minutes": 42.5, "p95_minutes": 175.0, "avg_minutes": 59.4 },
{ "jurisdiction": "AT", "event_type": "construction",
"total_events": 150,
"p50_minutes": 4320.0, "p95_minutes": 21600.0, "avg_minutes": 7200.0 }
]GET /api/v1/analytics/corridors
Pro-Straße-Ereignishäufigkeit und durchschnittliche Räumungszeit. Bestes Signal dafür, „welcher Korridor heute unzuverlässig ist“.
[
{ "road": "A100", "jurisdiction": "DE",
"total_events": 245,
"avg_clearance_minutes": 52.3,
"incident_count": 180, "construction_count": 65 }
]GET /api/v1/analytics/trends
Tägliche Ereigniszählungen mit Aufschlüsselung nach Typ.
[
{ "period": "2026-03-29", "total": 142,
"by_type": { "incident": 58, "construction": 62, "closure": 12, "weather": 10 } },
{ "period": "2026-03-28", "total": 128,
"by_type": { "incident": 45, "construction": 60, "closure": 15, "weather": 8 } }
]GET /api/v1/analytics/hotspots
Geografische Cluster von Ereignissen mit dem dominanten Typ und der dominanten Straße pro Cluster.
[
{ "cluster_id": 1,
"latitude": 52.5167, "longitude": 13.2833,
"event_count": 28, "radius_km": 2.5,
"top_type": "incident", "top_road": "A100" }
]GET /api/v1/analytics/weather
Historische Messwerte von Wetterstationen — die Datenbasis für die Wetter-Ereignis-Korrelation.
[
{ "station_id": "at-wx-a4-vie",
"name": "A4 Vienna Weather Station",
"latitude": 48.2082, "longitude": 16.3738,
"temperature": 12.4, "wind_speed": 18.2, "wind_direction": "NW",
"precipitation": "light_rain", "road_surface": "wet",
"humidity": 78, "visibility": 12.0,
"recorded_at": "2026-03-29T14:45:00Z" }
]Weitere Analytik-Endpunkte
Gleiche Form wie die obigen Beispiele — vollständige Schemas siehe interaktive Referenz.
| Endpunkt | Beschreibung |
|---|---|
| /analytics/feature-history | Lebenszyklusänderungen von Funktionen (erstellt, deaktiviert, reaktiviert). |
| /analytics/event-weather/{id} | Wetter-Snapshot zum Zeitpunkt der Ereigniserstellung (PostGIS-Suche der nächsten Station). |
| /analytics/weather-correlation | Aggregierte Korrelation zwischen Ereignissen und Wetter. |
Metadaten & Status
Leichte Katalog- und Status-Endpunkte. Diese sind öffentlich (kein API-Schlüssel erforderlich) — nur /fuel-prices erfordert einen API-Schlüssel, ist aber nicht durch Tarifgrenzen beschränkt.
GET /api/v1/jurisdictions
Aktive Zuständigkeitsbereiche mit Code, Name, Land und scope. Standardmäßig werden nur reale geografische Zuständigkeitsbereiche zurückgegeben (scope=state). Mit ?scope=federal erhalten Sie übergreifende nationale Quellen, mit ?scope=regional sub-nationale Feeds und mit ?scope=all alles.
Ist group_id nicht null, gehört der Zuständigkeitsbereich zu einer Gruppe (siehe /api/v1/jurisdictions/groups unten). Eine Abfrage mit ?jurisdiction=<primary> auf /events oder /features wird transparent auf alle Mitglieder ausgedehnt; um dies zu deaktivieren, geben Sie einen Nicht-Primärcode oder eine kommagetrennte Liste an. Die EU-Bereitstellung führt derzeit keine Gruppen – alle Zeilen liefern group_id: null –, das Feld ist jedoch dokumentiert, damit Clients es übernehmen können, sobald parallele Feeds entstehen.
[
{ "code": "DE", "name": "Germany", "country": "DE", "scope": "state", "group_id": null, "is_active": true },
{ "code": "AT", "name": "Austria", "country": "AT", "scope": "state", "group_id": null, "is_active": true }
]GET /api/v1/jurisdictions/groups
Kanonische Bündel für Zuständigkeitsbereiche, deren Feed über mehrere Codes verteilt ist. Der primary_jurisdiction_code ist der Code, den Sie auf /events und /features verwenden – die Abfrage wird transparent auf alle members ausgedehnt. Die EU-Bereitstellung gibt derzeit ein leeres Array zurück; der Endpunkt wird ausgeliefert, damit Clients sich darauf verlassen können, sobald Mobilithek oder andere nationale Quellen gebündelt werden müssen.
[]
GET /api/v1/stats/summary
Umfassende Sammelstatistiken — werden auf den Marketing-Seiten für Live-Zähler genutzt. Schwerere Abfrage als /stats; 60 s gecacht.
{
"jurisdictions": { "total": 28, "active": 26, "by_country": { "DE": 1, "AT": 1, "FR": 1 } },
"events": {
"active": 3120,
"by_type": { "incident": 820, "construction": 1450, "closure": 280 },
"by_severity": { "minor": 1080, "moderate": 1450, "major": 510, "critical": 80 }
},
"features": { "total": 96450, "by_type": { "cameras": 8120, "ev_charging": 42100 } },
"last_sync": "2026-03-29T14:55:00Z",
"uptime": "72h15m"
}GET /api/v1/fuel-prices
Europäische Kraftstoffpreise (sofern lizenzierte Quellen verfügbar sind). Mit latest=true nur die jeweils aktuellsten Werte je jurisdiction + fuel_type.
{
"data": [
{ "jurisdiction": "DE", "country": "DE", "fuel_type": "diesel",
"price": 1.69, "currency": "EUR", "unit": "litre",
"observed_at": "2026-05-05", "source": "BAFA" },
{ "jurisdiction": "FR", "country": "FR", "fuel_type": "diesel",
"price": 1.74, "currency": "EUR", "unit": "litre",
"observed_at": "2026-05-05", "source": "DGEC" }
],
"total": 128, "limit": 100, "offset": 0, "has_more": true
}GET /api/v1/status
Öffentlicher Status-Schnappschuss — geeignet für eine unauthentifizierte Statusseite oder externe Uptime-Monitore. Aggregierte Kennzahlen plus Aufschlüsselung pro Zuständigkeit mit 7-Tage-Verfügbarkeit. 60 s Cache.
{
"overall": "operational",
"generated_at": "2026-05-08T14:00:00Z",
"worker": { "last_seen": "2026-05-08T13:59:50Z", "staleness_seconds": 10, "healthy": true },
"total_resources": 186, "healthy": 175, "warning": 8, "critical": 3,
"jurisdictions": [
{ "code": "DE", "name": "Germany", "country": "DE",
"status": "operational", "total_resources": 12, "open_circuits": 0,
"uptime_7day_percent": 99.8 }
]
}Webhooks Pro+
Abonnieren Sie Echtzeit-Ereignisänderungen. Wenn ein Verkehrsereignis erstellt wird, seinen Schweregrad oder Status ändert oder archiviert wird, sendet die API einen HMAC-SHA256-signierten POST an Ihren Endpunkt. Pro- und Enterprise-Kunden konfigurieren Abonnements im Portal — portal.napspan.com/webhooks. Das automatisch generierte Secret wird beim Anlegen einmalig angezeigt; kopieren Sie es dann.
Jeder Webhook wird nach Zuständigkeit (verpflichtend, Mehrfachauswahl — wählen Sie eine oder mehrere) und optional nach Ereignistyp, Untertyp und Schweregrad (ebenfalls Mehrfachauswahl) gefiltert. Filter werden über Dimensionen UND-verknüpft; innerhalb einer Dimension feuert der Webhook, sobald das Ereignis einem der ausgewählten Werte entspricht.
Der optionale sub_type-Filter grenzt innerhalb eines Typs ein — z. B. liefert type: ["incident"] + sub_type: ["accident"] nur Unfälle, keine Pannen oder Fahrbahnhindernisse. Er ist additiv: Lassen Sie ihn weg (oder senden Sie ein leeres Array), erhalten Sie wie bisher jeden Untertyp. sub_type ist außerdem ein Feld in jedem Ereignis sowie ein ?sub_type=-Abfrageparameter auf /events. Das vollständige Vokabular finden Sie in der API-Referenz.
Der optionale cause-Filter funktioniert ähnlich, aber typübergreifend. Da sub_type einem type untergeordnet ist (der Untertyp einer Sperrung beschreibt die Sperrung, nicht ihre Ursache), trägt ein Unfall, den eine Quelle als Sperrung meldet, type: "closure", sub_type: "lane_closure" — und cause: "accident". Damit erfasst cause: ["accident"] unfallbedingte Ereignisse unabhängig davon, wie die Quelle sie modelliert hat — was sub_type: ["accident"] allein verpassen würde. Wie sub_type ist cause ein Feld in jedem Ereignis, ein ?cause=-Abfrageparameter auf /events und eine additive Webhook-Filterdimension.
Ereignistypen
| Ereignis | Wird ausgelöst, wenn |
|---|---|
event.created | Ein neues Verkehrsereignis aus einer nationalen Mobilitätsdatenquelle eintrifft. |
event.severity_change | Sich der Schweregrad eines bestehenden Ereignisses ändert (z. B. moderate → major). |
event.status_change | Sich der Status ändert (z. B. active → archived). |
event.archived | Das Ereignis beendet ist. |
test | Wird nur über den „Test"-Button im Portal gesendet — feuert sofort, wird nie im Zustellverlauf erfasst. |
Sofort-Payload (Standard)
Ein POST pro Änderung. Geeignet, wenn Sie die geringstmögliche Latenz benötigen und Ihr Empfänger Lastspitzen verarbeiten kann.
{
"event": "event.severity_change",
"timestamp": "2026-03-29T14:35:00Z",
"data": {
"event_id": "de-evt-a100-001",
"jurisdiction": "DE",
"type": "incident",
"sub_type": "accident",
"cause": "accident",
"severity": "major",
"road_name": "A100",
"changes": {
"old_severity": "moderate",
"new_severity": "major"
}
}
}Gebündelter Payload
Setzen Sie batch_window_seconds (1–300) beim Anlegen des Webhooks, um Änderungen für dieses Fenster zu sammeln und als einen POST auszuliefern. Reduziert das HTTP-Volumen bei gesprächigen Empfängern (Slack, Teams, Lambda) — auf Kosten von bis zu window_seconds zusätzlicher Latenz.
{
"batch": {
"window_seconds": 60,
"started_at": "2026-03-29T14:30:00Z",
"ended_at": "2026-03-29T14:31:00Z",
"event_count": 2
},
"events": [
{
"event": "event.created",
"timestamp": "2026-03-29T14:30:15Z",
"data": { "event_id": "de-evt-a8-002", "jurisdiction": "DE", "type": "construction", "sub_type": "roadwork", "severity": "minor", "road_name": "A8" }
},
{
"event": "event.severity_change",
"timestamp": "2026-03-29T14:30:42Z",
"data": { "event_id": "de-evt-a100-001", "jurisdiction": "DE", "type": "incident", "sub_type": "accident", "severity": "major", "road_name": "A100", "changes": { "old_severity": "moderate", "new_severity": "major" } }
}
]
}Empfänger verzweigen anhand des batch-Schlüssels:
if ("batch" in body) { // gebündelt: über body.events iterieren for (const ev of body.events) handle(ev); } else { // sofort: den Body selbst verarbeiten handle(body); }
Ein einzelner Batch ist auf 100 Ereignisse begrenzt; längere Warteschlangen werden im selben Fenster auf mehrere POSTs aufgeteilt.
Signatur prüfen
Jede Zustellung enthält einen X-Webhook-Signature-Header mit dem HMAC-SHA256 (Hex, lowercase) des Anfragerumpfs, signiert mit Ihrem Webhook-Secret. Lehnen Sie Anfragen ab, deren Signatur nicht übereinstimmt.
import crypto from "crypto"; app.post("/napspan-webhook", (req, res) => { const sig = req.headers["x-webhook-signature"]; const expected = crypto .createHmac("sha256", process.env.WEBHOOK_SECRET) .update(req.rawBody) // rohe Bytes, NICHT JSON.stringify(req.body) .digest("hex"); if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) { return res.status(401).end(); } // req.body verarbeiten… res.status(200).end(); });
Zuverlässigkeit
Fehlgeschlagene Zustellungen werden bis zu 3-mal mit exponentiellem Backoff (10s, 30s, 90s) wiederholt. Nach 10 aufeinanderfolgenden Fehlschlägen wird das Abonnement automatisch deaktiviert — reaktivieren Sie es im Portal, sobald Ihr Endpunkt wieder gesund ist. Verwenden Sie die Test-Schaltfläche je Zeile im Portal, um sofort ein test-Ereignis auszulösen und die Erreichbarkeit zu prüfen, bevor Sie sich produktiv auf einen Webhook verlassen.
LKW-Routing Pro+
Eine LKW-gerechte Route von Start nach Ziel — die Routinggeometrie kommt aus unserer Routing-Engine (einschließlich ADR-Tunnelkategorie-Beschränkungen für Gefahrgut) und wird anschließend mit jeder nahegelegenen Gefahr angereichert, die unsere Datenbank kennt: Live-RTTI-/SRTI-Vorfälle, geplante Bauarbeiten, Brückendurchfahrtshöhen gefiltert nach der angefragten Fahrzeughöhe, LKW- und Gewichtsbeschränkungen, Wetter entlang des Korridors und aktive Warnungen — sofern der jeweilige NAP die zugrunde liegenden Daten veröffentlicht.
POST /api/v1/routing/route
| Feld | Typ | Beschreibung |
|---|---|---|
| origin Erforderlich | object | { "lat": ..., "lng": ... } |
| destination Erforderlich | object | { "lat": ..., "lng": ... } |
| truck Erforderlich | object | Fahrzeugblock — profile (tractor, straight, box), weight_t, height_m, optional length_m, width_m, axle_count, hazardous[] |
| truck.profile_id | string | Verweist auf ein gespeichertes LKW-Profil aus Ihrer Flottenbibliothek (im Portal unter Meine LKW verwaltet), statt den vollständigen Block erneut zu senden. Inline mitgesendete truck.*-Felder werden darüber tief zusammengeführt (Inline-Werte gewinnen pro Feld). Der aufgelöste Block wird als resolved_truck zurückgegeben. Siehe Wiederverwendbare LKW-Profile. |
| alternatives | int | Anzahl alternativer Routen (0–3, Standard 0) |
| avoid | array | Optional: tolls, ferries, tunnels |
| include | array | Optionale Detailkanäle. Fügen Sie tolls hinzu, damit die Routing-Engine die Mautsysteme der Route für Ihren LKW bepreist — die Kosten werden als summary.toll_costs[] (ein Eintrag pro Währung) und sections[].tolls[] (pro System) zurückgegeben. polyline und summary sind immer enthalten. Fügen Sie toll_alternative hinzu (kostenpflichtige Tarife; impliziert tolls), um zusätzlich eine zweite, mautfreie Route zu berechnen und den Vergleich zu bepreisen — siehe Mautbewusste Alternative; dies wird als 2 Routing-Aufrufe abgerechnet. Die Mautberechnung verursacht zusätzliche Upstream-Kosten und ist daher nur auf Anfrage aktiv. |
| currency | string | ISO-4217-Währung für Mautgebühren — nur wirksam mit include: ["tolls"]. Weglassen, um die native Währung jedes Mautsystems zu erhalten. |
| enrichment | object | Feintuning des Warnungsfilters nach dem Routing — keines dieser Felder wird an die Routing-Engine übermittelt. Unterfelder: exclude_types, min_severity, buffer_m (10–1000, Standard 100), clearance_pad_m (0–1, Standard 0.15), skip_temporal_filter, max_distance_m. |
| cargo | object | Ladungsmetadaten, auf der gespeicherten Route abgelegt. Unterfeld: hazmat_class (ADR-Klasse, z. B. "1.3D"). |
| truck.permit_number | string | Schwerlast-/Sondertransport-Genehmigungsnummer. In der Antwort zurückgegeben. |
| customer_route_id | string | Beliebiger Korrelationsschlüssel (≤128 Zeichen). Wird wortwörtlich zurückgegeben. |
| tags | array | Frei wählbare Labels für Flotten-/Lane-Analyse (max. 16 Einträge, jeweils ≤64 Zeichen). |
curl -X POST -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ https://api.napspan.com/api/v1/routing/route \ -d '{ "origin": { "lat": 52.5200, "lng": 13.4050 }, "destination": { "lat": 48.1351, "lng": 11.5820 }, "truck": { "profile": "tractor", "weight_t": 20, "height_m": 4.0 }, "include": ["tolls"], "currency": "EUR" }'
{
"route_id": "rt_01HXYZ4K8Q2V7R9N3M5P6T8W0E",
"expires_at": "2026-05-18T14:32:00Z",
"routes": [
{
"summary": {
"distance_km": 585.4,
"duration_min": 352,
"toll_costs": [ { "currency": "EUR", "value": 38.70 } ]
},
"geometry": {
"type": "LineString",
"coordinates": [
[13.4050, 52.5200],
[12.3700, 51.3400],
[11.5820, 48.1351]
]
},
"warnings": [
{
"type": "bridge_clearance",
"severity": "critical",
"feature_id": "DE-bridge-A9-K1247",
"name": "A9 Überführung bei Leipzig",
"latitude": 51.3400,
"longitude": 12.3700,
"clearance_m": 4.0,
"truck_height_m": 4.2,
"message": "Ausgeschilderte Durchfahrtshöhe liegt unter der angefragten Fahrzeughöhe."
}
]
}
]
}Mautbewusste Alternative
Fügen Sie toll_alternative zu include hinzu (es impliziert tolls), und die Antwort erhält einen toll_alternative-Block auf oberster Ebene: eine zweite Route, die unter Vermeidung von Mautstraßen berechnet wird, plus den bepreisten Vergleich — wie viele zusätzliche Meter und Sekunden der mautfreie Weg kostet und wie viel Mautgeld pro Währung er einspart. So kann ein Disponent in einer einzigen Anfrage abwägen: „Maut zahlen oder außen herum fahren“.
Abrechnung: Da hierbei eine zweite Route berechnet wird, wird dies als 2 Routing-Aufrufe gezählt (die primäre Route + die mautfreie Alternative) — oder als 1, wenn die gesamte Antwort aus dem Cache bedient wird. Die Funktion ist nur in kostenpflichtigen Tarifen verfügbar; eine Anfrage im Free-Tarif liefert die primäre Route plus toll_alternative_omitted: "plan_upgrade_required". Kann die Alternative aus einem anderen Grund nicht erzeugt werden, wird dennoch die primäre Route zurückgegeben, mit dem Grund in toll_alternative_omitted (quota_exhausted, upstream_error oder no_alternative).
"toll_alternative": { "summary": { "distance_m": 372000, "duration_s": 13800, "toll_costs": [] }, "geometry": { "type": "LineString", "coordinates": [ /* … */ ] }, "extra_distance_m": 22000, "extra_duration_s": 1200, "savings": [ { "currency": "EUR", "value": 38.70 } ], "cached": false }
Warnungstypen
Jeder Eintrag in warnings[] trägt einen type, einen severity (info / warning / critical), die Distanz entlang der Route, eine voraussichtliche Ankunftszeit und einen typspezifischen properties-Block. Nutzen Sie das enrichment-Objekt, um nach Schweregrad zu filtern oder Typen wegzulassen, die Sie nicht interessieren. Die Verfügbarkeit jedes Typs hängt davon ab, was der NAP für diesen Korridor veröffentlicht.
| Typ | Typischer Schweregrad | Wird ausgelöst, wenn |
|---|---|---|
| bridge_clearance | critical | Ausgeschilderte Durchfahrtshöhe < Fahrzeughöhe + clearance_pad_m, oder Tragfähigkeit < Fahrzeuggewicht |
| truck_restriction | critical | Eine ausgeschilderte Höhen-/Breiten-/Längen-/Gewichtsbeschränkung auf der Route liegt unter dem Wert des LKW (pro Dimension markiert) |
| weight_restriction | critical | Eine ausgeschilderte Gewichtsbeschränkung auf der Route liegt unter dem Fahrzeuggewicht |
| traffic_event | critical–info | Ein Live-RTTI-/SRTI-Vorfall, eine Sperrung oder ein Bauarbeitenereignis schneidet den Korridor innerhalb des Reisefensters |
| future_construction | warning | Geplante Bauarbeiten überschneiden sich an dieser Stelle der Route mit der voraussichtlichen Reisezeit |
| special_event | info | Eine geplante Sperrung oder ein Sonderereignis berührt die Route |
| alert | info | Eine allgemeine Warnung der Zuständigkeit gilt entlang des Korridors |
| weather | info | Wetterbedingungen / Warnungen, die von Stationen nahe der Route gemeldet werden |
| border_crossing | critical–info | Ein Grenzübergang liegt auf der Route. Sofern der Datenanbieter eine Wartezeit für die Nutzfahrzeugspur meldet, richtet sich die Dringlichkeit danach (info unter 15 Min., warning ab 15, critical über 45 oder bei geschlossenem Übergang) |
ADR-Tunnelkategorie-Beschränkungen werden vom Router selbst angewandt (über die Tunnelkategorie und Gefahrgutklasse des LKW), sodass verbotene Tunnel in der Routengeometrie gemieden statt als Warnung gemeldet werden. Aktivieren Sie den separaten features[]-Kanal mit enrichment.include_features, um zusätzlich nahegelegene Einrichtungen entlang der Route zu erhalten — truck_parking, truck_rest_areas, LKW-taugliche rest_areas, service_plazas und ev_charging. Die Anzahl der gleichzeitig anforderbaren Einrichtungstypen ist tarifabhängig begrenzt (Free: keine; das Limit steigt mit dem Tarif; Enterprise: unbegrenzt) — Ihr Limit wird als routing_max_feature_types unter GET /api/v1/customer/plans veröffentlicht. Eine Überschreitung führt zu 403 feature_types_limit.
Lenk- und Ruhezeiten-Planung
Fügen Sie einen truck.hos-Block hinzu — die aktuellen Lenk- und Ruhezeiten des Fahrers bei Abfahrt — und die Antwort erhält einen hos[]-Kanal: die Punkte, an denen der Fahrer nach der gewählten Regelung eine Pause einlegen oder die Fahrt beenden muss, jeweils mit den vor diesem Limit noch erreichbaren LKW-Parkplätzen und Rastplätzen. Abgedeckt sind die EU (Verordnung 561/2006), die USA (FMCSA) und Kanada (südlich und nördlich des 60. Breitengrads — canada_south / canada_north), und es ist in jedem Tarif kostenlos. Lassen Sie ruleset weg, um auf die Region Ihres Deployments zurückzufallen (hier eu).
Jedes *_remaining_s-Feld ist die verbleibende Zeit in Sekunden gegen das jeweilige Limit — lassen Sie eines weg, um einen ausgeruhten Fahrer anzunehmen. Ein wiederverwendbares LKW-Profil sollte nur ruleset speichern; senden Sie die fahrtbezogenen Zähler inline.
"truck": { "profile": "tractor", "weight_t": 20, "height_m": 4.0, "hos": { "ruleset": "eu", "drive_remaining_s": 32400, "since_break_s": 9000 } }
"hos": [ { "reason": "break_required", "distance_along_route_m": 112000, "projected_time": "2026-05-18T13:30:00Z", "legal_deadline": "2026-05-18T13:30:00Z", "feasible": true, "suggested_stops": [ { "type": "truck_parking", "name": "Autohof Montabaur A3", "distance_along_route_m": 106000, "available_spots": 22, "capacity": 45, "as_of": "2026-05-18T13:25:00Z" } ] } ], "hos_summary": { "adjusted_arrival_time": "2026-05-19T02:10:00Z", "delay_s": 39600, "meets_arrival_window": false }
reason ist einer von break_required, drive_limit, duty_window oder cycle_limit. suggested_stops sind zuerst nach freien Plätzen, dann nach Nähe zur Frist sortiert, damit der Fahrer die meiste legale Fahrzeit ausschöpft, bevor er anhält; wenn ein Parkplatz-Feed die Belegung meldet, trägt jeder Halt available_spots / capacity, und feasible: false bedeutet, dass vor diesem Limit jeder erreichbare Parkplatz voll (oder keiner erreichbar) ist. hos_summary fasst die Projektion gegen Ihre Ankunftszeit zusammen — adjusted_arrival_time ist die Ankunft nach den vorgeschriebenen Ruhezeiten, delay_s die dadurch hinzugefügte Zeit und meets_arrival_window (nur vorhanden, wenn Sie arrival_time senden), ob der Fahrer dieses Zeitfenster noch legal einhält. Ein unbekanntes ruleset liefert 400 invalid_hos_ruleset.
Gespeicherte Routen
Jeder Aufruf wird unter seiner route_id automatisch 30 Minuten lang gespeichert. Rufen Sie die Route innerhalb dieses Zeitfensters jederzeit über GET /api/v1/routing/route/saved/{id} erneut ab, um die Warnungen gegen den aktuellen Live-Zustand neu zu bewerten — solche Refetches verbrauchen kein Routing-Kontingent. Um eine Route über die 30 Minuten hinaus zu behalten, rufen Sie POST /api/v1/routing/route/saved/{id}/persist auf; dauerhaft gespeicherte Routen werden auf das Slot-Limit Ihres Tarifs angerechnet.
Rufen Sie Points of Interest entlang einer gespeicherten Route bei Bedarf über GET /api/v1/routing/route/saved/{id}/features?types=cameras,fuel_stations,truck_parking ab. Dies ist die bedarfsgesteuerte Ergänzung zu include_features: Der Aufruf verbraucht kein Routing-Kontingent und liefert die angeforderten POI-Typen — nach Entfernung entlang der Route sortiert — einschließlich Verkehrskameras und Tankstellen, die nur hier und nicht im eingebetteten features[]-Kanal verfügbar sind (beide sind dichte landesweite Ebenen, die den synchronen Routing-Aufruf verlangsamen würden). Sofern ein nationaler Datenfeed Preise pro Tankstelle veröffentlicht, werden diese in den properties des Features mitgeliefert. Jedes Feature ist mit distance_along_route_m, dem senkrechten detour_m-Abstand zur Route und der side (left/right) der Fahrtrichtung versehen. Die Anzahl unterschiedlicher Typen unterliegt demselben routing_max_feature_types-Limit, und die Ergebnisse werden pro Route zwischengespeichert und wie ein Refetch ratenbegrenzt.
Wiederverwendbare LKW-Profile
Wenn Sie dieselbe Handvoll Fahrzeuge immer wieder routen, speichern Sie jeden LKW einmal, statt seinen vollständigen Block bei jedem Aufruf erneut zu senden. Erstellen und verwalten Sie benannte Profile in Ihrem Portal unter Meine LKW und verweisen Sie dann per ID über truck.profile_id auf eines:
curl -X POST -H "X-API-Key: $KEY" \ -H "Content-Type: application/json" \ https://api.napspan.com/api/v1/routing/route \ -d '{ "origin": { "lat": 48.2082, "lng": 16.3738 }, "destination": { "lat": 48.3069, "lng": 14.2858 }, "truck": { "profile_id": "9f1c2e7a-6b3d-4a21-9f0e-2c5d8b7a1e34", "weight_t": 38 } }'
Der Server lädt das gespeicherte Profil und führt alle inline mitgesendeten truck.*-Felder tief zusammen — Inline-Werte gewinnen Feld für Feld, sodass Sie ein Basisprofil behalten und z. B. weight_t für eine beladene Fahrt überschreiben können. Der vollständig aufgelöste LKW-Block wird als resolved_truck zurückgegeben, sodass Sie genau bestätigen können, was die Routing-Engine gesehen hat:
{
"route_id": "rt_01HXYZ4K8Q2V7R9N3M5P6T8W0E",
"resolved_truck": {
"profile_id": "9f1c2e7a-6b3d-4a21-9f0e-2c5d8b7a1e34",
"profile": "tractor",
"weight_t": 38,
"height_m": 4.0,
"axle_count": 5
},
"routes": [ /* … */ ]
}Eine unbekannte ID liefert 400 profile_not_found. Ein gespeichertes Profil darf selbst kein profile_id enthalten.
Erweiterte Vermeidung & Routendetails
Über avoid hinaus akzeptiert die Anfrage feinere Routensteuerungen: avoid_areas (Sperrung von Bounding-Box-, Kreis- oder Polygon-Sperrzonen), avoid_zones (environmental, congestion_pricing), avoid_truck_roads, avoid_countries sowie das striktere exclude_countries (ISO-3-Codes) und details[] für streckenabschnittsbezogene Straßenattribute (Tempolimits, Functional Class, Fahrspuren …). Jede Route trägt außerdem die notices[] des Routing-Engines selbst — Hinweise wie violatedVehicleRestriction, wenn kein vollständig regelkonformer Weg existiert. Die vollständige Feldliste finden Sie in der Referenz.
Vollständiges Request-/Response-Schema (alle LKW-Profilfelder, alle Warnungs-Typen, Fehler-Envelopes): siehe die interaktive Referenz unter /reference.html.
Funktionsgruppen
60+ Funktionstypen, organisiert in 16 Gruppen. Verwenden Sie die id als group-Parameter bei /features, um alle Mitglieder in einer einzigen Anfrage abzurufen.
| Gruppen-ID | Name | Mitglieder |
|---|---|---|
| imagery | Bildmaterial | cameras |
| weather | Wetter & Umwelt | weather_stations, regional_weather, weather_forecasts, weather_alerts, wind_warnings |
| road_conditions | Straßenzustand | road_conditions, ice_roads, snow_plans |
| traffic_performance | Verkehrsfluss | traffic_segments, speed_data, travel_times, express_lanes, hov_lanes |
| planned_events | Geplante Ereignisse & Sperrungen | workzones, future_construction, future_roadwork, special_events, seasonal_loads |
| alerts_advisories | Warnungen & Hinweise | alerts, emergency_alerts, advisories, general_info |
| wildfires | Waldbrände | wildfires, wildfire_incidents, wildfire_perimeters |
| trucking | LKW-Verkehr & Nutzfahrzeuge | truck_restrictions, weight_restrictions, bridge_clearances, truck_routes, freight_corridors, truck_parking, truck_rest_areas, weigh_stations, inspection_stations |
| traveler_services | Reisedienste & POIs | rest_areas, service_centres, info_centres, visitor_locations, parks, communities, carpool_lots, airports |
| fuel_charging | Kraftstoff & Ladung | ev_charging, alt_fuel_stations |
| borders | Grenzübergänge | border_crossings, ports_of_entry |
| ferries | Fähren | ferries, coastal_ferries |
| transit | Öffentlicher Verkehr | transit_hubs, transit_stops |
| tolls | Maut | tolls |
| static_infrastructure | Infrastruktur & Überwachung | bridges, signs, roundabouts, speed_cameras |
| operations | Betrieb | service_vehicles |
Funktionstypen
Übergeben Sie einen dieser Werte als type-Parameter an /features.
Ereignistypen
| Typ | Schweregradbereich | Beschreibung |
|---|---|---|
| incident | moderate–critical | Unfälle, liegengebliebene Fahrzeuge, Gefahren |
| construction | minor–moderate | Straßenarbeiten, Wartung, Asphaltierung |
| closure | major–critical | Vollsperrungen |
| weather | moderate–critical | Wetterbedingte Fahrbahnauswirkungen |
| special_event | minor–moderate | Geplante Veranstaltungen (Paraden, Rennen) |
| advisory | minor–moderate | Reisehinweise, Warnungen |
| restriction | minor–moderate | Gewichts-, Höhen-, Geschwindigkeitsbeschränkungen |
Tarife & Limits
| Limit | Free (14-Tage-Testphase) | Starter (29 €/Monat) | Pro (99 €/Monat) | Enterprise |
|---|---|---|---|---|
| RPM | 60 | 300 | 1.000 | 5.000 |
| Tägliche Anfragen | 1.000 | 50.000 | 500.000 | Unbegrenzt |
| API-Schlüssel | 1 | 3 | 10 | 50 |
| Zuständigkeitsbereiche/Anfrage | 2 | 10 | Unbegrenzt | Unbegrenzt |
| Ergebnisse/Seite | 100 | 500 | 1.000 | Unbegrenzt |
| GeoJSON-Export | Nein | Ja | Ja | Ja |
| Analytik | Nein | Nein | Ja | Ja |
| LKW-Korridor | Nein | Nein | Ja | Ja |
| Datenverzögerung | 15 Min. | Echtzeit | Echtzeit | Echtzeit |