BYTETOOLS

MBTA V3 API

Free Boston MBTA transit API with no key: subway, bus, commuter rail and ferry routes, stops, live predictions, vehicle positions and service alerts. Tested example included.

No API key requiredCORS enabledHTTPSFree tier

Endpoint tested and returned HTTP 200 on 21 Aug 2026

What is the MBTA V3 API?

The MBTA V3 API is Boston's official public transit API and works without an API key at a reduced rate limit. It covers subway, bus, commuter rail and ferry — routes, stops, schedules, live arrival predictions, vehicle positions, trip details and service alerts.

Among large American transit agencies the MBTA is the outlier that made its API genuinely open: no key is required at all, and requesting one simply raises the limit from 20 requests a minute to 1,000. That makes it a rare case where a real production transit API can be explored and prototyped against with nothing more than curl.

It follows the JSON:API specification strictly, which is either a convenience or a surprise depending on what you expected. Attributes live under `attributes`, associations under `relationships` with type-and-id references rather than embedded objects, and filters are bracketed as `filter[type]=1`. The pay-off is `include`: one request can return routes with their lines and agencies resolved in the `included` array, avoiding a chain of follow-up calls. Route types follow the GTFS numbering — 0 light rail, 1 heavy rail, 2 commuter rail, 3 bus, 4 ferry.

Quick facts

Base URL
https://api-v3.mbta.com
Authentication
No key required. A free key, obtained from the MBTA developer portal, raises the rate limit substantially but is not needed to use the API.
Rate limit
20 requests per minute without a key, 1,000 per minute with one. Reported in `X-RateLimit-Limit` and `X-RateLimit-Remaining`.
Pricing
Free at both tiers.
CORS
Enabled — callable directly from browser JavaScript
Official docs
Read the docs

How to use the MBTA V3 API

Every request below was executed against the live API on 21 Aug 2026, and the response shown is the real body it returned — not an illustration.

1. List Boston subway lines by route type

GET https://api-v3.mbta.com/routes?filter%5Btype%5D=1&page%5Blimit%5D=2

