mta-js uses MTA’s standard identifiers for stops and routes. These identifiers come directly from MTA’s GTFS static dataset—the same dataset that powers Google Maps, Apple Maps, and most third-party transit apps. Understanding how stop IDs, route IDs, and transit modes work is essential for querying the right data and interpreting the responses you receive.
Stop IDs
Every subway and bus stop in the MTA system has a unique stop ID defined in MTA’s GTFS static feed. Stop IDs are alphanumeric strings that identify a specific physical platform or stop location. For subway stops, the ID typically combines a letter prefix and a numeric suffix. For example,A27 identifies the Howard Beach–JFK Airport station on the A line. The same physical station can have multiple stop IDs if it serves multiple lines or has separate platforms for each direction.
stops.txt file.
Route IDs
Route IDs identify a specific subway line or bus route. mta-js uses these identifiers in method parameters to filter results to a single route. Subway route IDs match the line letter or number you see on signage and subway maps:
Bus route IDs use the MTA route designation, which includes a borough prefix and route number:
route parameters across the SDK are typed as smart-string unions. Subway-specific methods narrow to SubwayRoute, bus-specific methods to BusRoute, and pan-mode methods (alerts, stops) accept RouteId. You get autocomplete for valid IDs without losing the freedom to pass any string. See Typed route and stop IDs below.
Transit modes and directions
mode (or modes) parameter. The two most commonly used values are:
'subway'— the NYC subway system'bus'— the NYC bus network (local, express, and SBS routes)
'lirr' and 'metro-north' are also valid for service alerts. mta.subway.arrivals additionally accepts 'uptown' and 'downtown' as direction aliases — they’re normalized into the underlying Direction value for you.
Timestamps
Time values inmta-js responses are returned as ISO 8601 strings (e.g. '2026-05-26T17:12:29.787Z'), so you can pass them straight to new Date() without unit conversion.
Arrival also includes a precomputed minutes field for the common “minutes until arrival” use case, so you usually don’t have to do the math yourself.
TypeScript interfaces
mta-js ships with full TypeScript type definitions. Every response is a structured object — routes and stops are nested, not flat strings.
mta-js for use in your own annotations:
Typed route and stop IDs
mta-js exports literal union types generated from the live hosted stops snapshot, plus “smart string” wrappers that let you pass any string while still getting autocomplete for known values. Every stopId and route parameter on the SDK uses these wrappers, so your editor suggests valid IDs as you type — but you can still pass new or experimental IDs without fighting the type system.
The
(string & {}) intersection is the TypeScript trick that preserves autocomplete for the known literals while still allowing any string at the type level.
Known* unions directly:
These literal unions are regenerated from the hosted snapshot at
mtaapi.dev, so they always match the routes and stops the API currently knows about. Update mta-js to pick up newly added routes or stops.