GTFS + GTFS-Realtime Transit Feed Monitor (open-licensed) avatar

GTFS + GTFS-Realtime Transit Feed Monitor (open-licensed)

Under maintenance

Pricing

Pay per event

Go to Apify Store
GTFS + GTFS-Realtime Transit Feed Monitor (open-licensed)

GTFS + GTFS-Realtime Transit Feed Monitor (open-licensed)

Under maintenance

Normalize and monitor open-licensed public-transit feeds. Static GTFS (zipped CSV) to schedule snapshots and diffs; GTFS-Realtime (protobuf) to alerts, vehicle positions and trip updates. Only verifiably open-licensed feeds are decoded; each record carries its source license and attribution.

Pricing

Pay per event

Rating

0.0

(0)

Developer

ByteHaven Studios

ByteHaven Studios

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

GTFS + GTFS-Realtime Transit Feed Monitor

Normalize and monitor open-licensed public-transit feeds. Static GTFS (zipped CSV) becomes a schedule snapshot and, in monitoring mode, a schedule diff. GTFS-Realtime (Protocol-Buffers binary) becomes normalized service alerts, vehicle positions, or trip updates. Every record is stamped with its source feed's license and attribution.

This Actor is compliance-first. It decodes and redistributes feed content only for feeds whose license is verifiably open. See the data-source & licensing section below — it is load-bearing, not boilerplate.

Modes

modeInput feedOutput records
vehicle-positionsGTFS-RT .pbvehicle id/label, trip, route, lat/lon, bearing, speed, status, stop, timestamp
service-alertsGTFS-RT .pbcause, effect, header/description text, active periods, informed entities
trip-updatesGTFS-RT .pbtrip, route, per-stop arrival/departure delays + predicted times
static-diffGTFS .zipfirst run: schedule snapshot (route/stop/trip counts, service window); later runs: added/removed routes/stops/trips vs the previous run

Input

FieldTypeDefaultNotes
feedsstring[]— (required)Mobility Database mdb_source_ids (e.g. mdb-1 or 1) or direct GTFS/GTFS-RT URLs
modeenumvehicle-positionssee table above
openLicensesOnlybooleantruecompliance filter — keep ON (see below)
sinceDatestring""monitoring filter (YYYY-MM-DD)
maxRecordsPerFeedinteger00 = no cap
requestDelayMsinteger500polite pacing between feed fetches
fetchRetriesinteger2extra attempts on transient fetch failures (network / HTTP 408/429/5xx), exponential backoff; permanent 4xx never retried
retryBaseDelayMsinteger500retry backoff base; wait doubles each attempt
proxyConfigurationobjectproxy offmost open feeds are plain public HTTP; enable only if an agency rate-limits by IP

Mobility Database IDs are resolved against the CC0 catalog CSV automatically; direct URLs skip the catalog.

Output

One dataset item per normalized record, plus these fields on every item:

  • _feed { sourceId, url, dataType }
  • _license, _licenseUrl, _attribution — the source feed's license and provider (always propagate these downstream)
  • _mode, _fetchedAt

Feeds skipped by the license filter emit a { _skipped: true, reason: "license-not-open", … } marker instead of content. Fetch/decode failures emit { _error: true, stage, … } (stage = fetch / decode / emit — where it broke). A feed reached and decoded but carrying no entities emits an un-charged { _empty: true, … } marker so an idle feed is recorded rather than silently dropped. Transient fetch failures are retried with backoff before an _error is emitted (see fetchRetries).

Pricing (pay-per-event)

Charges one record-returned event per normalized record pushed. Skipped/errored feeds are not charged. Honors the platform per-run charge limit (eventChargeLimitReached) and stops cleanly.


Data source & licensing — READ THIS

This Actor sits on top of the Mobility Database and public agency feeds. The compliance posture is captured in full in ./COMPLIANCE.md. Summary:

  • Catalog metadata is CC0. "All metadata generated by MobilityData is licensed under CC0 1.0 Universal." So resolving feed IDs, URLs, provider, and location from the catalog is unrestricted.
  • Feed content is each agency's license, and the consumer is responsible. Per the Mobility Database Terms: "Content within the feeds is licensed by their respective data owners" and "API users are solely responsible for ensuring compliance with the licensing requirements for each feed they access." MobilityData grants no rights to the underlying schedules/positions.
  • Therefore this Actor filters to verifiably-open feeds only. With openLicensesOnly = true (the default), a feed is decoded/redistributed only if its catalog license matches a standard open license (CC0 / CC-BY / ODC-BY / public-domain) or it is on the built-in verified-open allowlist (feeds hand-confirmed open out-of-band, e.g. MBTA — the Mobility Database carries no license metadata for real-time feeds).
  • Reality of the open universe: in the current US catalog, ~85 % of static feeds declare no license and only ~0.5–0.9 % carry a standard open license. This Actor is intentionally scoped to the open subset, not "every transit feed." Turning openLicensesOnly off shifts per-feed license compliance onto you.
  • Attribution: every emitted record carries _license / _licenseUrl / _attribution. Open licenses (notably CC-BY / ODC-BY and MBTA) require attribution on downstream use — keep these fields.

The GTFS-Realtime format decoder derives from the google/transit spec (Apache-2.0); decoding the format is unrestricted — the constraint is on the feed data, handled by the license filter above.

Docs

  • ./docs/SCOPE.md — what the Actor is and honestly is not (curated open-feed sizing).
  • ./docs/PRICING.md — pay-per-event model (concrete price values owner-gated).
  • ./docs/LISTING.md — Apify Store copy draft.
  • ./COMPLIANCE.md — the load-bearing license gate.

Local development

npm install
npm run smoke # one request to the MBTA open feed; proves license filter + protobuf decode
apify run # full Actor run (needs an input.json / Apify CLI)