A Ruby gem for accessing the Chicago Transit Authority (CTA) API. Track real-time bus and train locations, get arrival predictions, and check service alerts.
Add to your Gemfile:
gem "cta-api"Or install directly:
gem install cta-api
API keys are required for Bus Tracker and Train Tracker. Get yours at:
- Bus Tracker: https://www.transitchicago.com/developers/bustracker.aspx
- Train Tracker: https://www.transitchicago.com/developers/traintracker.aspx
- Customer Alerts: No key required
You can pass keys directly or set environment variables:
export CTA_BUS_TRACKER_API_KEY="your_bus_key"
export CTA_TRAIN_TRACKER_API_KEY="your_train_key"Uses CTA Bus Tracker API v3 with JSON responses.
require "cta-api"
client = CTA::BusTracker.new(api_key: "your_key")
# Or, if ENV["CTA_BUS_TRACKER_API_KEY"] is set:
client = CTA::BusTracker.new
# List all routes
client.routes
# => {"50"=>"Damen", "8"=>"Halsted", ...}
# Get directions for a route
client.directions(rt: "50")
# => [:northbound, :southbound]
# List stops for a route and direction
client.stops(rt: "50", dir: :north)
# Get real-time vehicle locations
client.vehicles(rt: "50")
client.vehicles(vid: ["1782", "1419"])
# Get arrival predictions
client.predictions(stpid: "8923", rt: "50")
client.predictions(vid: ["1782", "1419"])
# Get route patterns
client.patterns(pid: "5431")
client.patterns(rt: "50")
# Get active detours
client.detours(rt: "50")
client.detours(rt: "50", rtdir: "Northbound")
# Get supported locales
client.locales
# Get system time
client.timeclient = CTA::TrainTracker.new(api_key: "your_key")
# Get arrival predictions
client.arrivals(stpid: "30106")
client.arrivals(mapid: "40360")
client.arrivals(stpid: "30106", max: 5)
# Get train positions by route
client.positions(rt: "brn")
client.positions(rt: ["brn", "red"])
# Follow a specific train run
client.follow(runnumber: "421")client = CTA::CustomerAlerts.new # No API key needed
# Get route status
client.routes(routeid: "red")
client.routes(routeid: "red,blue")
client.routes(stationid: "40830")
# Get service alerts
client.alerts
client.alerts(activeonly: true)
client.alerts(accessibility: true)
client.alerts(planned: true)Responses are CTA::API::Response objects — a thin Hash subclass that also
supports dot-notation at the top level (result.rt, result.vid). Nested
objects stay as plain Hashes, and fields whose names collide with existing
Hash methods (size, count, keys, length, etc.) are only reachable via
[]:
result["size"] # works
result.size # returns the Hash size, not the CTA fieldAll errors inherit from CTA::API::Error:
ConfigurationError— missing API key at initializationApiError— CTA API returned an error, or HTTP non-2xx response. Has acodeattribute (integer HTTP status, string CTA error code, or nil)Error— network timeout, connection failure, or non-JSON body
begin
client.routes
rescue CTA::API::ConfigurationError => e
puts e.message # => "BusTracker API key is required"
rescue CTA::API::ApiError => e
puts e.message # => "CTA API Error: No data found for parameter"
puts e.code # => nil, "101", or 500 (depends on error source)
rescue CTA::API::Error => e
puts e.message # => "CTA API request timed out after 10s"
end- Ruby >= 3.1 required (was 2.7)
- API errors raise exceptions instead of printing to stdout
- HTTPS by default for all endpoints
Array.wrapmonkey-patch removedhashiedependency removed — responses useCTA::API::Response(same hash/dot-notation access)- HTTParty replaced with Faraday — single runtime dependency; responses parsed as JSON
- Bus Tracker API upgraded from v1 to v3 — new base URL, JSON responses. JSON response keys differ from the old XML shape for
routes,directions,stops, anddetours. v3 directions return structured objects withid/namefields, but thedirectionsmethod still returns symbols (:northbound, etc.), so the public API is unchanged. - All APIs now use JSON — XML parsing removed entirely
- Empty results return
[]instead ofnil - Bundled CSV data removed —
CTA::TrainTracker#stops,#stations,CTA::CustomerAlerts.train_routes, andCTA::CustomerAlerts.bus_routesare gone. For static stop/station/route data, use the CTA's GTFS feed directly. - Removed class-method API —
CTA::BusTracker.key=/CTA::BusTracker.routesand equivalent class methods onTrainTrackerandCustomerAlertsare gone. Use instance-based clients instead. - Removed
bulletins— usedetoursinstead. Thegetservicebulletinsendpoint is not documented in Bus Tracker API v3.
- Bus Tracker:
locales,detours - Train Tracker:
positions,follow
git clone https://github.com/mjrossi/cta-api.git
cd cta-api
bundle install
bundle exec rake # runs rubocop + rspec
bundle exec rspec # tests only
bundle exec rubocop # lint onlyMIT License. See LICENSE for details.