Skip to main content

Best Practices

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

Rate limiting

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:

Headerx-ratelimit-limitDescriptionThe maximum number of requests you’re allowed to make per time window.
Headerx-ratelimit-remainingDescriptionThe number of requests remaining in the current time window.
Headerx-ratelimit-resetDescriptionThe 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.

Sparse fieldsets

Each type of data supports a query parameter `fields[type]` which limits the returned attributes (reference). For example,,long_name returns only the names 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:[route]=CR-Providence&include=representative_trip&fields[trip]=headsign .

Nested includes

An often-overlooked JSON:API feature is the ability to include multiple levels of relationships, by connecting the relationship names with dots (reference). For example, the response for will include the requested route, its route patterns, the representative trips of those patterns, and the shapes of those trips. This works to any "depth" of relationships, and can save you the need to make N+1 requests in many situations.


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.


Displaying real-time predictions is a popular use of the API, and there are some complexities involved in interpreting and displaying this data correctly.