One signal.
A shared language.
Follow a vehicle observation into a dated trip, a published feed and a passenger answer. The identifiers stay connected at every step.
Standardise the boundary.
Keep the existing standards.
AIS-140 concerns vehicle-side telemetry. GTFS describes passenger services. UTI proposes the adapter contract between them: identity, units, timestamps, assignment evidence and publication rules.
Vendor packets can differ. The JSON below is our normalized adapter output, not a universal AIS-140 wire format or a certification claim.
Live synthetic example
Inspect one bus, end to end.
Input format
The observation contract.
Send JSON to POST /v1/observations on the bridge. Batch ingestion accepts an array at POST /v1/observations/batch. Invalid fields are rejected; unknown assignments do not become invented trips.
| Field | Type and constraint | Meaning |
|---|---|---|
schemaVersion | Required · literal 1.0 | Version of this normalized adapter contract. |
sourceProtocol | Required · AIS-140 | Source family, not a claim of a universal AIS-140 JSON packet. |
providerId / vehicleId | Required · non-empty strings | Source provider and stable vehicle identity. |
observedAt | Required · ISO 8601 with offset | When the source measured the position. Not when the server received it. |
receivedAt | Optional · ISO 8601 with offset | Receipt time, separate from measurement time. |
position.latitude / longitude | Required · WGS84 degrees | Latitude −90…90; longitude −180…180. |
speedKph / headingDegrees | Required · 0…180 km/h; 0…<360° | Convert speed to m/s for GTFS-Realtime. Heading is clockwise from north. |
routeHint / tripHint / serviceDate | Optional in schema; required for network assignment | Validate the route and dated trip against the schedule. serviceDate is YYYYMMDD. |
The contract is versioned as JSON Schema 2020-12. Schema validity alone does not prove a trip exists: assignment also checks its service date, route and time window. The current reference implementation uses explicit hints, not inferred dispatch assignments.
The static foundation
A timetable is a set
of connected tables.
GTFS Schedule is a ZIP of CSV files. A route is not a vehicle; a trip is one run of that route; a stop is a location. Shared IDs connect the records. Schedule reference ↗
| File | Key fields | What it tells a consumer |
|---|---|---|
agency.txt | Operator and timezone | The demo uses Asia/Kolkata. |
stops.txt | stop_id, stop_name, stop_lat, stop_lon | A physical boarding or alighting point. |
routes.txt | route_id, route_short_name, route_type | The service riders recognise. Bus route_type = 3. |
trips.txt | route_id, service_id, trip_id, shape_id | One scheduled run in a particular direction. |
stop_times.txt | trip_id, arrival_time, departure_time, stop_id, stop_sequence | Ordered calls, with separate arrival and departure times. |
calendar.txt / shapes.txt | Service dates / ordered coordinates | When a trip operates, and the path it follows. |
routes.route_id → trips.route_id trips.trip_id → stop_times.trip_id stops.stop_id → stop_times.stop_id trips.service_id → calendar.service_id trips.shape_id → shapes.shape_id
Service times belong to the agency timezone. A trip crossing midnight keeps its original service date and can have stop times beyond 24:00:00. Our calendar operates daily from 1 January 2026 through 31 December 2027.
Realtime format
Same trip.
Updated information.
The wire format is Protocol Buffers. JSON endpoints are inspection views of those messages; camelCase names in this inspector correspond to the specification's snake_case fields. Realtime reference ↗
| UTI input | Published field | Rule |
|---|---|---|
vehicleId | vehicle.id | Same physical vehicle across observations |
observedAt | VehiclePosition.timestamp | UTC epoch seconds, not milliseconds |
speedKph / 3.6 | position.speed | Metres per second |
assignment | trip.trip_id + trip.start_date | The dated trip in the published schedule |
shape progress + timetable | stop_time_update | Predicted arrivals/departures; 45-second uncertainty in this simulator |
VehiclePositions
Position, bearing, speed and the observation timestamp, linked to the dated trip. The feed timestamp says when the feed was generated; it does not make an older GPS fix fresh.
TripUpdates
Ordered stop predictions with arrival, departure, delay and uncertainty. This demo estimates them from progress along the route and its timetable, without traffic data.
Both feeds declare GTFS-Realtime 2.0 and FULL_DATASET. Missing live data falls back to the schedule. The rider map hides fixes older than 90 seconds.
Use the actual output.
Open the full feed, download the timetable or build against the contracts. These are the interfaces used by this demo, not screenshots of a proposed integration.