Nov 2, 2026 / Gary Tokman
NJ Transit and PATH realtime data in JavaScript with one client
In short
- NJ Transit, PATH, and LIRR each publish data differently. With mta-js you read all three through one client:
mta.njTransit.rail.departures(),mta.path.arrivals(), andmta.lirr.departures(). - NJ Transit direct: register, request access, wait for approval, mint a token, then send HTTP POST requests. mta-js: one API key, one client, GET requests over HTTP or SDK calls.
- Modes covered: PATH, NJ Transit rail, LIRR, Metro-North, subway, bus, NYC Ferry, Citi Bike.
What using NJ Transit directly involves
The demo above is live and uses the PATH and NJ Transit calls shown below.
NJ Transit's developer portal describes this path from sign-up to first call:
- Register an account and verify your email.
- Select the APIs you want and submit a request.
- Wait for an administrator to approve it.
- Mint a token by calling the token endpoint with your credentials.
- Call the API with your token.
Calls are HTTP POST requests with a multipart/form-data body. NJ Transit's Rail Data API document lists a limit of 10 accesses per day for token methods and 40,000 per day for current and vehicle data, so you should cache tokens and avoid constant polling. Check the developer portal for the current limits.
PATH
We did not find an official PATH developer portal comparable to NJ Transit's. Community projects such as mrazza/path-data were built to fill the gap. That one says it is not endorsed by the Port Authority, and its repository was archived in 2024.
One client for PATH, NJ Transit, and LIRR
Each mode returns its own typed rows. PATH arrivals carry mode: "path" and arrivalTime, NJ Transit departures carry mode: "nj-transit-rail", departureTime, track, and status, and LIRR departures carry time and trainNumber. All three include minutes, so you can merge them into one commuter board for a hub like Penn Station and sort by minutes. Log each response once to confirm which fields your mode returns.
import { MTA } from "mta-js"const mta = new MTA({ apiKey: process.env.MTA_API_KEY })// PATH arrivals at Journal Square, toward New Yorkconst path = await mta.path.arrivals({ station: "JSQ", direction: "to-ny" })// NJ Transit rail departures from New York Pennconst njTransit = await mta.njTransit.rail.departures({ station: "NY", limit: 10 })// LIRR departures from Penn Stationconst lirr = await mta.lirr.departures({ stop: "Penn Station", limit: 5 })
The same data over HTTP
The REST path is GET /api/v1/path/arrivals. Send your key in an x-api-key header or as a bearer token. See the API reference for parameters.
Mode endpoints
| Mode | Endpoints |
|---|---|
| PATH |
|
| NJ Transit rail |
|
| LIRR |
|
See the OpenAPI reference for parameters.
Self-host or use the hosted API
mta-js is open source under the MIT license. The hosted API removes the per-agency registration steps and gives you one key, one set of limits, and consistent response shapes. Indie starts at $19 per month with a 7-day free trial. See pricing.
FAQ
mta.njTransit.rail.departures({ station: "NY", limit: 10 }) with one mtaapi.dev API key.mta.path.arrivals().https://www.mtaapi.dev/mcp with your API key, and the get_path_arrivals and get_njt_rail_departures tools return the same data as the SDK.Get one API key for PATH, NJ Transit, LIRR, and the subway.