REST API - Route patterns
Last updated
The route patterns endpoint returns a route's stop patterns for one service date: each sequence of stops the route's trips serve that day, and how many trips run it. It can also return each pattern's stops, the shapes its trips follow, and a timetable of every trip's stop times.
For an overview of trips and schedules, see the Trips and schedules concept page.
Route patterns, trips, and departures
Use route patterns to get a route's schedule for a full service date. One request returns the arrival and departure times of every trip at every stop, as one timetable for each pattern.
Use the trips endpoint to get the details of one trip, such as its calendar, or its stop times with pickup and drop-off types. The trips endpoint returns stop times only for a request for a single trip by ID.
Use stop departures to get the trips that depart one stop within a time window, with real-time estimates where a feed provides them. Route patterns return scheduled times from the static GTFS feed only.
Request overview
Patterns are requested through a route, by the route's internal ID, a <feed onestop_id>:<route_id> key, or the route's Onestop ID. A route Onestop ID can match routes in more than one feed, so the response is a list of routes, each with its own patterns. Results are not paginated.
A route requested by Onestop ID or by <feed onestop_id>:<route_id> key is read from the "active" feed versions. An internal ID identifies a route in one feed version, whether or not that feed version is active.
Each pattern always includes its stop_pattern_id, direction_id, count of trips, and the requested service_date. Patterns are listed in order of count, highest first. Trips with the same stops but different direction_id values are listed as separate patterns with the same stop_pattern_id. The following parameters add fields:
| Parameter | Adds to each pattern |
|---|---|
include_stops=true | Its stops, in order, with names and locations |
include_shapes=true | Each shape its trips follow, once, with the distance along the shape at each point |
include_timetable=true | Its trips, and grids of their arrival times, departure times, and distances along their shapes |
Route pattern API results are based on this GraphQL query.
Dates
A date is required. Use service_date for a GTFS service date in YYYY-MM-DD format, or relative_date for a date relative to the current date in the feed version's timezone, such as TODAY, TUESDAY, or NEXT_TUESDAY. When both are given, relative_date is used. The stop departures page explains how relative dates are chosen.
The response includes only the patterns that have trips on that date. A pattern's count is the number of its trips that operate on that date. Its timetable lists those trips, except flex trips and trips whose stored stop times do not match the pattern's stops.
When the date is outside the feed version's service window, the endpoint uses the same day of the week in the feed version's fallback week: the week in the service window with the most scheduled service, preferring weeks with service on all seven days. The response's service_date is the requested date, not the fallback date. Set use_service_window=false to disable this fallback.
Timetable layout
A pattern's timetable contains its trips' stop times as grids. In every grid, row i is the stop stop_ids[i] and column j is the trip trips[j], so departure_times.values[i][j] is when trip j leaves stop i. Trips are ordered by their time at the first stop.
arrival_timesanddeparture_timesare GTFS times inHH:MM:SSformat. GTFS measures times from noon minus 12 hours on the service date, which is midnight except on days when daylight saving time changes. Times after midnight are later than24:00:00. Where the feed does not give a time for a stop, the grid contains the time Transitland interpolated on import.shape_distancesis each stop's distance along its trip's shape, in whole meters, measured the same way as thedistancesthatinclude_shapesreturns. It is null for a trip without a shape, and for a stop more than 500 meters from its trip's shape.
A cell is null where there is no value.
A trip defined by frequencies.txt appears once, as a template, and its frequencies field lists the periods and headways at which it repeats. Flex trips, which serve locations or time windows rather than set times, have no timetable.
Encoded responses
Timetables for routes with many trips produce large responses. The encoding=polyline parameter reduces response size. For example, a full service date of TriMet MAX Red Line timetables and shapes is 36 percent of its encoding=array size. With encoding=polyline:
- Each shape's
geometryis replaced bypolyline, an encoded polyline at five digits of precision. Withencoding=polyline6, it is replaced bypolyline6, at six digits. - Each timetable grid's
valuesis replaced bypolyline, one string for each row. Grids hold whole numbers, so they are encoded the same way underpolylineandpolyline6.
To decode a grid:
- Decode each row's string as a sequence of single integers with the encoded polyline algorithm, not as coordinate pairs, and without scaling. A
.marks a null cell. - Each integer is the difference from the previous non-null value in the row. The first integer is the difference from 0. Compute a running sum along the row.
- In each column, the first non-null value is absolute, and each later value is the difference from it. Add the first value to each later value. For times, the values are in seconds, measured as the
HH:MM:SStimes are.
For example, a departure_times grid's first row starts c_a@ooB and its second row starts oF??:
- The first row decodes to 17410, 1800. The second row decodes to 120, 0, 0.
- The running sums are 17410, 19210 for the first row and 120, 120, 120 for the second row.
- Adding each column's first value gives the times. The first two trips depart the first stop at 17410 and 19210 seconds (04:50:10 and 05:20:10), and depart the second stop 120 seconds later (04:52:10 and 05:22:10).
This JavaScript decodes one grid:
// Decode one row: polyline integers, each the difference from the last value present.
function decodeRow (s) {
const row = []
let prev = 0
let i = 0
while (i < s.length) {
if (s[i] === '.') {
row.push(null)
i++
continue
}
let result = 0
let shift = 0
let b
do {
b = s.charCodeAt(i++) - 63
result |= (b & 0x1f) << shift
shift += 5
} while (b >= 0x20)
prev += (result & 1) ? ~(result >> 1) : (result >> 1)
row.push(prev)
}
return row
}
// Decode a grid: rows are stops and columns are trips. Add each trip's first value back.
function decodeGrid (rows) {
const grid = rows.map(decodeRow)
const nTrips = grid[0]?.length ?? 0
for (let j = 0; j < nTrips; j++) {
let first = null
for (const row of grid) {
if (row[j] === null) {
continue
}
if (first === null) {
first = row[j]
} else {
row[j] += first
}
}
}
return grid
}
GEThttps://transit.land/api/v2/rest/routes/{route_key}/patterns
Request
route_stringrequiredkey - Route lookup key; can be an integer ID, a '<feed onestop_id>:<gtfs route_id>' key, or a Onestop ID
service_optional string (date)date - Return only the patterns that trips run on this date, counting their trips and building their timetables from this date's service. Required unless relative_date is given.
relative_optional stringdate - Search for departures on a relative date label, e.g. TODAY, TOMORROW, TUESDAY, NEXT_WEDNESDAY
Allowed:
TODAY,YESTERDAY,TOMORROW,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY,NEXT_MONDAY,NEXT_TUESDAY,NEXT_WEDNESDAY,NEXT_THURSDAY,NEXT_FRIDAY,NEXT_SATURDAY,NEXT_SUNDAY use_optional stringservice_ window - Use a fall-back service date if the requested date is outside the active service period of the feed version: the matching day of the week in the week with the most scheduled service. Defaults to true.
Allowed:
true,false include_optional stringtimetable - Include each pattern's timetable: its trips, and grids of their arrival times, departure times and distances along their shapes. Needs a date.
Allowed:
true,false include_optional stringshapes - Include the shapes each pattern's trips follow, each once, with the distance along it at each point
Allowed:
true,false encodingoptional string- How timetable grids and shape geometries are written: plain arrays, or encoded polylines. polyline6 encodes shape geometries at six digits of precision rather than five; timetable grids hold whole numbers either way. Defaults to array.
Allowed:
array,polyline,polyline6 license_optional stringcommercial_ use_ allowed - Filter entities by feed license 'commercial_use_allowed' value. Please see Source Feed concept for details on license values. 'exclude_no' is equivalent to 'yes' and 'unknown'.
Allowed:
yes,no,unknown,exclude_no license_optional stringcreate_ derived_ product - Filter entities by feed license 'create_derived_product' value. Please see Source Feed concept for details on license values. 'exclude_no' is equivalent to 'yes' and 'unknown'.
Allowed:
yes,no,unknown,exclude_no