Explainer · Feeds & Standards
The Transit Operational Data Standard (TODS), explained: the schedule the garage runs, in GTFS files
The GTFS feed an agency publishes stops at the first revenue stop. TODS is the ten-file extension that adds the pull-outs, deadheads, crew runs, and vehicle assignments behind it, so a scheduling system can hand a day's work to CAD/AVL without a custom export.
Every transit schedule exists twice. The version riders see is the one in the GTFS feed: revenue trips, public stops, arrival times. The version the garage runs starts earlier and ends later. A bus pulls out of the yard at 09:45 with nobody on it, the operator has already signed in and walked around the vehicle, a second operator takes over at a stop in the middle of the second trip, and at 15:00 the bus is back in the yard on a route that has no number. None of that is in GTFS, because GTFS was built for trip planning and the trip planner does not need it.
The scheduling system knows all of it, because the scheduling system produced it. The problem is that the computer-aided dispatch and automatic vehicle location system, the CAD/AVL, needs it too, and for most of the industry’s history the handoff between the two has been a vendor-specific file that gets rebuilt every time either side is replaced. The Transit Operational Data Standard, TODS, is the attempt to make that file a standard one. It extends GTFS rather than replacing it, its current version is 2.1.0, adopted on 2025-04-16, and it is small: ten files, all of them optional, and 28 fields of its own beyond what GTFS already defines.
The name has moved. The specification was ODS, the Operational Data Standard,
from its first version in 2022. MobilityData’s March 2024 announcement that it
was taking over management already called it TODS, using a third variant,
Transit Operational Data Specification, and on 2024-06-26 the board gave its
program manager authority to change the branding from ODS to TODS across the
governance documents. The project’s own
citation block still tells authors to cite it at an ods.calitp.org address,
which now redirects to tods-transit.org. All four names mean this
specification.
What the public feed leaves out
The project’s FAQ gives the list of what operational data is: which vehicles run which routes, which operators work which routes, when and where vehicles pull in and out, non-revenue movement, and service disruptions. The first four are what TODS covers. A schedule that has been through runcutting has three layers of structure that GTFS flattens away.
Blocks are the vehicle’s day: a chain of trips one bus runs from pull-out to
pull-in. GTFS has a block_id on trips.txt, but it is optional and it says
nothing about the deadheads between the trips or the garage at either end. Runs
are the operator’s day, which is not the same thing, because a block that runs
from the morning peak to the evening one is worked by more than one person.
Pieces are the stretches of a
run between breaks. And every one of those things happens at places that are
not in stops.txt: the yard, a relief point on a street corner, a layover
loop.
TODS is the set of files that puts those back.
The supplements and the four new files
The design in version 2 is different from version 1, and the difference is the
most useful thing to understand about the specification. Version 1 invented its
own files for non-revenue service and crew: deadheads.txt,
ops_locations.txt, deadhead_times.txt, runs_pieces.txt, and
run_events.txt, 39 fields in total, parallel to GTFS and joined to it by trip
identifiers. Version 2.0 deleted four of the five. The three deadhead files were
replaced by supplement files, and pieces survive only as an optional
piece_id column on a rebuilt run_events.txt. The two calendar supplements
came later, in 2.1.0.
A supplement file has the same columns as the GTFS file it is named for. The
spec gives three rules for merging one into
the public feed. If the row’s primary key exists in the GTFS file and the
TODS_delete field is 1, the GTFS row is removed. If the key exists and
TODS_delete is not 1, any non-blank values in the supplement row overwrite the
GTFS values. If the key does not exist, the whole row is added. Blank cells are
ignored, so a supplement row can change one column and leave the rest alone.
The spec’s own example is a stops.txt with three stops and a
stops_supplement.txt with three rows: one that deletes stop 2, one that
rewrites the description of stop 3, and one that adds a stop 4. The merged
result is a valid stops.txt with stops 1, 3, and 4. The same mechanism adds a
deadhead as a trip on a route called deadheads, adds the garage as a stop with
TODS_location_type set to garage, and adds the stop times that put the bus
at the garage at 09:45 and at the first revenue stop at 09:55.
| File | Kind | What it does |
|---|---|---|
trips_supplement.txt |
Supplement | Adds deadheads and other non-public trips, or changes public ones |
stops_supplement.txt |
Supplement | Adds garages, waypoints, and relief points, or changes public stops |
stop_times_supplement.txt |
Supplement | Adds times at non-public locations and times for non-public trips |
routes_supplement.txt |
Supplement | Adds internal routes such as a deadhead route |
calendar_supplement.txt |
Supplement | Adds or adjusts service patterns for crew and deadhead calendars |
calendar_dates_supplement.txt |
Supplement | The same, for exception dates |
run_events.txt |
TODS-specific | Every event in an employee’s run, in order, with start and end place and time (14 fields) |
employee_run_dates.txt |
TODS-specific | Which employee works which run on which date (4 fields) |
vehicles.txt |
TODS-specific | The fleet: identifier, label, plate or MMSI (3 fields) |
vehicle_assignments.txt |
TODS-specific | Which vehicle covers which block on which date (4 fields) |
Only three fields are TODS’s own in the supplement files: TODS_delete, which
works in any of them, TODS_trip_type on trips, and TODS_location_type on
stops. Everything else is GTFS’s column set. A row that adds a new entry has to
carry every field the GTFS file marks required, a rule the spec spelled out in a
clarification merged on 2026-09-08 without a version bump. The six supplements
were adopted with 2.0 and 2.1.0; the reference page adds that extending the
mechanism to other GTFS files “is not yet formally adopted into the
specification and remains subject to change.” The four TODS-specific files
carry the other 25 fields, and after a feed has been merged the spec expects
the result to be a valid GTFS dataset, with the stated exception of references
to deleted rows, which consumers are told to ignore. An agency’s existing
validator can therefore check most of it.
A run, event by event
run_events.txt is the heart of the specification and the file that has no
GTFS analogue. Its primary key is the triple of service_id, run_id, and
event_sequence, and the first two of those together are what identifies a
run, because agencies reuse run numbers freely: the spec’s own example is a Run
100 on weekday and weekend service, and even a Run 100 at two garages on the
same day. Each row is one event with a start_location, start_time,
end_location, and end_time, a free-text event_type such as Report Time or
Pull-Out, an optional job_type, and an optional trip_id if the event is
working a trip.