curl
curl 'https://api-v3.mbta.com/routes?filter%5Btype%5D=1&page%5Blimit%5D=2'
JavaScript (fetch)
const res = await fetch("https://api-v3.mbta.com/routes?filter%5Btype%5D=1&page%5Blimit%5D=2");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://api-v3.mbta.com/routes?filter%5Btype%5D=1&page%5Blimit%5D=2", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200 (truncated)
{
  "data": [
    {
      "attributes": {
        "color": "DA291C",
        "description": "Rapid Transit",
        "direction_destinations": [
          "Ashmont/Braintree",
          "Alewife"
        ],
        "direction_names": [
          "South",
          "North"
        ],
        "fare_class": "Rapid Transit",
        "listed_route": true,
        "long_name": "Red Line",
        "short_name": "",
        "sort_order": 10010,
        "text_color": "FFFFFF",
        "type": 1
      },
      "id": "Red",
      "links": {
        "self": "/routes/Red"
      },
      "relationships": {
        "agency": {
          "data": {
            "id": "1",
            "type": "agency"
          }
        },
        "line": {
          "data": {
            "id": "line-Red",
            "type": "line"
          }
        }
      },
      "type": "route"
    },
    {
      "attributes": {
        "color": "ED8B00",
        "description": "Rapid Transit",
        "direction_destinations": [
          "Forest Hills",
          "Oak Grove"
        ],
        "direction_names": [
          "South",
          "North"
        ],
        "fare_class": "Rapid Transit",
        "listed_route": true,
        "long_name": "Orange Line",
        "short_name": "",
        "sort_order": 10020,
        "text_color": "FFFFFF",
        "type": 1
      },
      "id": "Orange",
      "links": {
        "self": "/routes/Orange"
      },
      "relationships": {
        "agency": {
          "data": {
            "id": "1",
            "type": "agency"
          }
        },
        "line": {

Parameters

ParameterTypeRequiredDescription
filter[type]queryOptionalGTFS route type: 0 light rail, 1 heavy rail, 2 commuter rail, 3 bus, 4 ferry. 1
page[limit] / page[offset]queryOptionalPage size and offset, in JSON:API bracket notation. 2
filter[stop] / filter[route]queryOptionalNarrow predictions, schedules or vehicles to a stop or route. place-sstat
includequeryOptionalResolve related resources into the `included` array in the same response. line,agency
sortqueryOptionalField to sort by; prefix with `-` to reverse. sort_order
(predictions)pathOptional`/predictions` returns live arrival and departure estimates. predictions
(alerts, vehicles)pathOptionalService alerts and live vehicle positions, on their own endpoints.

Response fields

dataarray
JSON:API resource objects. The useful values are inside `attributes`, not at the top level.
data[].idstring
Resource identifier — "Red", "Orange", "place-sstat". Human-readable for routes and stations.
attributes.long_name / short_namestring
Route names. Subway lines use `long_name` ("Red Line"); buses use `short_name` (the route number).
attributes.color / text_colorstring
Official hex colours without the leading hash, for rendering line badges correctly.
attributes.direction_names / direction_destinationsarray
Two-element arrays indexed by direction id — ["South", "North"] paired with their destinations.
attributes.typeinteger
GTFS route type. 1 is heavy rail, which is what the example filters on.
attributes.fare_classstring
Fare category, such as "Rapid Transit" or "Commuter Rail" — what a rider is charged, not how the vehicle runs.
relationshipsobject
References to related resources by type and id. Use `include` to have them resolved in one call.
(predictions) arrival_time / departure_time / statusstring
Live predicted times and status text, on the predictions endpoint.

What you can build with the MBTA V3 API

  • Build a live arrival board for a Boston station or stop
  • Show subway, bus and commuter rail routes with official colours
  • Alert riders to delays and diversions from the alerts endpoint
  • Track live vehicle positions on a map
  • Plan trips using schedules, trips and stop sequences

Common errors and how to fix them

429 Too Many Requests

The keyless tier allows 20 requests per minute.

Fix: Read `X-RateLimit-Remaining`, and request a free key from the developer portal if you need more — it raises the limit to 1,000 a minute.

Fields are missing from data[]

JSON:API nests values under `attributes`.

Fix: Read `data[i].attributes.long_name`, not `data[i].long_name`. This is the most common first mistake with the API.

400 on a filter parameter

Filters use bracket notation.

Fix: Write `filter[type]=1`, URL-encoded as `filter%5Btype%5D=1`. A bare `type=1` is ignored or rejected.

Predictions are empty for a valid stop

No vehicle is currently scheduled to arrive there.

Fix: Predictions cover a short forward window only. Use `/schedules` for planned times outside it, and expect nothing overnight.

MBTA V3 API — frequently asked questions

Do I need an API key for the MBTA API?

No. It works without one at 20 requests per minute. A free key from the MBTA developer portal raises that to 1,000 a minute, but nothing is gated behind it.

Why is the response structured so unusually?

It follows the JSON:API specification, which puts values under `attributes` and links under `relationships`. The benefit is the `include` parameter, which resolves related resources in a single request instead of a chain of calls.

What do the route type numbers mean?

They are GTFS values: 0 light rail (the Green Line), 1 heavy rail (Red, Orange, Blue), 2 commuter rail, 3 bus, 4 ferry. Filtering on `filter[type]` is how you separate modes.

Does it cover the whole Boston area?

It covers everything the MBTA operates — subway, bus, commuter rail, ferry and the RIDE paratransit service — across greater Boston and eastern Massachusetts. Neighbouring agencies are not included.

Tools that pair with this API

Alternatives to MBTA V3 API

If MBTA V3 API does not fit, these transport & vehicle apis cover similar ground. Every one was called before publishing, and each links to its own reference page with a working curl command and the response it returned.

APIWhat it doesAuthCORSLast verified
NHTSA vPICFree NHTSA vPIC API with no key: decode any VIN, list vehicle makes and models, and get manufacturer and specification data. Tested curl example.No keyNo19 Aug 2026
NHTSA RecallsFree NHTSA recalls API with no key: look up open safety recalls by make, model and year, with remedy details and Park It warnings. Tested curl example.No keyNo19 Aug 2026
Transport for LondonFree Transport for London API: live tube line status, arrivals, journey planning, bike hire and stop points across London. No key for light use. Tested example.No keyYes19 Aug 2026
OpenSky NetworkFree OpenSky Network API: live aircraft positions, altitude, velocity and callsigns worldwide from crowd-sourced ADS-B receivers. Tested curl example.No keyNo19 Aug 2026
Metro de Lisboa (Line Status)Free Lisbon Metro line status feed with no key: current service state for all four lines in one tiny JSON response. Tested curl example and live response included.No keyNo21 Aug 2026
Mobilités M (Grenoble)Free Grenoble public transport API with no key: tram and bus routes, stops, live arrivals and journey planning on an OpenTripPlanner backend. Tested example included.No keyYes21 Aug 2026
All Transport & Vehicle APIs

MBTA V3 API is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 21 Aug 2026; always check the official documentation before relying on this API in production, as terms and limits can change.