More from Developers
Select from the list below to learn more about the information and tools available for developers interested in MBTA data.
The Swagger documentation is the best source for information about the different endpoints and fields we provide. Some particular places to look:
- The endpoint documentation includes what filters are available and what additional information can be included
- The resource documentation includes the format of the fields, as well as what the values can be
Usage of the API v3 is subject to certain rate limits:
- Requests made without an API key are subject to a limit of 20 requests per minute.
- Requests made with a valid API key are limited to a default of 1000 requests per minute.
You can register to request an API key here. If you already have an API key, you can also view your current rate limit in the portal; you can also request an increase to your rate limit if you need one. See the sections of this document on Caching and Fields for ways to fetch less data and avoid hitting rate limits.
All API v3 responses include HTTP headers which show your rate limit status:
|Header||Description||The maximum number of requests you’re allowed to make per time window.|
|Header||Description||The number of requests remaining in the current time window.|
|Header||Description||The time at which the current rate limit time window ends in UTC epoch seconds.|
API v3 supports caching via the `Last-Modified` response and `If-Modified-Since` request headers. Each response contains a `Last-Modified` header, specifying the last time that data was updated. If, on subsequent requests, your client passes an `If-Modified-Since` header with that value and the data hasn't changed, you'll quickly receive a 304 Not Modified. This cached response won't count against your API key limit either. Another advantage of using this header is that you won't receive an update if you hit a server which was updated slightly in the past.
Note: This only works for the root data type; included data isn't currently tracked by the `Last-Modified` header.
API v3 supports GZIP compression via the `Accept-Encoding` header. If your HTTP client doesn't do this transparently, you can pass `Accept-Encoding: gzip` as a request header, and the response will be compressed. This can result in large data savings: the full list of routes goes from 48k without compression to 3.4k with compression.
Each type of data supports a query parameter `fields[type]` which limits the returned attributes. For example, https://api-v3.mbta.com/routes/?fields%5Broute%5D=short_name,long_name returns only the name s for the routes. If you know what fields you need, this is another good way to reduce the amount of data you receive. This also works for included data types: https://api-v3.mbta.com/trips/?filter%5Broute%5D=CR-Providence&include=shape&fields%5Btrip%5D=name&fields%5Bshape%5D=name
The realtime data can update very frequently, even using `If-Modified-Since` headers to avoid stale data. You may want to include some logic in your clients to prevent relative times from bouncing (say between "3 minutes away" and "4 minutes away") if that would be confusing to your users. If you're displaying predictions at that level of granularity, you can also reduce the frequency of updates accordingly.
Displaying alerts is one of the trickiest features to get correct. Service disruptions can affect large sets of riders, and you as the client developer are in the best position to know where they might be trying to ride.
If you don’t know where along a route a rider is traveling, filtering only by their origin stop (see example) is likely to miss relevant alerts at other stops along the line. In that case, you should also query for alerts on the entire route (see example) and incorporate them.
The same recommendation applies to implementations where the filtering of the alerts to show happens on the client side. You want to add the alerts where any informed entity includes the relevant route. Even if an alert is about a specific stop, it still may affect your riders.
When you do have the information about the rider's entire trip (where they are leaving from and where they are going), you still should consider the alerts on the stops along their route. For example, there might be an alert about shuttles replacing regular service somewhere in the middle of their trip. You can query for multiple stops by comma-separating them in the filter (see example).
You can also use the activity field of the Informed Entity to better filter to those alerts.
- For stops where the rider boards a vehicle (even transfers), filter for the BOARD activity
- For stops where the rider gets off a vehicle (even transfers), filter for the EXIT activity
- For stops the rider travels through, filter for the RIDE activity
- If the user requests accessible trips, filter for the USING_WHEELCHAIR activity
The documentation for AlertResource has more detail on other types of activities.
Alerts with a severity of 1 are informational. If possible, they can receive a more muted visual treatment compared with more severe alerts.
Arrival and Departure Times
Follow these best practices for displaying prediction information for MBTA arrivals and departures of vehicles in a way that will match up with what is displayed on MBTA signage, apps, and the MBTA website.
When you make a "predictions" query, you'll receive predictions data that contains both arrival-time and departure-time values. Here's how to interpret and display that to customers:
This is a mid-route stop and you should display the arrival time to customers, not the departure time.
When the predicted time drops below 45 seconds in the future, you can optionally display "Arriving."
If the status field is present (for example "Stopped 3 stops away"), we recommend displaying the contents of that field rather than the predicted arrival time.
This is a final stop of the trip and information about it would not normally be displayed to customers, because most of the time people don't care what time a vehicle arrives at its last stop.
We recommend against displaying any information about this prediction unless you have a specific use case for it.
This is a first stop of a trip, and you should display the departure time to customers.
In this case, you should not use the word "Arriving" and should instead display "Boarding" when the predicted time drops below 30 seconds in the future.
The most popular way to display the MBTA's prediction information is a countdown clock showing how many minutes away the vehicle is from the stop.
We provide the expected arrival/departure times in one of two formats, depending on how you fetch the predictions. GTFS-Realtime files have the times in POSIX Epoch format: the number of seconds since January 1, 1970 in the UTC/GMT timezone. The V3 API has the times in ISO8601 format, a string format which includes the timezone offset. You can convert either of these into the date/time format your language supports.
In the V3 API, we also provide a "status" attribute, which is a free-text field to display to riders.
If a "status" attribute is present and non-null
Display that status
Calculate the number of seconds away the vehicle is
Use the arrival time if available, otherwise use the departure time
Subtract the current time from the prediction time
If the vehicle status is STOPPED_AT the stop for which you're displaying a prediction,
If there's an arrival time or the seconds <= 90
Display "Boarding" or "BRD" (depending on space)
If seconds is <= 30
Display "Arriving" or "ARR"
If seconds is <= 60
Display "Approaching" or "1 min"
If seconds is <= 89
Display "1 minute" or "1 min"
Otherwise, calculate the number of minutes by rounding to the closest minute:
90 - 149 seconds
Display "2 minutes" or "2 min"
150 - 209 seconds
Display "3 minutes" or "3 min"