GBFS v2.3-RC is here to fix (some) of your problems
*Puede encontrar una traducción de este artículo al español aquí.*
*Vous pouvez trouver une version francophone de cet article ici.*
We have been loving watching all of those GBFS v2.2 feeds popping up all over the world – powering so many new trip planning integrations and making it easier for travelers to find their nearest shared bike, scooter, moped, or car!
But even though we love v2.2, GBFS was ready for a few improvements. Let us introduce you to v2.3-RC!
In a nutshell, v2.3-RC adds information about:
- Stations that have charging ability,
- Vehicle drop-off restrictions,
- Vehicle icons and brand information,
- Vehicle hold times, and
- Terms & privacy policy.
To make life a little easier on station-based systems, v2.3-RC also adds the ability to present pricing information by vehicle type instead of just by individual vehicle.
Let’s dig a little deeper into each of the changes. After that, we’ll provide data examples for the developers out there.
The changes in detail
Charging stations
Earlier versions of GBFS did not have a way to show that a station could offer vehicle charging. Unsurprisingly, we noticed a variety of different, non-standard solutions added onto standard GBFS datasets. v2.3-RC has added a simple way to indicate if a station provides vehicle charging. In the future, this will make it easier to represent programs that provide incentives for parking at a charging station or that require a rental be returned to a charging station.
Vehicle drop-off restrictions
Most shared bike, scooter, and moped services allow point to point rentals, unlike, for example, traditional car rentals which are picked up and dropped off at the same location. But as GBFS is extended to represent carsharing (with its universe of different operating models), and as shared mobility services increasingly include adaptive vehicle pilots (often with more restrictive rental rules), GBFS needed a way to represent drop-off restrictions.
v2.3-RC allows shared mobility providers to define if the vehicle’s return requirement is free floating (vehicle must be returned anywhere within the service area), roundtrip (vehicle must be returned at original rental station), or station (vehicle must be returned to any station within the service area).
Icons and brands
Public GBFS datasets make it easy for any trip planning application to make shared mobility services easier to find and use. But previous versions of GBFS did not provide a way to graphically represent different operators or vehicles, requiring extra work on the part of GBFS producers and consumers. v2.3-RC adds information about the shared mobility system logo and brand colors and about the vehicle type icons to help ensure consistent graphic representation (and therefore easy recognition by travelers!).
Vehicle hold times
Many shared mobility services allow a traveler to put a hold on a vehicle immediately in advance of a rental. The length of time that vehicle may be reserved is typically less than 30 minutes. During this time the vehicle cannot be rented by another user. If a ride is not initiated before the reserve time elapses, the vehicle is released and becomes available to other users. With v2.3-RC, GBFS can represent how long of a hold is allowed by vehicle type, making it easier for trip planning applications to provide travelers with options that may benefit from being able to hold a vehicle.
Terms and privacy policy
v2.3-RC includes fields for a shared mobility provider to share their terms and their privacy policy, making it easier for travelers to access that information when they’re considering a service.
Pricing for station-based systems
Like we said earlier, we’re thrilled to see v2.2 so widely adopted! v2.2 improved pricing information a lot (see our discussion about that here). One change v2.2 brought was to add a pricing plan id to information about an available bike, associating pricing plans with individual vehicles. The thinking was that doing this at the individual vehicle level would allow dynamic pricing based on the vehicle’s location – which it does! But that solution posed a challenge for station-based systems, since they are not required to publish the file with information about individual available bikes (they can publish that information at a station level instead). It also limited vehicles to a single pricing plan.
v2.3-RC allows pricing plans to be represented for vehicle types, allows for more than one pricing plan to apply to a vehicle type, and allows the shared mobility operator to define a default pricing plan to be used by trip planners in calculating the cost of a single trip.
Want more details? Read the section below!
Descriptions and code examples
Charging stations
v2.3-RC adds an optional boolean field is_charging_station
to station_information.json
. This indicates whether a station supports the charging of electric vehicles. See the example below in the station_information.json
code block.
Vehicle drop-off restrictions
v2.3-RC adds an optional return_type
field to vehicle_types.json
that allows operators to define if the vehicle is free_floating
(vehicle must be returned anywhere within the service area), roundtrip (vehicle must be returned at original rental station), or station (vehicle must be returned to any station within the service area). The field is modeled as an array to account for hybrid vehicles that have multiple ways of being returned. See the example below in the vehicle_types.json
code block.
Additionally, to account for edge cases where a vehicle must be returned to a particular station that is not the original station, a home_station_id
field has been added to free_bike_status.json
. See the example below in the free_bike_status.json
code block.
Brand assets and icons
v2.3-RC adds fields to system_information.json
and vehicle_types.json
to support brand information and vehicle icons.
In vehicle_types.json
, a new optional JSON object field – vehicle_assets
– has been added. Within vehicle_assets
, an operator can share:
- a URL for an SVG v1.1 graphic vehicle icon file (
icon_url
), - a URL for an SVG v1.1 graphic vehicle icon file for dark mode (
icon_url_dark
), and - the last time the referenced icons were updated (
icon_last_modified
).
If vehicle_assets
is defined, icon_url
and icon_last_modified
are conditionally required. See the example below in the vehicle_types.json
code block.
In system_information.json
, a new optional JSON object field – brand_assets
– has been added. Within brand_assets
, an operator can share:
- a URL for an SVG v1.1 graphic brand image (
brand_image_url
), - a URL for an SVG v1.1 graphic brand image for dark mode (
brand_image_url_dark
), - the last time the referenced images were updated (
brand_last_modified
), - a color used to represent the brand expressed as a six digit hexadecimal color code, and
- a link to license terms for brand assets (
brand_terms_url
).
If brand_assets
is defined, brand_image_url
and brand_last_modified
are conditionally required. See the example below in the system_information.json
code block.
Vehicle hold times
v2.3-RC adds an optional field default_reserve_time
to vehicle_types.json
that contains the maximum duration in minutes for which a vehicle may be reserved in advance of the start of a rental. The field name was chosen to leave flexibility to include other use cases in the future (for example, maximum reserve time being associated with a pricing plan). See the example below in the vehicle_types.json
code block.
Terms and privacy policy
v2.3-RC adds four new optional fields to system_information.json
. An operator can now share a URL (terms_url
) that points to their terms of service (also known as ‘terms of use’ or ‘terms and conditions’) and a URL (privacy_url
) that points to their privacy policy. Both of these new fields are accompanied by two new fields to indicate the last time the policy at the URL was updated – terms_last_updated
and privacy_last_updated
. If privacy_url
is defined, privacy_last_updated
is required. Similarly, if terms_url
is defined, terms_last_updated
is required. See the example below in the system_information.json
code block.
Pricing
v2.3-RC adds a p
ricing_plan_ids
array to vehicle_types.json
that contains the plan IDs of all applicable pricing plans for that vehicle type. It also adds a field (default_pricing_plan_id
) that defines a default pricing plan to be used by trip planners in calculating the cost of a single trip.
The ability to define pricing plans at the individual vehicle level is preserved, which would allow pricing to be set based on vehicle location or other factors. Any pricing plan assigned to individual vehicles in free_bike_status.json
supersedes the default plan defined in vehicle_types.json
. See the example below in the vehicle_types.json
code block.
More details for the Shared Mobility Developers
–> vehicle_types.json
Example of representing vehicle drop-off restrictions, brand assets and icons, vehicle hold times, and pricing by vehicle type.
In this example, you can see three different vehicle types:
- A non-electric bicycle that can be held for 30 minutes prior to trip start, that can be returned at any station or anywhere in the service area (or as restricted by
geofencing_zones.json
), that has vehicle icons available for regular and dark mode, and to which three different pricing plans can apply (with one identified as the default). - An electric scooter that can be held for 30 minutes prior to trip start, with a maximum range of 12345 meters on a full charge, that can be returned anywhere in the service area (or as restricted by
geofencing_zones.json
), that has vehicle icons available for regular and dark mode, and to which one pricing plan applies. - A combustion engine four-door sedan that cannot be held prior to trip start, with a maximum range of X on a full tank, that must be returned to the original rental station, that has vehicle icons available for regular and dark mode, and to which one pricing plan applies.
{
"last_updated": 1632269413,
"ttl": 60,
"version": "2.3",
"data": {
"vehicle_types": [
{
"vehicle_type_id": "abc123",
"form_factor": "bicycle",
"propulsion_type": "human",
"name": "Example Basic Bike",
"default_reserve_time": 30,
"return_type": [
"any_station",
"free_floating"
],
"vehicle_assets": {
"icon_url": "https://www.example.com/assets/icon_bicycle.svg",
"icon_url_dark": "https://www.example.com/assets/icon_bicycle_dark.svg",
"icon_last_modified": "2021-06-15"
},
"default_pricing_plan_id": "bike_plan_1",
"pricing_plan_ids": [
"bike_plan_1",
"bike_plan_2",
"bike_plan_3"
]
},
{
"vehicle_type_id": "def456",
"form_factor": "bicycle",
"propulsion_type": "electric",
"name": "Example E-bike V2",
"default_reserve_time": 30,
"max_range_meters": 12345,
"return_type": [
"any_station"
],
"vehicle_assets": {
"icon_url": "https://www.example.com/assets/icon_ebike.svg",
"icon_url_dark": "https://www.example.com/assets/icon_ebike_dark.svg",
"icon_last_modified": "2021-06-15"
},
"default_pricing_plan_id": "ebike_plan_1"
},
{
"vehicle_type_id": "car1",
"form_factor": "car",
"propulsion_type": "combustion",
"name": "Four-door Sedan",
"default_reserve_time": 0,
"max_range_meters": 523992,
"return_type": [
"roundtrip_station"
],
"vehicle_assets": {
"icon_url": "https://www.example.com/assets/icon_car.svg",
"icon_url_dark": "https://www.example.com/assets/icon_car_dark.svg",
"icon_last_modified": "2021-06-15"
},
"default_pricing_plan_id": "car_plan_1"
}
]
}
}
–> free_bike_status.json
Example of representing vehicle drop-off restriction where a vehicle is required to be dropped off at a particular station that may not be the station where it was picked up (home_station_id).
In this example, you can see two bikes – both of which are available for rental (for both, is_reserved
and is_disabled
are false). One bike is a non-electric bike, and the other is an electric bike located at a station (station_id
86). The electric bike located at the station can travel 6543 meters on its current charge, it has one applicable pricing plan, and it must be returned to a different location (station_id
146) at the end of the trip. For this example, the accompanying vehicle_types.json
file will need to define vehicle_type_id
as having at least the any_station return_type
.
{
"last_updated": 1609866247,
"ttl": 0,
"version": "3.0",
"data": {
"bikes": [
{
"bike_id": "ghi789",
"last_reported": 1609866109,
"lat": 12.345678,
"lon": 56.789012,
"is_reserved": false,
"is_disabled": false,
"vehicle_type_id": "abc123"
},
{
"bike_id": "jkl012",
"last_reported": 1609866204,
"is_reserved": false,
"is_disabled": false,
"vehicle_type_id": "def456",
"current_range_meters": 6543,
"station_id": "86",
"pricing_plan_id": "plan3",
"home_station_id": "146"
}
]
}
}
–> system_information.json
Example of representing terms and privacy policy fields and brand assets.
In this example, you can see a system that has defined many optional fields, including all of the new fields added in v2.3-RC: terms_url, terms_last_updated, privacy_url, privacy_last_updated
, and all available fields in brand_assets (brand_last_modified, brand_image_url, brand_image_url_dark, color, and terms_url).
{
"last_updated": 1611598155,
"ttl": 1800,
"version": "3.0",
"data": {
"system_id": "example_cityname",
"language": "en",
"name": "Example Bike Rental",
"short_name": "Example Bike",
"operator": "Example Sharing, Inc",
"url": "https://www.example.com",
"purchase_url": "https://www.example.com/join",
"start_date": "2010-06-10",
"phone_number": "1-800-555-1234",
"email": "customerservice@example.com",
"feed_contact_email": "datafeed@example.com",
"timezone": "US/Central",
"license_url": "https://www.example.com/data-license.html",
"terms_url": "https://www.example.com/terms-of-service.html",
"terms_last_updated": "2021-09-23",
"privacy_url": "https://www.example.com/privacy-policy.html",
"privacy_last_updated": "2021-09-25",
"brand_assets": {
"brand_last_modified": "2021-06-15",
"brand_image_url": "https://www.example.com/assets/brand_image.svg",
"brand_image_url_dark": "https://www.example.com/assets/brand_image_dark.svg",
"color": "#C2D32C",
"terms_url": "https://www.example.com/assets/brand.pdf"
}
}
}
Stay tuned for more updates soon, or join us on Slack!