Drop one URL into your mapping tool — points appear on your map, refreshed every 15 minutes.
Each link returns a GeoJSON FeatureCollection. Pick the smallest scope you need; smaller files are faster.
/munich.geojson, /amsterdam.geojson, /cambridge.geojson, /san_francisco.geojson, /tokyo.geojson._verified variant
holding only the reviewer-confirmed hazards, which is usually the one
you want. e.g.
/shapefiles/munich_shapefile.zip,
/shapefiles/munich_verified_shapefile.zip.
Each contains .shp/.shx/.dbf/.prj/.cpg and a README.
Rebuilt daily; the GeoJSON above is the live source.
.shp into your map. The .prj is included, so you are not asked for a coordinate system.ogr2ogr -f "ESRI Shapefile" munich.shp /vsicurl/https://alerts.blossomedge.ai/munich_verified.geojson
Two things to know if you convert it yourself. Shapefile field names cannot
exceed 10 characters, so user_confirmed silently becomes
user_confi — in our archives it is named confirmed
deliberately. And manual and user_confirmed are only
present on the features that have them, so a converter that infers its schema
from the first few records will drop those columns; download the file before
converting rather than streaming it. If shapefile is not a hard requirement,
GeoPackage avoids both problems — same command with
-f "GPKG", or ask us and we will publish one.
https://alerts.blossomedge.ai/london.geojson) and click Add Layer.label field if you want to colour verified vs unverified separately.label.map.addSource('gobike-alerts', {
type: 'geojson',
data: 'https://alerts.blossomedge.ai/london.geojson'
});
map.addLayer({
id: 'gobike-alerts-layer',
type: 'circle',
source: 'gobike-alerts',
paint: {
'circle-radius': 4,
'circle-color': [
'case', ['==', ['get', 'label'], 'p'], '#16a34a', '#94a3b8'
],
'circle-opacity': 0.7
}
});
fetch('https://alerts.blossomedge.ai/london.geojson')
.then(r => r.json())
.then(data => {
L.geoJSON(data, {
pointToLayer: (f, latlng) => L.circleMarker(latlng, {
radius: 4,
color: f.properties.label === 'p' ? '#16a34a' : '#94a3b8',
fillOpacity: 0.7
})
}).addTo(map);
});
import geopandas as gpd
gdf = gpd.read_file('https://alerts.blossomedge.ai/london.geojson')
verified = gdf[gdf['label'] == 'p']
print(f'{len(verified)} verified out of {len(gdf)}')
gdf.plot(column='label', markersize=2, legend=True)
The data file is regenerated every 15 minutes server-side. CloudFront caches for 60 seconds, so a polite tool that polls hourly will always be at most ~16 minutes behind real time. Tools that auto-refresh (ArcGIS, QGIS, Mapbox) will pick up new alerts on their own polling schedule.
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [lng, lat] },
"properties": {
"timestamp": 1745234567000, // Unix ms, UTC
"label": "p" // "p" = verified TP; anything else = unverified
}
}
Coordinate system is WGS84 (EPSG:4326). Coordinates are in [longitude, latitude] order — the GeoJSON convention.
Free to use with attribution: "GoBike hazard alerts, BlossomEdge". All records are anonymised — no userId, no runId, no rider information of any kind. Please don't attempt to re-identify riders.
If you'd like a per-client URL scoped to specific boroughs or cities (so it's "your" feed and won't change scope without notice), email contact@blossomedge.ai.