GBFS 3.0 Feeds
GBFS 3.0 is the spec the MobilityData validator now checks against, and most new tier-1 city permits reference it explicitly. Levy Fleets publishes both feeds in parallel:
| Version | Base URL | Status |
|---|---|---|
| GBFS 2.3 (legacy) | /api/gbfs/{subaccountId}/... | Untouched. Still available for consumers that haven't migrated. |
| GBFS 3.0 | /api/gbfs/v3/{subaccountId}/... | Active. Validated against MobilityData's GBFS validator with no warnings. |
No migration required
The legacy v2 feed continues to publish at its existing URL. Existing consumers don't have to change anything; cities that require GBFS 3.0 use the new /v3/ URL.
Feed root — gbfs.json
curl https://fleets.levyelectric.com/api/gbfs/v3/<subaccountId>/gbfs.json
Returns the discovery document with paths to every other feed file:
{
"last_updated": "2026-05-18T12:00:00Z",
"ttl": 60,
"version": "3.0",
"data": {
"feeds": [
{ "name": "manifest", "url": "..." },
{ "name": "system_information", "url": "..." },
{ "name": "vehicle_types", "url": "..." },
{ "name": "vehicle_status", "url": "..." },
{ "name": "station_information", "url": "..." },
{ "name": "station_status", "url": "..." },
{ "name": "system_regions", "url": "..." },
{ "name": "system_pricing_plans", "url": "..." },
{ "name": "geofencing_zones", "url": "..." },
{ "name": "system_alerts", "url": "..." }
]
}
}
What's new vs GBFS 2.x
| GBFS 2.x | GBFS 3.0 | Why it matters |
|---|---|---|
free_bike_status.json | vehicle_status.json | Includes vehicle_type_id ref so consumers can filter by class. |
| Time fields as POSIX epoch | RFC3339 strings | Easier for humans and validators; matches MDS 2.0. |
Languages via URL prefix (/en/, /es/) | Declared per-feed in manifest.json | One feed root serves all supported languages. |
vehicle_types.json optional | Required and structured | Carries max_range_meters, return_constraint, propulsion_type. |
No system_regions.json | Required when the fleet covers multiple regions | Lets cities draw their boundary onto an existing taxonomy. |
geofencing_zones.json has flat rules | Rules can scope to vehicle_type_id | Different zones for scooters vs ebikes in the same fleet. |
station_information lacks per-class capacity | Adds vehicle_type_capacity | Mixed-fleet stations get accurate capacity numbers. |
manifest.json
New in 3.0. Declares languages, the GBFS version, and the auth scheme (if any). Levy's manifest is generated from the subaccount's default_language plus any languages with at least one localized field.
{
"last_updated": "2026-05-18T12:00:00Z",
"ttl": 60,
"version": "3.0",
"data": {
"datasets": [
{
"system_id": "levy-<subaccountId>",
"versions": [
{ "version": "3.0", "url": ".../v3/<subaccountId>/gbfs.json" },
{ "version": "2.3", "url": ".../<subaccountId>/gbfs.json" }
]
}
]
}
}
The manifest is what tells discovery aggregators (MobilityData, transit apps) that both 2.x and 3.0 are available for the same system.
vehicle_status.json
Replaces free_bike_status.json. Each row carries a vehicle_type_id that references vehicle_types.json:
{
"version": "3.0",
"last_updated": "2026-05-18T12:00:00Z",
"ttl": 60,
"data": {
"vehicles": [
{
"vehicle_id": "abc123",
"vehicle_type_id": "scooter_standard",
"lat": 40.0149,
"lon": -105.2705,
"current_range_meters": 18000,
"is_reserved": false,
"is_disabled": false,
"last_reported": "2026-05-18T11:59:47Z"
}
]
}
}
The vehicle's vehicle_type_id flows from vehicles.model_id -> vehicle_models.gbfs_type_id. Set the latter under Settings -> Vehicle Models when you import new SKUs.
geofencing_zones.json — operator + policy zones merged
This is the file where city compliance shows up in the public feed. It contains every operator zone (parking, no-parking, slow, no-go, ride zones) plus every active policy_geofences row for the subaccount. Each feature emits the right vehicle_type_id per rule per MDS Policy.
Order matters: features are sorted by priority descending so consumers that pick the "first match" get the strictest rule. See Stacked Geofence Priority.
{
"version": "3.0",
"last_updated": "2026-05-18T12:00:00Z",
"ttl": 60,
"data": {
"geofencing_zones": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "Boulder Pearl Street No-Ride",
"rules": [
{
"vehicle_type_ids": ["scooter_standard"],
"ride_allowed": false,
"ride_through_allowed": false
}
],
"priority": 950,
"source": "city",
"source_jurisdiction_id": "boulder-co"
},
"geometry": { "type": "Polygon", "coordinates": [ ... ] }
}
]
}
}
}
The priority, source, and source_jurisdiction_id properties are Levy extensions on top of the GBFS schema — they're ignored by validators and consumed by clients (including our own mobile app) that understand the stack semantics.
system_regions.json
New in 3.0. Useful when a single subaccount operates across multiple distinct geographic regions (e.g., separate campuses or boroughs). Levy emits one region per mds_jurisdictions row by default; you can edit names and language labels under Compliance -> Jurisdictions -> Edit -> Regions.
system_alerts.json
Carries operator-published alerts (planned outages, special events, weather restrictions). Currently driven by the Settings -> Alerts UI; tied to subaccount, not per-jurisdiction.
Caching
Like the MDS feed, GBFS 3.0 endpoints are edge-cached for 60 seconds (Cache-Control: public, s-maxage=60). The ttl value in each file's payload matches the cache window.
Validator configuration
Use MobilityData's gbfs-validator for end-to-end checks:
gbfs-validator https://fleets.levyelectric.com/api/gbfs/v3/<subaccountId>/gbfs.json
A clean run reports Errors: 0, Warnings: 0. Common warnings to expect when first onboarding:
vehicle_type_idmissing on a vehicle — setvehicle_models.gbfs_type_idfor every model in your fleet.system_regions.jsonempty — add at least onemds_jurisdictionsrow, or remove the file fromgbfs.jsonif you don't operate across multiple regions.pricing_plansmissing — set at least one row inpricing_plansfor the subaccount.
How v2 and v3 stay in sync
Both feeds read from the same underlying tables (vehicles, vehicle_models, zones, policy_geofences, stations, pricing_plans). There is no separate write path for v3, so a change in the dashboard appears in both feeds at the next 60-second cache cycle.
The only file that lives only in v3 is manifest.json and system_regions.json. Removing the v3 feed (if a city only needs v2.x) is just a matter of not pointing them at the /v3/ URL.
What's next
- Policy Ingestion from Cities — where the policy geofences merged into
geofencing_zones.jsoncome from. - Stacked Geofence Priority — the priority ladder applied when zones overlap.
- MDS Provider Setup — the signed MDS endpoints that cities consume alongside GBFS.
Running a fleet on this hardware?
Levy Fleets runs scooters, e-bikes, mopeds and golf carts on the IoT hardware you already have, with integration pages for 29 vendors including Segway, Okai, Omni, Queclink, Invers and Comodule. Keyless unlock, geofencing, rider payments and rider support are included, and the Managed plan is a share of revenue with no per-vehicle software fee.