The Provider API endpoints are intended to be implemented by mobility providers and consumed by regulatory agencies. Data is pulled from providers by agencies. When a municipality queries information from a mobility provider, the Provider API has a historical view of operations in a standard format.
This specification contains a data standard for mobility as a service providers to define a RESTful API for municipalities to access on-demand.
The following information applies to all provider
API endpoints.
This specification uses data types including timestamps, UUIDs, and vehicle state definitions as described in the MDS General Information document.
MDS Provider endpoint producers SHALL provide authorization for API endpoints via a bearer token based auth system. When making requests, the endpoints expect provider_id
to be part of the claims in a JSON Web Token (JWT) access_token
in the Authorization
header, in the form Authorization: Bearer <access_token>
. The token issuance, expiration and revocation policies are at the discretion of the agency. JSON Web Token is the recommended format.
General authorization details are specified in the Authorization section in MDS General Information.
Provider
APIs must handle requests for specific versions of the specification from clients.
Versioning must be implemented as specified in the Versioning section.
MDS is intended to be used for multiple transportation modes, including its original micromobility (e-scooters, bikes, etc.) mode, as well as additional modes such as taxis, car share, and delivery bots. A given provider_id
shall be associated with a single mobility mode, so that the mode does not have to be specified in each data structure and API call. A provider implementing more than one mode shall register a unique provider_id
for each mode.
The response to a client request must include a valid HTTP status code defined in the IANA HTTP Status Code Registry.
The response must set the Content-Type
header as specified in the Versioning section.
Response bodies must be a UTF-8
encoded JSON object
See the Responses, Error Messages, and Bulk Responses sections, and the schema for more details.
Response bodies must be a UTF-8
encoded JSON object and must minimally include the MDS version
and an object payload:
{
"version": "x.y.z",
"trips": [
{
"provider_id": "...",
"trip_id": "..."
}
]
}
All response fields must use lower_case_with_underscores
.
See the GBFS Requirement language for more details.
The data returned by a near-realtime endpoint should be as close to realtime as possible, but in no case should it be more than 5 minutes out-of-date. Near-realtime endpoints must contain last_updated
and ttl
properties in the top-level of the response body. These properties are defined as:
Field Name | Required | Defines |
---|---|---|
last_updated | Yes | Timestamp indicating the last time the data in this feed was updated |
ttl | Yes | Integer representing the number of milliseconds before the data in this feed will be updated again (0 if the data should always be refreshed). |
See the Endpoints below for information on their specific schema, and the mds-openapi
repository for full details and interactive documentation.
The /trips
and /events/historical
endpoints must not use pagination.
If Providers choose to use pagination for either of the /events
or /vehicles
endpoints, the pagination must comply with the JSON API specification.
The following keys must be used for pagination links:
first
: url to the first page of datalast
: url to the last page of dataprev
: url to the previous page of datanext
: url to the next page of data
At a minimum, paginated payloads must include a next
key, which must be set to null
to indicate the last page of data.
{
"version": "x.y.z",
"trips": [{
"provider_id": "...",
"trip_id": "...",
}],
"links": {
"first": "https://...",
"last": "https://...",
"prev": "https://...",
"next": "https://..."
}
}
Municipalities requiring MDS Provider API compliance should provide an unambiguous digital source for the municipality boundary. This boundary must be used when determining which data each provider
API endpoint will include.
The boundary should be defined as a polygon or collection of polygons. The file defining the boundary should be provided in Shapefile or GeoJSON format and hosted online at a published address that all providers and provider
API consumers can access and download. The boundary description can be sent as a reference to an GeoJSON object or flat-file, if the agency is using Geography.
Providers are not required to recalculate the set of historical data that is included when the municipality boundary changes. All new data must use the updated municipality boundary.
For Timestamps, Vehicle Types, Propulsion Types, UUIDs, Costs, and Currencies, refer to the MDS General Information document.
The /vehicles
is a near-realtime endpoint and returns the current status of vehicles in an agency's Jurisdiction and/or area of agency responsibility. All vehicles that are currently in any vehicle_state
should be returned in this payload. Since all states are returned, care should be taken to filter out states not in the PROW if doing vehicle counts. For the states elsewhere
and removed
which include vehicles not in the PROW but provide some operational clarity for agencies, these must only persist in the feed for 90 minutes before being removed.
As with other MDS APIs, /vehicles
is intended for use by regulators, not by the general public. /vehicles
can be deployed by providers as a standalone MDS endpoint for agencies without requiring the use of other endpoints, due to the modularity of MDS. See our MDS Vehicles Guide for how this compares to GBFS /free_bike_status
. Note that using authenticated /vehicles
does not replace the role of a public GBFS feed in enabling consumer-facing applications. If a provider is using both /vehicles
and GBFS endpoints, the /vehicles
endpoint should be considered source of truth regarding an agency's compliance checks.
In addition to the standard Provider payload wrapper, responses from this endpoint should contain the last update timestamp and amount of time until the next update in accordance with the Data Latency Requirements:
{
"version": "x.y.z",
"last_updated": "12345",
"ttl": "12345",
"vehicles": []
}
The /vehicles
endpoint returns the specified vehicle (if a device_id is provided) or a list of known vehicles. Contains vehicle properties that do not change often.
Endpoint: /vehicles/{device_id}
Method: GET
Beta feature: No (as of 1.2.0)
Schema: See mds-openapi
repository for schema.
data
Payload: { "vehicles": [] }
, an array of Vehicle objects
Path Parameters:
Path Parameters | Type | Required/Optional | Description |
---|---|---|---|
device_id |
UUID | Optional | If provided, retrieve the specified vehicle |
If device_id
is specified, GET
will return an array with a single vehicle record, otherwise it will be a list of vehicle records with pagination details per the JSON API spec:
{
"version": "x.y.z",
"vehicles": [ ... ]
"links": {
"first": "https://...",
"last": "https://...",
"prev": "https://...",
"next": "https://..."
}
}
Possible HTTP Status Codes: 200, 400 (with parameter), 401, 404, 406, 500
See Responses, Bulk Responses, and schema for details.
The /vehicles/status
endpoint returns the specified vehicle (if a device_id is provided) or a list of known vehicles. Contains specific vehicle status records that are updated frequently.
Endpoint: /vehicles/status/{device_id}
Method: GET
Beta feature: No (as of 1.2.0)
Schema: See mds-openapi
repository for schema.
data
Payload: { "vehicles_status": [] }
, an array of Vehicle Status objects
Path Parameters:
Path Parameter | Type | Required/Optional | Description |
---|---|---|---|
device_id |
UUID | Optional | If provided, retrieve the specified vehicle |
If device_id
is specified, GET
will return an array with a vehicle status record, otherwise it will be a list of vehicle records with pagination details per the JSON API spec:
{
"version": "x.y.z",
"vehicles": [ ... ]
"links": {
"first": "https://...",
"last": "https://...",
"prev": "https://...",
"next": "https://..."
}
}
Possible HTTP Status Codes: 200, 400 (with parameter), 401, 404, 406, 500
See Responses, Bulk Responses, and schema for details.
A trip represents a journey taken by a mobility as a service customer with a geo-tagged start and stop point.
The trips endpoint allows a user to query historical trip data.
Unless stated otherwise by the municipality, the trips endpoint must return all trips with a route
which intersects with the municipality boundary.
Endpoint: /trips
Method: GET
Beta feature: No
Schema: See mds-openapi
repository for schema.
data
Payload: { "trips": [] }
, an array of Trip objects
The /trips
API should allow querying trips with the following query parameters:
Query Parameter | Format | Expected Output |
---|---|---|
end_time |
YYYY-MM-DDTHH , an ISO 8601 extended datetime representing an UTC hour between 00 and 23. |
All trips with an end time occurring within the hour. For example, requesting end_time=2019-10-01T07 returns all trips where 2019-10-01T07:00:00 <= trip.end_time < 2019-10-01T08:00:00 UTC. |
Without an end_time
query parameter, /trips
shall return a 400 Bad Request
error.
The API's response will depend on the hour queried and the status of data processing for that hour:
-
For hours that are not yet in the past the API shall return a
404 Not Found
response. -
For hours in which the provider was not operating the API shall return a
404 Not Found
response. -
For hours that are in the past but for which data is not yet available the API shall return a
202 Accepted
response. -
For all other hours the API shall return a
200 OK
response with a fully populated body, even for hours that contain no trips to report. If the hour has no trips to report the response shall contain an empty array of trips:{ "version": "x.y.z", "trips": [] }
For the near-ish real time use cases, please use the events endpoint.
Possible HTTP Status Codes: 200, 202, 400 (with parameter), 401, 404, 406, 500
See Responses, Bulk Responses, and schema for details.
The /telemetry
endpoint is a feed of vehicle telemetry data for publishing all available location data. For privacy reasons, in-trip telemetry may be delayed at the discretion of the regulating body.
To represent trip telemetry, the data should include every observed point in the trip, even those which occur outside the municipality boundary, as long as any part of the trip intersects with the municipality boundary.
Telemetry for a trip must include at least 2 points: the start point and end point. Trips must include all additional GPS or GNSS samples collected by a Provider. Providers may round the latitude and longitude to the level of precision representing the maximum accuracy of the specific measurement. For example, a-GPS is accurate to 5 decimal places, differential GPS is generally accurate to 6 decimal places. Providers may round those readings to the appropriate number for their systems.
Endpoint: /telemetry
Method: GET
Schema: See mds-openapi
repository for schema.
data
Payload: { "telemetry": [] }
, an array of Vehicle Telemetry objects
Query Parameter | Format | Expected Output |
---|---|---|
telemetry_time |
YYYY-MM-DDTHH , an ISO 8601 extended datetime representing an UTC hour between 00 and 23. |
All telemetry with timestamp occurring within the hour. For example, requesting telemetry_time=2019-10-01T07 returns all telemetry where 2019-10-01T07:00:00 <= telemetry.timestamp < 2019-10-01T08:00:00 UTC. |
Without a telemetry_time
query parameter, /telemetry
shall return a 400 Bad Request
error.
Possible HTTP Status Codes: 200, 400 (with parameter), 401, 406, 500
See Responses, Bulk Responses, and schema for details.
The /events/recent
and /events/historical/
endpoints return a list of Event objects, describing the activity of the Provider's vehicles. Recent events are at most two weeks old and can be queried with start/stop time, and historical events are packaged in hour-sized chunks for ease of implementation.
Unless stated otherwise by the municipality, this endpoint must return only those status changes with a event_location
that intersects with the municipality boundary.
Note: As a result of this definition, consumers should query the trips endpoint to infer when vehicles enter or leave the municipality boundary.
Endpoint: /events/historical
Method: GET
Beta feature: No
Schema: See mds-openapi
repository for schema.
data
Payload: { "events": [] }
, an array of Events object
The /events/historical
API uses the following query parameter:
Query Parameter | Format | Expected Output |
---|---|---|
event_time |
YYYY-MM-DDTHH , an ISO 8601 extended datetime representing an UTC hour between 00 and 23. |
All status changes with an event time occurring within the hour. For example, requesting event_time=2019-10-01T07 returns all status changes where 2019-10-01T07:00:00 <= status_change.event_time < 2019-10-01T08:00:00 UTC. |
Without an event_time
query parameter, /events
shall return a 400 Bad Request
error.
The API's response will depend on the hour queried and the status of data processing for that hour:
-
For hours that are not yet in the past the API shall return a
404 Not Found
response. -
For hours in which the provider was not operating the API shall return a
404 Not Found
response. -
For hours that are in the past but for which data is not yet available the API shall return a
202 Accepted
response. -
For all other hours the API shall return a
200 OK
response with a fully populated body, even for hours that contain no status changes to report. If the hour has no status changes to report the response shall contain an empty array of status changes:{ "version": "x.y.z", "status_changes": [] }
Possible HTTP Status Codes: 200, 202, 400 (with parameter), 401, 404, 406, 500
See Responses, Bulk Responses, and schema for details.
The /events/recent
endpoint is a near-realtime feed of events less than two weeks old.
See also Stop-based Geographic Data.
Endpoint: /events/recent
Method: GET
Beta feature: No (as of 1.0.0)
Schema: See mds-openapi
repository for schema.
data
Payload: { "events": [] }
, an array of Events object objects
The Recent Events API requires two parameters:
Query Parameter | Type | Expected Output |
---|---|---|
start_time |
timestamp | status changes where start_time <= event.timestamp |
end_time |
timestamp | status changes where event.timestamp < end_time |
Should either side of the requested time range be missing, /events/recent
shall return a 400 Bad Request
error.
Should either side of the requested time range be greater than 2 weeks before the time of the request, /events/recent
shall return a 400 Bad Request
error.
Possible HTTP Status Codes: 200, 400 (with parameter), 401, 406, 500
See Responses, Bulk Responses, and schema for details.
Stop information should be updated on a near-realtime basis by providers who operate docked mobility devices in a given municipality.
In addition to the standard Provider payload wrapper, responses from this endpoint should contain the last update timestamp and amount of time until the next update in accordance with the Data Latency Requirements:
{
"version": "x.y.z",
"last_updated": "12345",
"ttl": "12345",
"stops": []
}
Endpoint: /stops/{stop_id}
Method: GET
Beta feature: Yes (as of 1.0.0). Leave feedback
Schema: See mds-openapi
repository for schema.
data
Payload: { "stops": [] }
, an array of Stops
In the case that a stop_id
path parameter is specified, the stops
array returned will only have one entry. In the case that no stop_id
query parameter is specified, all stops will be returned.
Possible HTTP Status Codes: 200, 400 (with parameter), 401, 404 (with parameter), 406, 500
See Responses, Bulk Responses, and schema for details.
Reports are information that providers can send back to agencies containing aggregated data that is not contained within other MDS endpoints, like counts of special groups of riders. These supplemental reports are not a substitute for other MDS Provider endpoints.
The authenticated reports are monthly, historic flat files that may be pre-generated by the provider.
Endpoint: /reports
Method: GET
Beta feature: No (as of 2.0.0). Leave feedback
Usage note: This endpoint uses media-type text/vnd.mds+csv
instead of application/vnd.mds+json
, see Versioning.
Schema: See mds-openapi
repository for schema.
data
Filename: monthly file named by year and month, e.g. /reports/YYYY-MM.csv
data
Payload: monthly CSV files of Report objects
Possible HTTP Status Codes: 200, 401, 404, 500
See Responses, Bulk Responses, and schema for details.
See Provider examples.