Skip to main content

transitmatters-py

MBTA performance data from the TransitMatters Data Dashboard, as Python objects: travel times, headways, dwells, ridership, service levels, delays, speed restrictions, and alerts.

pip install transitmatters
from transitmatters import TransitMatters

tm = TransitMatters()

# Every southbound Red Line trip from Alewife to Braintree on March 4, 2025
trips = tm.travel_times("2025-03-04", from_stop="70061", to_stop="70105")
print(trips[0].dep_dt, trips[0].travel_time_sec)

Dates can be datetime.date objects or "YYYY-MM-DD" strings, and date ranges include both ends. Parameters that take IDs accept one string or a list.

Which method do I want?

What happened on one day. Each item is a single event.

Question Method Each item is
How long did trips between two stops take? TransitMatters.travel_times a trip
How long between departures at a stop? TransitMatters.headways a departure
How long did vehicles sit at a stop? TransitMatters.dwells a stop a vehicle made
Which alerts were posted for a route? TransitMatters.historical_alerts an alert
Where were speed restrictions on a line? TransitMatters.speed_restrictions a zone, in .zones

Trends over a date range. Each item summarizes one day, week, or month.

Question Method Each item is
Travel-time statistics between two stops TransitMatters.aggregate_travel_times a day
...also broken down by time of day TransitMatters.aggregate_travel_times_v2 a day, or a 30-minute slot
Headway statistics, bunching, and on-time counts at a stop TransitMatters.aggregate_headways a day
Dwell-time statistics at a stop TransitMatters.aggregate_dwells a day
Trip count, speed, and miles for a rapid transit line TransitMatters.trip_metrics a day, week, or month
Minutes of delay on a line, by cause TransitMatters.line_delays a day or week
Number of scheduled trips on a route TransitMatters.scheduled_service a day, week, or month, in .counts
Scheduled vs. delivered service hours TransitMatters.service_hours a day, week, or month
Ridership on a line TransitMatters.ridership a week
How accurate arrival predictions were TransitMatters.time_predictions a week

Right now, and system-wide.

Question Method
Which alerts are in effect now? TransitMatters.current_alerts
Where are the elevators and escalators? TransitMatters.facilities
Service and ridership across the whole system TransitMatters.service_ridership_dashboard
Is the API healthy? TransitMatters.healthcheck

Finding IDs

Each kind of ID has its own format, and some endpoints spell the same line differently. Check this table before guessing:

Parameter Used by Looks like
stop, from_stop, to_stop headways, dwells, travel_times, aggregate_* "70061" (rapid transit), "1-0-110" (bus), "CR-Fairmount_0_DB-2205-01" (commuter rail)
route, route_id historical_alerts, scheduled_service, time_predictions, stops "Red", "66", "CR-Fairmount", "Boat-F1"
line line_delays "Red", "CR-Fairmount"
line, line_id trip_metrics, service_hours "line-red" (lowercase; rapid transit only)
line_id ridership "line-Red", "line-66", "line-Fairmount"
line_id speed_restrictions "line-Red" (case-sensitive; rapid transit only)

TransitMatters.routes lists every route ID. TransitMatters.stops lists the stations on a route, with the stop ID of each platform by direction:

red = tm.stops("Red")
print(red.direction.to_dict())  # {'0': 'northbound', '1': 'southbound'}
for station in red.stations[:3]:
    print(station.stop_name, station.stops.to_dict())
# Alewife {'0': ['70061'], '1': ['70061']}
# Davis {'0': ['70064'], '1': ['70063']}
# Porter {'0': ['70066'], '1': ['70065']}

Platforms have separate IDs for each direction, so from_stop and to_stop must both be platforms for the direction you're traveling. Southbound from Davis to Porter is from_stop="70063", to_stop="70065".

A stop ID that doesn't exist isn't an error; you just get an empty list back.

Working with pandas

Every result is a model object (see transitmatters.models), and every model has to_dict():

import pandas as pd

events = tm.headways("2025-03-04", stop="70061")
df = pd.DataFrame([e.to_dict() for e in events])
df["current_dep_dt"] = pd.to_datetime(df["current_dep_dt"])
  • Timestamps are Eastern local time, formatted YYYY-MM-DDTHH:MM:SS with no offset.
  • to_dict() uses the API's field names. A few differ from the Python attribute names, e.g. min and 25% instead of min_ and field_25.
  • When a response wraps its list in a field, such as scheduled_service(...).counts or speed_restrictions(...).zones, build the DataFrame from that field.

Errors

When the API rejects a request, methods raise transitmatters.APIError:

from transitmatters import APIError

try:
    tm.stops("Purple")
except APIError as e:
    print(e.status_code, e.message)  # 404 Route 'Purple' not found

Async

transitmatters.AsyncTransitMatters has the same methods, as coroutines. It's useful for fetching many days at once. In Jupyter you can await directly in a cell.

import asyncio
from transitmatters import AsyncTransitMatters

async def main():
    async with AsyncTransitMatters() as tm:
        days = ["2025-03-03", "2025-03-04", "2025-03-05"]
        return await asyncio.gather(*(tm.headways(d, stop="70061") for d in days))

per_day = asyncio.run(main())

Development

uv sync
uv run pytest
uv run python scripts/docs.py  # preview the API docs at http://localhost:8080

The API docs are built from this README and the docstrings in src/transitmatters/, and are published to GitHub Pages on every push to main.

src/transitmatters/_generated/ is generated from the upstream OpenAPI spec by openapi-python-client; don't edit it by hand. A weekly workflow syncs the spec and opens a PR (see scripts/sync_spec.py). The public API lives in src/transitmatters/client.py.

Metadata

Release files for transitmatters 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for transitmatters 0.1.0
File Size Uploaded
transitmatters-0.1.0.tar.gz 90.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for transitmatters 0.1.0
File Interpreter ABI Platform
transitmatters-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 214.6 kB

Release files / transitmatters-0.1.0.tar.gz

Download URL transitmatters-0.1.0.tar.gz
Size 90.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5a044ad70e4b8a57030410fda3d62b666293e680e165adbea9c66f576c9cd608
BLAKE2b-256 checksum
How to use checksums
a62c3ad3e3019c1ea4db0caf3a73f7fad8a730d9574fdd220aff84a152ea03bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / transitmatters-0.1.0-py3-none-any.whl

Download URL transitmatters-0.1.0-py3-none-any.whl
Size 124.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
645cfc67b067fc6574c2c0ae81c34139e3a82119657772ef8018e9440d734a88
BLAKE2b-256 checksum
How to use checksums
f68c0c953e112b35696e1fc1a3677731ed7baf171f9383a063c6ee1b4205bfe3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page