BlueBikes API Feeds Guide#
What Was Established#
- Comprehensive breakdown of BlueBikes GBFS (General Bikeshare Feed Specification) endpoints.
- JSON structure analysis for static (
station_information) and real-time (station_status) feeds. - JavaScript patterns for fetching, joining, and displaying station data.
Key Decisions#
- Base URL:
https://gbfs.lyft.com/gbfs/1.1/bos/en/ - Primary Feeds:
station_information(static map/location data) andstation_status(live availability) are the core feeds for real-time tracking. - Join Strategy: Match
station_idfields between static and status feeds to combine location metadata with live bike/dock counts.
Current Configuration#
Core GBFS Endpoints#
| Feed | Purpose |
|---|---|
station_information |
Static station list, names, IDs, coordinates, capacity, kiosk info |
station_status |
Real-time bike/dock counts, station active/inactive status, last reported timestamp |
system_information |
System metadata (operator, name, URLs) |
system_regions |
Regional breakdowns for color-coding/mapping |
system_hours |
Operating hours |
system_calendar |
Start/end years, holidays |
gbfs_versions |
Available GBFS versions |
free_bike_status |
Free-floating bike locations |
ebikes_at_stations |
Real-time e-bike counts per station |
system_pricing_plans |
Membership & pricing details |
system_alerts |
Current advisories |
Data Structure Examples#
station_information
{
"last_updated": 1742774947,
"ttl": 60,
"version": "1.1",
"data": {
"stations": [
{
"station_id": "1",
"name": "MIT at Mass Ave / Amherst St",
"short_name": "A31006",
"lat": 42.358177,
"lon": -71.092639,
"region_id": "10",
"capacity": 19,
"rental_methods": ["KEY", "CREDITCARD"],
"eightd_has_key_dispenser": false,
"has_kiosk": true
}
]
}
}station_status
{
"last_updated": 1742775312,
"ttl": 10,
"version": "1.1",
"data": {
"stations": [
{
"station_id": "1",
"num_bikes_available": 2,
"num_ebikes_available": 0,
"num_bikes_disabled": 0,
"num_docks_available": 16,
"num_docks_disabled": 1,
"is_installed": 1,
"is_renting": 1,
"is_returning": 1,
"last_reported": 1742775275,
"eightd_has_available_keys": false
}
]
}
}JavaScript Fetch & Join Pattern#
async function getBlueBikesStations() {
try {
const [infoResponse, statusResponse] = await Promise.all([
fetch('https://gbfs.lyft.com/gbfs/1.1/bos/en/station_information.json'),
fetch('https://gbfs.lyft.com/gbfs/1.1/bos/en/station_status.json')
]);
const infoData = await infoResponse.json();
const statusData = await statusResponse.json();
const statusMap = new Map();
statusData.data.stations.forEach(status => {
statusMap.set(status.station_id, status);
});
const stations = infoData.data.stations.map(station => {
const status = statusMap.get(station.station_id) || {};
return {
station_id: station.station_id,
name: station.name,
short_name: station.short_name,
lat: station.lat,
lon: station.lon,
capacity: station.capacity,
region_id: station.region_id,
bikes_available: status.num_bikes_available || 0,
ebikes_available: status.num_ebikes_available || 0,
docks_available: status.num_docks_available || 0,
disabled_bikes: status.num_bikes_disabled || 0,
disabled_docks: status.num_docks_disabled || 0,
is_renting: status.is_renting === 1,
is_returning: status.is_returning === 1,
last_reported: status.last_reported,
last_reported_date: status.last_reported
? new Date(status.last_reported * 1000).toLocaleString()
: null
};
});
stations.sort((a, b) => a.name.localeCompare(b.name));
return stations;
} catch (error) {
console.error('Error fetching BlueBikes data:', error);
}
}Historical Notes#
- Conversation date: 2026-02-13
- Focus was on understanding GBFS structure and building a JS fetch/join pattern for station IDs and names.
ttlvalues observed: 60s forstation_information, 10s forstation_status.
Open Questions#
- How to integrate this API into the existing MBTA Dashboard or Homelab status dashboard?
- Should station data be cached locally via n8n or Proxmox services?
Related Pages#
Sources#
ingested/chats/173-BlueBikes API Feeds Guide.md- BlueBikes GBFS Endpoint:
https://gbfs.bluebikes.com/gbfs/gbfs.json - DeepSeek Conversation (2026-02-13)