Before you proceed with this section, if you haven't already done so, verify the supported micromobility systems you're building the feed for.
In the following sections, each header has the following format:
Required|Optional|Conditionally required: Feed name (System supported)
. The
following systems are supported:
- Docked system
- Dockless system
- Docked and dockless system
To successfully integrate with Google, provide only the files needed for the system your feed describes, and specify the required fields included in the relevant sections. For conditionally required fields, refer to the field's description for guidance. You can also specify optional fields that add information and provide a better user experience.
Required header for Micromobility feeds
Micromobility feeds are feeds that contain either docked or dockless Micromobility structured data as defined in this article.
All feeds must always specify the fields included in the following table at the top level of the JSON object, known collectively as the common GBFS header.
Field name | Type | Requirement | Description |
---|---|---|---|
last_updated |
Timestamp | Required | A POSIX timestamp, which specifies a number of seconds since January
1, 1970 00:00:00 UTC.
Set to the last time that the data in the feed was updated. |
ttl |
Non-negative integer | Required | A non-negative integer that represents the number of seconds that
remain until it's time to update the feed.
If the data must be updated at a constant rate, set this value to
|
data |
JSON | Required | JSON that contains the data fields for the individual feed. |
For example, an aggregated free_bike_status.json
feed which specifies the
common GBFS header, might be as follows:
{
"ttl": 30,
"last_updated": 1576123774,
"data": {
"bikes": [ ... ] // GBFS free bike status objects.
}
}
Required: system_information.json (Docked and dockless system)
Refer to the GBFS specification as needed.
This feed provides details regarding the system operator.
Field name | Type | Requirement | Description |
---|---|---|---|
system_id |
ID | Required | A globally unique identifier for the vehicle share system. This value is intended to remain the same over the life of the system. Each distinct system or geographic area in which vehicles are operated SHOULD have its own system_id. Systems IDs SHOULD be recognizable as belonging to a particular system as opposed to random strings - for example, bcycle_austin or biketown_pdx. |
name |
String | Required | Name of the system, which is displayed to customers. |
rental_apps |
Object | Required | A JSON object that contains the rental app's information for Android and iOS in their respective fields. |
rental_apps.android |
Object | Conditionally required |
Contains rental app download and app discovery information for the Android
platform in the store_uri and discovery_uri
fields. If the system provider has an Android rental app, this field is
required.
|
rental_apps.android.store_uri |
URI | Required | URI where the rental Android app can be downloaded from. This is typically a URI to an app store such as Google Play. If the URI points to an app store such as Google Play, we recommend that the URI follows Android best practices so the viewing app can directly open the URI to the native app store app instead of a website. |
rental_apps.android.discovery_uri |
URI | Required | URI that has the form your_custom_scheme://your/path/here .
The URI can be used by PackageManager.queryIntentActivities()
to discover whether the rental Android app is installed on the device.
|
rental_apps.ios |
Object | Conditionally required | Contains rental app download and app discovery information for the iOS
platform in the store_uri and discovery_uri
fields. If the system provider has an iOS rental app, this field is
required.
|
rental_apps.ios.store_uri |
URI | Required | URI where the rental iOS app can be downloaded from. This is typically a URI to an app store such as the Apple App Store. If the URI points to an app store such as the Apple App Store, we recommend that the URI follows iOS best practices so the viewing app can directly open the URI to the native app store app instead of a website. |
rental_apps.ios.discovery_uri |
URI | Required | URI that has the form your_custom_scheme:// . The URI can be
used by UIApplication canOpenURL: to discover whether the
rental iOS app is installed on the device.
|
Required: free_bike_status.json (Dockless system)
Refer to the GBFS specification as needed.
This feed defines the locations and attributes for available free-standing vehicles. For privacy reasons, vehicles that are part of an active rental must not appear in this feed.
Field name | Type | Requirement | Description |
---|---|---|---|
bikes |
Array | Required | An array of currently available, stopped bikes where each bike is an object. |
bikes[].bike_id |
ID | Required | The identifier of a bike.
To protect privacy, the ID can be changed to a random string after each trip. |
bikes[].lat |
Latitude | Required | The WGS 84 latitude of the bike, in decimal degrees format. |
bikes[].lon |
Longitude | Required | The WGS 84 longitude of the bike, in decimal degrees format. |
bikes[].is_reserved |
Boolean | Required | Whether the bike is currently reserved, as follows:
|
bikes[].is_disabled |
Boolean | Required | Whether the bike is currently disabled or broken, as follows:
|
bikes[].rental_uris |
Object | Required | A JSON object that contains rental URIs for Android, iOS, and web in their respective fields. |
bikes[].rental_uris.android |
URI | Conditionally required | A URI that can be passed to an Android app with an
android.intent.action.VIEW Android intent to support
Android Deep Links. The rental_uris provided must be
Android App Links so that the viewing app doesn't need to manually
manage the redirect of the user to the app store in the event that the
user doesn’t have the provider application installed.
This URI must be a deep link specific to the individual bike, not a general rental page that includes information for more than one bike. The deep link must take the user directly to the bike without any prompts, interstitial pages, or logins. Ensure that users can see the bike even if they've never opened the application. URIs aren't necessarily required to include the If the partner has an Android rental app, this field is required. Android App Links example:
|
bikes[].rental_uris.ios |
URI | Conditionally required | A URI that can be used on iOS to launch the rental app for the bike.
For more information about this, refer to Apple's article about
iOS custom URL schemes.
The rental_uris provided must be
iOS Universal Links so that the viewing app doesn't need to manually
manage the redirect of the user to the app store in the event that the
user doesn’t have the provider application installed.
This URI must be a deep link specific to the individual bike, not a general rental page that includes information for more than one bike. The deep link must take the user directly to the bike without any prompts, interstitial pages, or logins. Ensure that users can see the bike even if they've never opened the application. URIs aren't necessarily required to include the bike_id for the bike, as long as the partner has other means to identify the respective bike. For example, the rental app can use other identifiers within the URI to uniquely identify the bike. If the partner has an iOS rental app, this field is required. iOS Universal Links example:
|
bikes[].rental_uris.web |
URL | Optional | A URL that can be used by a web browser to show more information about renting a vehicle at this vehicle. This URL must be a deep link specific to the individual bike, not a general rental page that includes information for more than one bike. The deep link must take the user directly to the bike without any prompts, interstitial pages, or logins. Ensure that users can see the bike even if they've never opened the application. URLs aren't necessarily required to include the If this field is unset, it means that deep links aren't supported for the web browser. Example value:
|
bikes[].vehicle_type_id |
ID | Required | The vehicle_type_id of the vehicle as described in the
vehicle_types.json
section.
|
bikes[].pricing_plan_id |
ID | Required | Identifier of the price plan that's applied when this vehicle type is
rented as described in the
system_pricing_plans.json
section.
|
bikes[].current_range_meters |
Non-negative float | Conditionally required | If the vehicle_type definition that corresponds to the
vehicle has a motor, then this field is required.
Set to the furthest distance in meters that the vehicle can travel without the need for recharge or refuel, given the vehicle's current charge or fuel level. |
bikes[].last_reported |
Timestamp | Optional | Set to the last time the vehicle reported its status to the operator's backend. |
The following is an example for free_bike_status.json
:
"bikes": [{
"bike_id": "xyz123",
"lat": 12.34,
"lon": 56.78,
"is_reserved": true,
"is_disabled": false,
"rental_uris":{
"android": "https://www.example.com/app?sid=1234567890&platform=android",
"ios": "https://www.example.com/app?sid=1234567890&platform=ios",
"web": "https://www.example.com/app?sid=1234567890"
},
"vehicle_type_id": "scooter_electric",
"pricing_plan_id": "sydneyPlan1",
"current_range_meters": 4500,
"last_reported": 1434054678
},
{
"bike_id": "abc123",
"lat": 1.34,
"lon": 146.78,
"is_reserved": false,
"is_disabled": true,
"rental_uris":{
"android": "https://www.example.com/app?sid=1234567890&platform=android",
"ios": "https://www.example.com/app?sid=1234567890&platform=ios",
"web": "https://www.example.com/app?sid=1234567890"
},
"vehicle_type_id": "bike_manual",
"pricing_plan_id": "sydneyPlan1",
"last_reported": 1434054241
}
]
Required: vehicle_types.json (Docked and dockless system)
Refer to the GBFS specification as needed.
This feed defines the details of individual vehicle types, as referred to in the
free_bike_status.json
section.
Field name | Type | Requirement | Description |
---|---|---|---|
vehicle_types |
Array | Required | An array of objects, where each object defines a distinct vehicle type in the provider's catalog. There can only be one object for a given vehicle type. |
vehicle_types[].vehicle_type_id |
ID | Required | A unique identifier for a given vehicle type. |
vehicle_types[].form_factor |
Enum | Required | An enum that represents the vehicle's general form factor, from the
following list of currently valid values:
|
vehicle_types[].propulsion_type |
Enum | Required | An enum that represents the vehicle's primary propulsion type, from the
following list of currently valid values:
|
vehicle_types[].max_range_meters |
Non-negative float | Conditionally required | If propulsion_type isn't set to human , the
vehicle has a motor, and then this field is therefore required.
Set to the furthest distance in meters that the vehicle can travel without the need for recharge or refuel, when the vehicle is fully fueled or fully charged. |
The following is an example for vehicle_types.json
:
"vehicle_types": [
{
"vehicle_type_id": "bike_manual",
"form_factor": "bicycle",
"propulsion_type": "human"
},
{
"vehicle_type_id": "scooter_electric",
"form_factor": "scooter",
"propulsion_type": "electric",
"max_range_meters": 10000
}
]
Required: system_pricing_plans.json (Dockless system)
Refer to the GBFS specification as needed.
This feed defines the price plans for free-standing vehicles. We require providers to show price information for free-standing vehicles.
Field name | Type | Requirement | Description |
---|---|---|---|
plans |
Array | Required | An array of objects where each object defines a given price plan. |
plans[].plan_id |
ID | Required | A string that represents a unique identifier for the given price plan that the provider offers. |
plans[].url |
URL | Optional | The URL that points end-users to more information about the price plan. |
plans[].currency |
String | Required | The ISO 4217 standard for the price plan. |
plans[].price |
Non-negative float | Required |
The price plan must be defined either as a non-rated price plan or a rated price plan:
|
plans[].per_km_pricing |
Array | Conditionally required |
If the price is a function of distance travelled, displayed in kilometers, then this field is required. An array of objects where each object defines a given
distance-divided segment. Each segment's To determine the total price of the given plan add the given plan's
If this field isn't set, there are no variable prices based on distance and therefore, none are included as part of the total price. |
plans[].per_km_pricing[].start |
Non-negative integer | Required |
The number of kilometers at which the segment rate starts to be charged.
This field is set to the
inclusive value
that starts the segment's range. Thus, once the number of kilometers have
elapsed, the rate is charged once.
|
plans[].per_km_pricing[].rate |
Float | Required | The rate that's charged for each interval , which begins at
the inclusive start of the segment. If this field is set to a
negative number, the traveller receives a discount.
|
plans[].per_km_pricing[].interval |
Non-negative integer | Required |
The interval in kilometers at which the The If the segment's If this field is set to |
plans[].per_km_pricing[].end |
Non-negative integer | Optional |
The number of kilometers at which point the If this field isn't set or is empty, the |
plans[].per_min_pricing |
Array | Conditionally required |
If the price is a function of time passed, displayed in minutes, then this field is required. An array of objects where each object defines a given time-divided
segment. Each segment's To determine the total price of the given plan add the given plan's
If this field isn't set, there are no variable prices based on time and therefore none are included as part of the total price. |
plans[].per_min_pricing[].start |
Float | Required |
The number of minutes at which the segment rate starts to be charged.
This field is set to the
inclusive value
that starts the segment's range. Thus, once the set number of minutes
elapse, the rate is be charged once.
|
plans[].per_min_pricing[].rate |
Float | Required | The rate that's charged for each interval . The rate starts
at the inclusive start of the segment. If this field is set
to a negative number, the traveller receives a discount.
|
plans[].per_min_pricing[].interval |
Non-negative integer | Required |
The interval in minutes at which the The If the segment's If this field is set to |
plans[].per_min_pricing[].end |
Non-negative integer | Optional |
The number of minutes at which point the If this field isn't set or is empty, the
|
Examples for system_pricing_plans.json
This section provides informative system_pricing_plans.json
code samples. Each
example's relevant details and results are also provided.
Example 1 for system_pricing_plans.json
The following price plan code sample shows charges based on the journey time for the following intervals:
- [0,1): $2 USD
- If the journey is less than a minute, the user pays $2 USD.
- Example: 59-secs trip
- [1,2): $3 USD
- If the journey is longer or equal to one minute but less than two minutes, the user pays $2 + $1 = $3 USD.
- Examples: 1-min trip; 1-min 45-secs trip
- x number of minutes where x is more than or equals to 2:
$3 + (($2 + $1) * (x - 2 + 1))
USD
- If the journey is longer or equal to two minutes the user pays $3 for
the portion of the journey less than two minutes and ($1 [continuing
from the first entry of the
per_min_pricing
list] + $2 [the second entry of theper_min_pricing
list]) for every minute after and inclusive of two minutes. - Examples:
- 2-mins trip cost $3 + ($2 + $1) = $6 USD
- 2-mins 30-secs trip cost $3 + ($2 + $1) = $6 USD
- 3-mins trip cost $3 + (($2 + $1) * 2) = $9 USD
- 10-mins trip cost $3 + (($2 + $1) * 9) = $30 USD
- If the journey is longer or equal to two minutes the user pays $3 for
the portion of the journey less than two minutes and ($1 [continuing
from the first entry of the
{
"plans": {
"plan_id": "plan1",
"currency": "USD",
"price": 2,
"per_min_pricing": [
{
"interval": 1,
"rate": 1,
"start": 1
},
{
"interval": 1,
"rate": 2,
"start": 2
}
],
}
}
Example 2 for system_pricing_plans.json
In this example, we show a code sample for a price price plan that is charged at a rate of both minutes and kilometers:
- Specifically, the end-user is charged $0.25 CAD per km as well as $0.50 CAD per minute.
- Both of these rates happen concurrently and aren't dependent on one another.
- Therefore, a one-kilometer trip that lasts for 10 minutes costs $9 CAD. The
breakdown of the cost is as follows:
- $3, base price
- $0.25 * 2, charged once at the start of the trip and once at the 1-km mark.
- $0.5 * 11, charged once at the start of every minute. Charges starts at 0 seconds, with the last interval charged at 10 minutes.
{
"plans": {
"plan_id": "plan2",
"currency": "CAD",
"price": 3,
"per_km_pricing": [{
"start": 0,
"rate": 0.25,
"interval": 1
}],
"per_min_pricing": [{
"start": 0,
"rate": 0.50,
"interval": 1
}]
}
}
Conditionally required: geofencing_zones.json (Docked and dockless system)
Refer to the GBFS specification as needed.
This feed defines the geofencing data for free-standing vehicles. Geofencing data includes the geographic boundaries that specify where vehicles are allowed to begin the ride and finish the ride, along with the speed at which the vehicles can go. This speed is either the vehicle's maximum speed or the speed limit of the road the vehicle is on, whichever is lower. Drivers must adhere to local laws and ordinances.
We use this data so that when a user searches for a given route, if the end of the trip falls outside the specific geofences, the Micrimobility result is filtered out. If geofences aren't provided, Google treats the service as though it has no boundary restrictions.
Field name | Type | Requirement | Description |
---|---|---|---|
geofencing_zones |
Object | Required | A FeatureCollection object as described by the
IETF RFC 7946 is an object that has a field, named
features . The value of features is a JSON array.
Each element of the JSON array is a Feature object.
Each geofenced zone, its associated rules and attributes, and the
definitions of the |
geofencing_zones.type |
String | Required | Set to FeatureCollection as described by the
IETF RFC 7946. |
geofencing_zones.features |
Array | Required | A JSON array, where each element of the JSON array is a Feature
object. |
geofencing_zones.features[].type |
String | Required | Set to Feature as described by the
IETF RFC 7946. |
geofencing_zones.features[].geometry |
GeoJSON Multipolygon | Required | A GeoJSON Multipolygon that describes where rides aren't able to start, end, go through, in addition to other limitations. A clockwise arrangement of points defines the area enclosed by the polygon, while a counterclockwise order defines the area outside the polygon. For more information about this, refer to the right-hand rule. |
geofencing_zones.features[].properties |
Object | Required | An object that defines the travel allowances and limitations. |
geofencing_zones.features[].properties.rules |
Array | Optional | An array of objects, where each object defines one and only one rule. If two or more rules overlap, collide, or otherwise conflict in some way, the earliest defined rule in the order of the JSON file takes precedence. |
geofencing_zones.features[].properties.rules[].vehicle_type_id |
Array | Optional | An array of vehicle type IDs, where each element is a
vehicle_type_id , for which any restrictions must be applied.
If no vehicle_type_id is specified, then the restrictions
apply to all vehicle types. |
geofencing_zones.features[].properties.rules[].ride_allowed |
Boolean | Required | Whether the free-standing "undocked" bike ride can start and end in the
zone, as follows:
|
The following is an example for geofencing_zones.json
:
"geofencing_zones":{
"type":"FeatureCollection",
"features":[{
"type":"Feature",
"properties":{
"rules":[{
"vehicle_type_id":"scooter",
"ride_allowed": false
}]
},
"geometry":{
"type":"MultiPolygon",
"coordinates":[[[
[-122.66780376434326, 45.49896266763551],
[-122.66810417175292, 45.49824825558575],
[-122.66830801963805, 45.49632305799116],
[-122.66780376434326, 45.49896266763551]
]]]
}
}]
}
Required: station_information.json (Docked system)
Refer to the GBFS specification as needed.
This feed defines the general information about public bikesharing stations.
Field name | Type | Requirement | Description |
---|---|---|---|
stations |
Array | Required | An array of objects where each object defines one and only one station. |
stations[].station_id |
String | Required | The identifier of the station. |
stations[].name |
String | Required |
The public name of the station in the local language of the city the
station is located in. The name must adhere to what's used
on signages at the station, where available, or it must be a reflection of
the station location through the use of a cross street or local landmark.
Dont use abbreviations such as "St." for "Street" unless it's explicitly
used in signages, and the name must be in mixed case
following local conventions for capitalization of place names and not in
all caps.
|
stations[].lat |
Latitude | Required | The WGS 84 latitude of the station, in decimal degrees format. |
stations[].lon |
Longitude | Required | The WGS 84 longitude of the station, in decimal degrees format. |
stations[].capacity |
Non-negative integer | Optional | A non-negative integer that represents the total number of docking points installed at the station, both available and unavailable. |
stations[].rental_uris |
Object | Required |
A JSON object that contains rental URIs for Android, iOS, and web in their respective fields. If these URIs are specified, they override the default deep links that were set when the provider was onboarded. |
stations[].rental_uris.android |
URI | Conditionally required |
A URI that can be passed to an Android app with an
This URI must be a deep link specific to the individual station, not a general rental page that includes information for more than one station. The deep link must take the user directly to the station without any prompts, interstitial pages, or logins. Ensure that users can see the station even if they've never opened the application. URIs aren't necessarily required to include the If the partner has an Android rental app, this field is required. Android App Links example:
|
stations[].rental_uris.ios |
URI | Conditionally required |
A URI that can be used on iOS to launch the rental app for the station.
For more information about this, refer to Apple's article about
iOS custom URL schemes.
The This URI must be a deep link specific to the individual station, not a general rental page that includes information for more than one station. The deep link must take the user directly to the station without any prompts, interstitial pages, or logins. Ensure that users can see the station even if they've never opened the application. URIs aren’t necessarily required to include the If the partner has an iOS rental app, this field is required. iOS Universal Links example:
|
stations[].rental_uris.web |
URL | Optional | A URL that can be used by a web browser to show more information about how to rent a vehicle at this station. This URL must be a deep link specific to the individual station, not a general rental page that includes information for more than one station. The deep link must take the user directly to the station without any prompts, interstitial pages, or logins. Ensure that users can see the station even if they've never opened the application. URLs aren't necessarily required to include the If this field is unset, it means that deep links aren't supported for the web browser. Example value:
|
The following is an example for station_information.json
:
"stations": [
{
"station_id": "597",
"name": "Silverthorne Road, Battersea",
"lat": 51.472865,
"lon": -0.148059,
"capacity": 10,
"rental_uris": {
"android": "https://www.example.com/app?sid=1234567890&platform=android",
"ios": "https://www.exampleexample.com/app?sid=1234567890&platform=ios",
"web": "https://www.example.com/app?sid=1234567890&platform=web"
}
},
]
Required: station_status.json (Docked system)
Refer to the GBFS specification as needed.
This feed defines the up-to-date, current status of public bikesharing stations.
Field name | Type | Requirement | Description |
---|---|---|---|
stations |
Array | Required | An array of objects, where each object defines one and only one station. |
stations[].station_id |
String | Required | The identifier of the station. |
stations[].num_bikes_available |
Non-negative integer | Required |
A non-negative integer that represents the number of functional bikes that are physically at the station and that might be offered for rental. To determine whether the station currently rents bikes, you must
inspect the station's |
stations[].vehicle_types_available |
Array | Optional |
An array of objects that defines the total number of vehicles,
categorized by the individual vehicle type available at a station. Each
object models the total number of vehicle for the associated vehicle
type. The total number of vehicles from each of these objects must add
up to match the value specified in the |
stations[].vehicle_types_available[].vehicle_type_id |
ID | Required |
The |
stations[].vehicle_types_available[].count |
Non-negative integer | Required |
The total number of available vehicles for the corresponding
|
stations[].num_docks_available |
Non-negative integer | Conditionally required |
The field is required, unless the station has unlimited docking capacity. For example, virtual stations have unlimited docking capacities and the field isn't required. A non-negative integer that represents the total number of functional docks physically at the station that are able to accept vehicle returns. To determine whether the station currently accepts bike returns, you
must inspect the station's |
stations[].is_installed |
Boolean | Required |
A Boolean that indicates whether it's true that the station is currently on the street and installed. If the station is installed on the street, set to If the station isn't installed on the street, set to |
stations[].is_renting |
Boolean | Required |
A Boolean that indicates whether it's true that the station currently rents bikes. If the station currently rents bikes, set to If the station doesn't currently rent bikes, set to |
stations[].is_returning |
Boolean | Required |
A Boolean that indicates whether it's true that the station currently accepts bike returns. If the station currently accepts bike returns, set to If the station doesn't currently accept bike returns, set to
|
The following is an example of station_status.json
:
"stations": [
{
"station_id": "2",
"num_bikes_available": 6,
"vehicle_types_available": [
{
"vehicle_type_id" : "scooter_electric",
"count" : 2
},
{
"vehicle_type_id" : "bike_manual",
"count" : 4
}
],
"num_docks_available": 30,
"is_installed": true,
"is_renting": true,
"is_returning": true,
"last_reported": 1576119631
},
]