The worked example behind that
chart is nine rows. The operator reports at 09:30 at the garage, an event whose
start and end times are equal because it is an instant. A pre-trip inspection
runs 09:35 to 09:45. Pull-out is a deadhead trip that exists only in
trips_supplement.txt. Trips 101 and 102 are ordinary rows in the public
trips.txt. The break from 11:50 to 13:00 has no trip and no piece. Trips 103
and 104 and the pull-back make up the second piece. Two pieces, one block, one
run.
Mid-trip relief is handled with two fields, start_mid_trip and end_mid_trip.
In the spec’s second example, run 10000 works trip 101 and the first half of
trip 102, ending at stop 2 with end_mid_trip set to 1. Run 20000 starts at stop
2 with start_mid_trip set to 1 and finishes trip 102, then does 103 and 104.
The trips in GTFS do not change. The relief exists only in how two runs’ events
reference the same trip_id.
The spec has two more design choices that show what the authors had been
through. Runs can be on a different service_id from the trips they work, so an
agency that schedules crew on a seasonal pattern and vehicles on a weekday
pattern does not have to
rewrite its public calendar; it adds the crew calendar in
calendar_supplement.txt. And events without a trip may overlap in time, so a
row can say an operator is available from 09:00 to 12:00 while other rows say
what they did in that window. The spec’s run-as-directed example shows the
no-trip case without the overlap: a sign-in, a deadhead, a three-hour block
with no trip at all, and a deadhead back.
Version 2.1.0 added the last two pieces. employee_run_dates.txt assigns an
employee identifier to a run on a date, after vacations and holidays have been
applied, and the spec says plainly that the identifier references the agency’s
own systems and is used nowhere else in TODS. vehicle_assignments.txt puts a
vehicle on a block for a date. vehicles.txt has three fields, recommends that
vehicle_id match the one in the agency’s GTFS-Realtime feed, and notes that a
future version may take up the GTFS-VehicleCouplings draft for train consists;
the assignments file points at the GTFS-Vehicles draft for vehicle categories.
TIDES has its own vehicle tables
with the same GTFS-Realtime alignment. Where TODS says which bus was supposed
to cover block A on
February 5, TIDES says which bus did, and where it was every few seconds while
doing so.
Where it came from and who runs it
Cal-ITP, the California Integrated Travel Project of the state transportation agency and Caltrans, studied the problem in 2020. Its history page says the friction between scheduling and operating was at its worst during the pandemic, when schedules changed constantly with labor availability. The feasibility phase consulted 14 organizations, from LADOT and Santa Barbara MTD to the Chicago Transit Authority and MBTA, plus Optibus, Clever Devices, Swiftly, and The Master Scheduler on the vendor side. The working group convened in 2021 and approved version 1.0.0 on 2022-05-03. The first implementations, per the project, were WETA, the San Francisco Bay ferry operator, and Swiftly.
The FAQ also answers the question every standards veteran asks, which is why this is not NeTEx or TCIP. Its answer on NeTEx is that it has no foothold in North America and that vendors prefer GTFS’s simpler model. On TCIP, APTA’s interface profile from roughly twenty years earlier, the answer is that it never achieved significant adoption and has not kept pace with GTFS. TODS is a bet that a GTFS-shaped file will be adopted where a more complete one was not.
Governance moved out of California in stages. On 2024-03-11 the board granted its program manager authority to move the repository out of the Cal-ITP GitHub organization and elected a chair and a coordinator. MobilityData announced on 2024-03-04 that it would assume management of TODS, TIDES, and the Mobility Data Interoperability Principles, all three incubated by Cal-ITP. The same nonprofit already stewards GTFS and, as the shared-mobility data stack piece covers, GBFS. An agency’s scheduling, dispatch, analytics, and bike-share data can pass through five specifications that now have one manager.
The board has five seats: MBTA, whose representative is coordinator, INIT, Giro, the Chicago Transit Authority, whose representative chairs, and Keolis Commuter Services. That is two agencies, one contractor that operates service, and two vendors, one of them Giro, the maker of the Hastus scheduling system. A MobilityData program manager runs the change process. Versions became semantic on 2024-06-26 and are bundled per development cycle rather than issued per proposal. On 2025-03-26 the board directed the manager to lead at least one development cycle a year; version 2.1.0 was adopted on 2025-04-16 and the policy amendment on 2025-04-23. The actions log records the votes in one table with counts, though the 2.1.0 adoption itself appears only in the revision history.
Who has actually implemented it
The project’s front page lists implementers with a check mark. We counted them against the contributors page.
The site marks six organizations as having implemented version 1.0: WETA, Swiftly, Equans Navineo, The Master Scheduler, Remix by Via, and Optibus, with Giro’s Hastus marked available on request. For version 2.0 and later, one: Optibus. MBTA and Keolis Commuter Services, which hold two of the five board seats, are marked in progress.
The contributors group lists 18 transit agencies and 19 companies, and states that contributors commit to supporting version 1. Of the 19 companies, five carry the implemented mark, one of them, Giro, annotated on request, leaving 14, among them Trapeze, Clever Devices, Cubic, GMV Syncromatics, Avail, and Passio, listed as contributors without an implementation. Of the 18 agencies, one, MBTA, is marked in progress. WETA, the first agency implementer, is not on the contributors list at all. California, where the working group was convened, accounts for 13 of the 18 agencies. None of these lists is dated, and the marks are the project’s own.
That is the state of a specification whose first version is four years old. The scheduling side has moved: Optibus on 2.0, Hastus on request, The Master Scheduler and Remix on 1.0. The consuming side, the other half of the handoff TODS exists to standardize, is thinner. Swiftly, a real-time data platform, is on 1.0. Equans Navineo, the one CAD/AVL vendor with a mark, is on 1.0. Nobody on that side is on 2.0. The board’s own 2024-09-18 actions record offers of assistance to Giro, Optibus, and GMV for 2.0 integrations. The implementation guide page on the site reads, in full, “Forthcoming.”
There is no official validator and no sample feed in the specification repository. The examples are prose and CSV fragments. A third-party tool, tods-validate, a beta from a single developer that first appeared in June 2026, checks feeds against 2.1.0 and publishes a conformance corpus of 43 fixtures. Its author opened an issue on 2026-07-12 asking the board whether it wants to adopt that corpus as official, saying they did not want to call it a TODS conformance suite without a board decision. The issue was open at the time of writing. The same developer wrote the packaging proposal below and the September clarification to the spec text, so much of the visible activity around TODS this summer traces to one person.
The absence of public feeds is by design. The front page
says it directly: TODS data is typically not published, to preserve the privacy
of internal operations data. A run_events.txt is a crew schedule and an
employee_run_dates.txt is a roster with employee identifiers. An agency that
has implemented TODS has a file moving between two of its vendors, not a URL.
How an agency gets it
The site’s advice to an agency is two lines: ask your scheduling and CAD/AVL vendors, or write it into the next procurement. The Mobility Data Interoperability Principles publish sample procurement language for TODS and other interoperability requirements. That is the whole adoption mechanism, and it puts the specification’s growth in the hands of agencies replacing systems, which happens on a cycle measured in years.
For a vendor, the site’s claim is that most already read and write GTFS, so
TODS is a marginal lift. The supplement design is what makes that claim
plausible: a scheduling system that can export GTFS can export a
trips_supplement.txt with the same code path and a different filter, and a
CAD/AVL system that imports GTFS can merge the supplement before it imports.
The genuinely new work is run_events.txt, and that is 14 fields.
What to watch
The open proposals show where the pressure is. A proposal opened on
2026-07-14
asks for a blocks.txt file with pull-out and pull-in
times, garage identifiers, and required vehicle type and propulsion, along with
matching capability fields on vehicles.txt. The stated drivers are two.
Zero-emission fleets: a battery bus with a charging window cannot swap onto any
block the way a diesel could, and today scheduling and CAD/AVL vendors each
solve that privately, which is the gap TODS was created to close. And yard
management systems, which work at the block level and today have to reconstruct
pull-out and pull-in times from deadhead trips in the supplement files. The same
issue points out that vehicle_assignments.txt already depends on block_id,
which GTFS makes optional, and asks for a rule that requires it on every trip
belonging to a block the assignments file references. A rosters.txt proposal
has been open since 2023; its author has since left the board. A packaging
convention, so that a TODS dataset has an agreed shape as a file rather than a
loose set of CSVs, was proposed on 2026-07-12.
The repository is also mid-reorganization. A rename to TODS was proposed in
June 2026 and a split of the website out of the specification repository in
July, and both were still open in September. The site’s own configuration still
names a MobilityData subdomain as its canonical address and the pre-rename
repository as its source, while tods-transit.org is the address on the front
page.
The measure of the specification is not the version number. It is whether a CAD/AVL vendor ships 2.x, because until then an agency that writes the current version into a procurement is choosing from one scheduling vendor and no dispatch vendor. The board has the right people on it to change that. As of September 2026, the check marks say it has not happened yet.
Common questions
- What is the Transit Operational Data Standard?
- TODS is an open specification that extends GTFS with the operational detail a transit provider needs to run scheduled service but does not publish to riders: deadhead trips, garage and layover locations, crew runs and their pieces, mid-trip reliefs, employee assignments by date, and which vehicle covers which block. Its main use is moving a finished schedule from a scheduling system into CAD/AVL and other operations software without a vendor-specific export. The current version is 2.1.0, adopted 2025-04-16.
- Is TODS the same as ODS?
- Yes. The specification was called the Operational Data Standard, or ODS, from its first version in 2022. The board voted on 2024-06-26 to rebrand it as TODS, the Transit Operational Data Standard. MobilityData's March 2024 announcement used a third variant, Transit Operational Data Specification, and the project's own citation block still points at the old ods.calitp.org domain.
- How does TODS relate to GTFS?
- TODS does not restate GTFS. Of its ten files, six are supplement files that carry the same columns as trips.txt, stops.txt, stop_times.txt, routes.txt, calendar.txt, and calendar_dates.txt, and are merged into the public feed by primary key: matching rows are updated or deleted, unmatched rows are added. The other four files, run_events.txt, employee_run_dates.txt, vehicles.txt, and vehicle_assignments.txt, describe crew and vehicle work that GTFS has no place for. The result after merging is meant to be a valid GTFS dataset with the non-public service added in.
- Who uses TODS?
- As listed on the project's site in September 2026: six organizations implemented version 1.0, namely WETA, Swiftly, Equans Navineo, The Master Scheduler, Remix by Via, and Optibus, with Giro's Hastus available on request. Only Optibus is listed as implementing version 2.0 or later, with MBTA and Keolis Commuter Services in progress. The contributors group lists 18 transit agencies and 19 companies.
- Is TODS data public?
- Usually not. The specification is open, but the project's site says TODS data is typically not published, to preserve the privacy of internal operations data, since it contains crew schedules and employee assignments. That is the main practical difference from its sibling TIDES, which describes what vehicles actually did and which Caltrans derives and publishes for California's fixed-route agencies.
- What is a run in TODS?
- A run is one employee's scheduled day of work, identified by the pair of service_id and run_id, because run numbers are commonly reused across service patterns. It is described in run_events.txt as an ordered sequence of events, each with a start and end location and time: sign-in, pre-trip inspection, a pull-out deadhead, revenue trips, a break, and a pull-back. A run can begin or end in the middle of a trip, which is how TODS represents a mid-trip relief.