InfraNode.dev
MCP InfraNode is also available as an MCP server for AI assistants like Claude and ChatGPT.

Changelog

Every change to the InfraNode API that is relevant to using it: new data types, newly covered cities, behaviour changes, fixes and announced deprecations. Newest first.

  1. Removed

    ICU bed data removed (DIVI intensive care registry)

    The endpoint /cities/{slug}/icu-live is discontinued without replacement, as are the icu_capacity field and the icu_latest meta field on /cities/{slug}/health. The reason is the purpose limitation attached to the data: the Robert Koch Institute objected to redistribution and live pass-through of DIVI intensive care registry data. Under Section 13(7) of the German Infection Protection Act the data is collected solely to assess hospital capacity utilisation, which does not cover passing it on to third parties. The institute is also considering discontinuing the data entirely. The endpoint had already stopped serving data (source_status disabled). All other hospital figures under /health remain unchanged.

  2. Changed

    Uniform English source names (meta.source)

    30 source names in meta.source, city_source and the sources list now carry uniform English names. The most important renames: hamburg_baustellen, muenchen_baustellen, dortmund_baustellen, rostock_baustellen and bremen_baustellen are now *_roadworks; koeln_baustellen_live is koeln_roadworks_live, koeln_ereignisse_live is koeln_incidents_live, koeln_verkehr is koeln_road_events; berlin_verkehrsmeldungen and hannover_verkehrsmeldungen are *_traffic_reports; hamburg_verkehrslage is hamburg_traffic_situation; kiel_zaehlstellen is kiel_counting_stations; the eight *_radzaehl sources (muenchen, leipzig, hamburg, berlin, stuttgart, koeln, essen, duesseldorf) are *_bike_counts; denkmal is heritage, baumkataster is tree_cadastre, koeln_wartezeiten is koeln_wait_times, hochwasser is lhp, feiertage is holidays; the Munich family muenchen_parkhaeuser/parkraum/park_ride/mobilitaetspunkte/radparken is now muenchen_parking, muenchen_parking_onstreet, muenchen_park_and_ride, muenchen_mobility_points and muenchen_bike_parking. Because meta.source is a single value, no dual-name transition period is possible; the switch is hard. Stored and historical data with old names are normalized to the new names on read. Old INFRANODE_* environment variable names remain valid as aliases.

  3. Deprecated

    Consistent English field names across eleven data types

    Eleven data types now also carry their payload fields under canonical English names: flood (stand becomes as_of), fire-danger (bundesland becomes federal_state), election (granularity becomes coverage_granularity with the values city/partial instead of stadt/teilweise), icu-live (kreis_id/kreis_name/datum become district_id/district_name/report_date; this also applies to the icu_capacity payload under health), land-values (stichtag becomes reference_date), tax-rates (gewerbesteuer_hebesatz/grundsteuer_a/b/c/stichtag become trade_tax_rate/property_tax_a/b/c/reference_date), business-registrations (anmeldungen/abmeldungen/saldo/jahr become registrations/deregistrations/balance/year) and insolvencies (unternehmensinsolvenzen/uebrige_schuldner_insolvenzen/jahr become corporate_insolvencies/other_debtor_insolvencies/year). On top of that, the individual entries inside lists follow suit: road-events per city source (Munich, Rostock, Dortmund, Dresden/Leipzig, Hamburg; e.g. beschreibung becomes description, von/bis become start/end), the hospital list in icu-live (bezeichnung/ort/letzte_meldung become name/place/last_report), tree-cadastre (e.g. art_dtsch becomes species, pflanzjahr becomes planting_year; the capped sample per response is 225 instead of 350 trees during the transition period) and heritage (e.g. typ becomes type, bezeichnung becomes name). The old German fields keep carrying identical values until 31 August 2026 and will be removed afterwards. Clients should migrate to the new field names.

  4. Changed

    Consistent English endpoint names for live routes

    Seven live routes now use English canonical paths: /live/{city}/baustellen becomes /live/{city}/roadworks, /live/{city}/ereignisse becomes /live/{city}/incidents, /live/berlin/verkehrsmeldungen and /live/hannover/verkehrsmeldungen become .../traffic-reports, /live/koeln/umweltzone becomes /live/koeln/low-emission-zone, /live/kiel/zaehlstellen becomes /live/kiel/counting-stations and /live/hamburg/verkehrslage becomes /live/hamburg/traffic-situation. The old German paths remain available as deprecated aliases with an unchanged envelope and carry a Deprecation header plus a Link header pointing to the respective successor. Clients should migrate to the new paths.

    Reference: getLiveHamburgTrafficSituation

  5. Fixed

    Hamburg: live traffic situation available again

    The real-time traffic situation for Hamburg (api.hamburg.de, OGC API Features) had been temporarily disabled since mid-July after upstream requests repeatedly timed out; during that period the endpoint reported source_status disabled. Following feedback from the Hamburg state agency for geo-information (LGV) confirming no IP block and a reliably responding upstream, the source is active again since 1 August and delivers the network summary and congested road segments as before.

    Reference: getLiveHamburgVerkehrslage

  6. Added

    Council papers: Freiburg im Breisgau joins as the eighth city

    The council-papers data type now covers eight licence-cleared cities: Dresden, Cologne, Düsseldorf, Münster, Leipzig, Magdeburg, Osnabrück and, new, Freiburg im Breisgau. The city of Freiburg's council office confirmed the licence of its OParl endpoint in writing (Data licence Germany attribution 2.0); the corpus holds roughly 13,900 papers, motions and resolutions from 2014 onwards. Responses also carry data.total now, the full count for the active filters; previously only the page length (count) was included, so clients could not learn the corpus size without paging to the end.

    Reference: getCityCouncilPapers

  7. Added

    Bike parking Munich: 47,518 spaces available

    New endpoint /cities/{slug}/bike-parking serves the bike parking stock of a city. For Munich that is 3,233 facilities with 47,518 spaces, each with construction type, covering, lighting and a bike-and-ride flag. 1,972 facilities with 33,060 spaces sit at public transport stops, 316 are covered, 86 are double-deck racks. Cargo bike facilities are reported separately (103 facilities, 281 spaces) because they are built for different vehicles. Plus the twenty largest locations, the biggest being Riesstrasse 69 with 392 spaces. Only the in-service stock is counted: the source also lists 156 planned, 306 removed and 25 out-of-service facilities in the same dataset. Counting their spaces would overstate today's bike parking by roughly 17 percent, so they are reported as separate figures. Source is the mobility department of the City of Munich (DL-DE/BY 2.0).

    Reference: getCityBikeParking

  8. Added

    Topic page for the sustainability and SDG indicators

    The sustainability data type now has a page of its own at /en/data/sustainability-api. It explains what the up to 53 municipal sustainability indicators contain, that the series runs from 2006 to 2023 and how the year filter ?from= and ?to= shrinks the response. It also states the difference in scope openly: district-free cities reach up to 53 indicators, cities inside a district fewer, because part of the measures is only collected at district level. Documentation only, the API is unchanged.

    Reference: getCitySustainability

  9. Added

    Nine more time-series data types from Wegweiser Kommune

    The Wegweiser dataset is now fully accessible. Until today only an eighth of it could be queried (sustainability); the rest sat unused in the store. Nine data types are new, all with a full time series: population-structure (age structure, 110 metrics, incl. a forecast to 2040), population-trend (70), municipal-finance (30), labour-market (labour market and commuters, 40), integration (26), childcare (20), education-stats (33), social-situation (17) and care (long-term care, 11). That makes 391 metrics per city available instead of 53. There is also a new year filter: every Wegweiser data type accepts ?from= and ?to= and then returns only that window. This matters for the large ones, population-structure weighs about 90 KB unfiltered. Without the filter nothing changes. Three data types are partially covered because the source does not publish them per municipality everywhere: childcare 83 cities, care 73, education-stats 70 (missing the cities that are part of a district). Existing data types are untouched: tax-rates, unemployment and indicators keep their own, partly more recent values.

    Reference: getCityPopulationStructure

  10. Added

    Six topic pages for the statistical data types

    After the live data types the statistical ones follow: new pages for municipal tax rates, population and density, crime statistics, road accidents, the labour market and business and insolvency data, each in German and English. Every page names the actual response fields, the source with its licence and the spatial resolution. That last point matters more here than for live data: crime statistics, accidents, labour market and business data are published per district, so for a city that is not a district of its own the district value applies. Tax rates, by contrast, are reported per municipality. Both facts are now on the pages instead of having to be inferred from the response.

  11. Added

    Six new topic pages and seven new MCP pages

    So far only nine of the 67 data types had a page of their own explaining what they contain, where they come from and under which licence they stand. New are EV charging, fuel prices, parking, roadworks, water levels and weather warnings, each in German and English with field list, coverage, source, licence and frequently asked questions. In parallel there are seven new pages for the matching MCP tools for AI assistants, among them charging, parking, weather warnings, solar, solar cadastre, procurement and council information. The topic pages now also link directly to the largest cities where the respective data type is actually available.

  12. Added

    New data type sustainability: SDG indicators as a time series

    New endpoint /cities/{slug}/sustainability serves municipal sustainability and SDG indicators from Wegweiser Kommune by Bertelsmann Stiftung: land take, local recreation areas, renewable energy in new residential buildings, broadband coverage, employment, education, social participation and more. The data is CC0 licensed and available for all 84 cities. What makes it different: every indicator carries its full TIME SERIES, typically 2006 to 2023, plus latest_year and latest_value for the most recent point. For the first time you can query a development instead of a single snapshot. Years without a value are absent from the series, a zero is never invented. 53 of the indicators are only published from district level upwards and are therefore missing for the 14 cities that are part of a district, such as Hanover, Aachen or Göttingen. Existing data types are untouched: indicators (INKAR/BBSR), tax-rates and unemployment keep their own, partly more recent values, and the datasets are deliberately not mixed.

    Reference: getCitySustainability

  13. Fixed

    Roadworks and traffic messages: fallback instead of 503

    If a source for roadworks, traffic messages or closures briefly fails, the last known state is now served for up to six hours instead of failing with 503. Such responses are recognisable by cache_status stale_on_error in the meta block. Until now only some sources had this window while equivalent sources in other cities had just two minutes, which caused brief 503s for the Hamburg roadworks on 26 July. Affected are Hamburg, Dortmund, Munich, Rostock, Berlin, Cologne, Saxony and Baden-Württemberg. Traffic flow gets 30 minutes as a flow value, because stale flow data says little. Freshness is unchanged everywhere, all sources stay minute-fresh. Deliberately excluded are departure times, shared vehicles and waiting times: a stale value would be misleading there, so an honest error remains.

  14. Changed

    Better signposts: 404 hint and example values

    Leaving out the /cities prefix, for example /api/v1/recklinghausen, now yields a 404 hint naming the correct path, as long as the segment really is a known city. Previously the similarity search suggested a data type with a similar name instead and pointed the caller the wrong way. Exonyms and short forms resolve to the canonical slug, so munich points at /api/v1/cities/muenchen. Separately, every required API parameter now carries a working example value. The code samples on the endpoint pages used to insert the word example there, which produced an error when copied and sent, for instance for stop_id of the live departures or type of the POIs. The parameter table now shows the example value in a column of its own. For the volatile GTFS-RT identifiers trip_id and route_id it also says where fresh ids come from and that an expired id is not an error but no_data.

  15. Changed

    MCP: transit_departures rejects trip stop ids gracefully

    Passing a trip_stop_id from a station board to the MCP tool transit_departures instead of a station id now returns a response with source_status no_data and a note on where valid stop ids come from, rather than a 400 from the live endpoint. The tool recognises the trip stop id pattern itself and no longer issues a request at all. Valid DELFI ids in the form de:AGS:id and purely numeric gtfs.de ids are unaffected. The live endpoint itself is unchanged: an invalid stop_id still yields a 400 there.

  16. Added

    Departure board: stop_id is now trip_stop_id

    In the station departure and arrival boards this field used to be called stop_id, although it identifies a single stop of one specific train run, not a station. The name collided with the stop id of the live departures under /live/{slug}/transit/departures, which expects a DELFI id in the form de:AGS:id. Passing the value from one endpoint to the other reliably produced a 400. The field is therefore now called trip_stop_id; stop_id keeps carrying the same value and is deprecated. The live endpoint's error message now names the mix-up explicitly and points to where valid stop ids come from.

    Reference: getCityStationDepartures

  17. Added

    Consistent field names across all data types

    The same concepts now use the same name everywhere, in snake_case and English: post_code, street, house_number, place, name, start, end, distance_km, power_kw, lat and lon. This affects charging stations (previously plz and ort), energy installations (plz, leistung_kw, einheit_typ), railway stations (zip), hospitals (zip, city), Cologne events (strasse, hausnummer, plz) and inner-city roadworks (bezeichnung, beginn, ende, art). Traffic messages from the Autobahn API additionally carry is_blocked as a real boolean, start_timestamp, delay_minutes, average_speed_kmh, abnormal_traffic_type, name, description_text plus bbox with lat and lon derived from the former comma string extent. Cologne roadworks gain event_type_label, the plain-text meaning of the former numeric code, taken straight from the service's own code list. The station catalog now calls the DB station category station_category, because category carries a text label in other data types, not a number. All changes are additive; the previous fields remain with identical values for now.

  18. Deprecated

    Deprecated: legacy field names and camelCase raw fields

    The former names plz, zip, strasse, hausnummer, ort, city, bezeichnung, beginn, ende, art, dist_km, leistung_kw, einheit_typ and the stop_id of the station boards (now trip_stop_id), the category in the station catalog (now station_category), as well as the camelCase raw fields of the Autobahn traffic messages (isBlocked, startTimestamp, delayTimeValue, averageSpeed, abnormalTrafficType, extent), are deprecated. They keep carrying the same value as their canonical counterparts and will be removed no earlier than 30 days after this entry. If you rely on them, switch to the new names before then.

  19. Fixed

    Departure times now carry a time zone

    planned_time in the departure and arrival boards used to come without a time zone (2026-07-25T10:01:00), which made it ambiguous. The value is station local time and now carries the matching offset (2026-07-25T10:01:00+02:00). Also fixed: empty address fields in the Cologne events came back as an empty string instead of null, and postal codes with a leading zero could lose that zero.

    Reference: getStationDepartures

  20. Added

    Fuel prices: address per station

    Individual stations in the fuel price payload now also carry street, house_number, post_code and place, the address reported to the German fuel price transparency unit (MTS-K). This makes a station identifiable without a map. post_code is always a five-character string, so leading zeros are preserved (01067). When the source reports no separate house number, it is often part of the street name ("Rödingsmarkt 14") and is split off, so street and house_number arrive separately. Stations without any house number keep house_number null. Purely additive, existing fields are unchanged.

    Reference: getCityFuelPrices

  21. Added

    Fuel prices: coordinates per station (map display)

    Individual stations in the fuel price payload now also carry lat and lon, the coordinate of the station itself. This makes the stations directly mappable without an extra lookup. Purely additive, existing fields are unchanged; when the source has no coordinate, lat and lon are null.

    Reference: getCityFuelPrices

  22. Changed

    Cologne: parking data now directly from the City of Cologne (Mobilithek)

    Cologne was previously served via the ParkenDD aggregator, whose Cologne feed has been frozen since 2021 and no longer delivered any data. Parking data now comes directly from the City of Cologne via Mobilithek (DATEX II, occupancy joined with facility master data, DL-DE/Zero 2.0, Tier A): 41 parking facilities with live occupancy, capacity, name and coordinates.

    Reference: getCityParking

  23. Added

    Parking in 14 more cities (DB BahnPark, nationwide)

    The /parking endpoint now covers 14 additional cities: Berlin, Bochum, Bonn, Bremen, Düsseldorf, Duisburg, Erfurt, Essen, Hannover, Mainz, Saarbrücken, Schwerin, Stuttgart and Wiesbaden. The source is DB BahnPark's station-adjacent parking facilities (DB API Marketplace, DL-DE/BY 2.0, Tier A). This is a static catalogue (location, name, total capacity, lot_type="station"): the source provides no numeric live occupancy (free), so that field stays null. Cities with their own live parking source (e.g. Cologne, Frankfurt, Hamburg) are unchanged.

    Reference: getCityParking

  24. Changed

    OSM POIs now from a weekly precompute (more stable)

    The POI and OSM infrastructure data types (pois, playgrounds, drinking-water, public-toilets, markets, parcel-lockers, post-offices, post-boxes, public-wifi, recycling-centres, government-offices, education) are now served from a periodic precompute of the OSM Germany extract (weekly) instead of being queried live. Envelope, fields and license (ODbL, Tier B) are unchanged; total_available still reports the real total. Benefit: no more dependency on a public live instance, hence noticeably more stable. If a city's data has not been computed yet, the route responds with 200 source_status="no_data" instead of an error.

    Reference: getCityPois

  25. Added

    Inner-city roadworks for Rostock

    The roadworks / traffic events data type now also covers Rostock (OpenData.HRO, CC0). Each roadwork comes with measure, utility, street, section, period and traffic impact.

    Reference: getCityRoadEvents

  26. Added

    Council papers now also for Magdeburg and Osnabrück

    The council-papers data type now covers Magdeburg (DL-DE/Zero-2.0) and Osnabrück (CC-BY-4.0) in addition to Cologne, Leipzig, Münster, Dresden and Düsseldorf, both via the standardized OParl interface. Available at /api/v1/cities/{city}/council-papers and via MCP through get_city_resource.

    Reference: get_city_resource

  27. Added

    Bike sharing for Kiel (SprottenFlotte)

    Kiel now has bike and scooter sharing: the SprottenFlotte runs on Donkey Republic (GBFS 3.0) and reports stations and availability just like the other sharing cities. The data is licensed CC0. This also brings first-time support for GBFS version 3.0 (localized name fields, num_vehicles_available).

    Reference: getCitySharing

  28. Added

    Tree cadastre for Hamburg and Kiel

    The tree cadastre now covers Hamburg and Kiel in addition to Berlin. Hamburg provides its street tree register (Landesbetrieb Geoinformation und Vermessung, DL-DE/BY-2.0), Kiel the trees on public ground (CC-BY-4.0). Each tree comes with location, species and crown diameter.

    Reference: getCityTreeCadastre

  29. Added

    Flood warnings for Hanover, Kiel and Magdeburg

    Flood warnings now also cover Hanover (Herrenhausen gauge, Leine), Kiel (Kiel-Holtenau, Baltic Sea, relevant for storm surges) and Magdeburg (Niegripp, Elbe). Each gauge reports warning level, water level and timestamp. Source is the joint German flood portals (LHP).

    Reference: getCityFlood

  30. Fixed

    Official weather warnings available again (new upstream)

    DWD shut down its old WarnApp interface, so the endpoint for official weather warnings briefly returned 503. Warnings are now fetched via the Bright Sky alerts API and thus remain the same official DWD data. Warning levels 1 to 4 are derived from the CAP severity; heat and UV warnings are still listed separately in special_warnings and do not count towards max_level. Note: start and end of individual warnings are now ISO 8601 timestamps instead of epoch milliseconds.

    Reference: getCityWeatherWarnings

  31. Fixed

    Live transit departures: delay-only updates and platform IDs now work

    The per-stop live departures endpoint returned no_data almost everywhere: the nationwide GTFS-RT feed mostly carries delays without absolute departure times, and exactly those entries were dropped. They are now served honestly (delay_s/delay_min set, departure_time and minutes_until = null) after the timed departures available e.g. in Berlin via the VBB feed. stop_id may now also be parent or platform level (de:AGS:nr or de:AGS:nr:area:platform); both resolve.

    Reference: getLiveTransitDepartures

  32. Added

    Council papers: complete data set for 5 cities (112,000+ documents)

    The new council-papers data type serves municipal council documents (motions, resolutions, drafts) via the standardized OParl interface for Cologne, Leipzig, Münster, Dresden and Düsseldorf. The historical backfill is now complete: more than 112,000 documents since 2020, including 48,000+ from Leipzig alone. New documents are added continuously. Available at /api/v1/cities/{city}/council-papers and via MCP through get_city_resource.

    Reference: get_city_resource

  33. Changed

    Docs: new navigation with task-based groups and a mobile drawer

    The docs menu is regrouped into Get started, Basics, API reference, AI & integrations and Project. The API reference now shows readable names instead of operationIds (the operationId appears on hover), and live endpoints sit inside their topic category with a LIVE badge instead of a separate section. The badge marks real-time data regardless of path, including fuel prices, parking occupancy, train departures and charging status. On mobile, a menu button in the top bar opens a drawer with only the active group expanded. All pages and URLs are unchanged.

  34. Changed

    Parking: staleness guard for frozen upstreams

    The ParkenDD cities now have a freshness guard: if an upstream has not delivered new occupancy timestamps for more than 48 hours, the endpoint returns no_data instead of stale values. This prevents months-old parking counts from looking current. A missing or unreadable timestamp defensively does not count as frozen.

    Reference: get_city_parking

  35. Added

    Bike counters: Düsseldorf added (8 cities)

    bike-counts now also serves the bicycle counting stations of Düsseldorf, bringing the data type to eight cities. Licence DL-DE/BY 2.0.

    Reference: get_city_bike_counts

  36. Changed

    City comparison: six more data types

    Comparing multiple cities in one call now additionally covers indicators, demographics, unemployment, tourism, charging status and weather warnings, on top of weather and air quality.

    Reference: compare_cities

  37. Added

    Roadworks and closures: Dresden and Leipzig

    road-events now serves roadworks and closures for Dresden and Leipzig from Saxony's SPERRINFOSYS. Licence DL-DE/BY 2.0.

    Reference: get_city_road_events

  38. Added

    InfraNode as a ChatGPT GPT and GPT action

    InfraNode is now available as a Custom GPT in the GPT Store and can be wired in as a GPT action via a curated actions OpenAPI, key-free and via URL import. See /en/chatgpt/.

  39. Added

    Live charging occupancy for all 84 cities

    New data type charging-status: the real-time occupancy of public charging points per city (available, occupied, charging, out of service), derived from the eRound feed (CC0). Complements the static charging point locations.

    Reference: get_city_charging_status

  40. Changed

    MCP server consolidated to 12 lean tools

    The hosted MCP server now bundles the 67 data types into 12 tools; the long-tail data types run through get_city_resource(slug, resource). Existing calls stay covered and the tool list is much shorter.

Older changes from before this changelog started are traceable in the commit history.