Transport for Ottawa, Canada

Transportation API · OC Transpo · Ottawa transit · Next bus arrivals

TL;DR

OC Transpo, Ottawa's public transit authority, provides a free API for next bus arrival predictions. Query by stop number to get real-time bus departure times, route numbers, and destination information for Ottawa's bus network and O-Train light rail. Perfect for building Ottawa transit apps, digital signage, and commuter tools. No API key required for the public endpoints.

Quick start: http://www.octranspo.com/index.php/developers

No API key needed — free Ottawa transit data!

How to Use This API

1. Get Next Bus for a Stop

Returns next bus predictions for a specific OC Transpo stop number:

http://api.octranspo1.com/v1.2/GetNextTripsForStop?stopNo=3000

2. Get Stop Information

http://api.octranspo1.com/v1.2/GetStopInfo?stopNo=3000

3. Search Routes

http://api.octranspo1.com/v1.2/GetRouteSummary?routeNo=95

4. JavaScript — Display Next Buses

const stopNo = 3000; // Rideau Centre
fetch(`http://api.octranspo1.com/v1.2/GetNextTripsForStop?stopNo=${stopNo}`)
  .then(r => r.text())
  .then(xml => {
    const parser = new DOMParser();
    const doc = parser.parseFromString(xml, 'text/xml');
    const trips = doc.querySelectorAll('Trip');
    trips.forEach(trip => {
      const route = trip.querySelector('RouteNo')?.textContent;
      const dest = trip.querySelector('Destination')?.textContent;
      const time = trip.querySelector('AdjustedScheduleTime')?.textContent;
      console.log(`Route ${route} to ${dest} — ${time} min`);
    });
  });

5. Python — Multiple Stops

import requests, xml.etree.ElementTree as ET

stops = [3000, 3010, 3020, 3050]  # Downtown Ottawa
for stop in stops:
    resp = requests.get(
        'http://api.octranspo1.com/v1.2/GetNextTripsForStop',
        params={'stopNo': stop}
    )
    root = ET.fromstring(resp.text)
    stop_name = root.find('.//StopLabel')
    print(f"\nStop {stop} ({stop_name.text if stop_name is not None else 'N/A'}):")
    for trip in root.findall('.//Trip')[:3]:
        route = trip.find('RouteNo')
        dest = trip.find('Destination')
        time = trip.find('AdjustedScheduleTime')
        print(f"  Route {route.text} → {dest.text}: {time.text} min")
Stop 3000 arrivals: http://api.octranspo1.com/v1.2/GetNextTripsForStop?stopNo=3000

Frequently Asked Questions

How do I find a stop number?
Stop numbers are posted on OC Transpo bus stop signs (4-digit numbers). You can also use the GetStopInfo endpoint with a partial stop description, or check the OC Transpo website for stop numbers near a location.
What format does the API return?
The OC Transpo API returns XML by default. You'll need to parse it with DOMParser (browser) or xml.etree.ElementTree (Python) or similar XML parsing tools.
Does it cover O-Train light rail?
Yes — O-Train Line 1 (Confederation Line) and Line 2 (Trillium Line) stations are included in the API. Use the station's stop number to get train arrival predictions.
How often are predictions updated?
Bus predictions update every 60-90 seconds based on GPS tracking. O-Train predictions update based on the train control system. Accuracy depends on real-time conditions.
What data is returned for each trip?
Each trip includes RouteNo, Destination, AdjustedScheduleTime (minutes until arrival), GPSTime, BusType, and Latitude/Longitude when available.
Is there a rate limit on the API?
OC Transpo requests that developers limit requests to reasonable levels and cache results where possible. The API is intended for real-time display rather than bulk data collection.

API Details

API URL
http://api.octranspo1.com/v1.2/
Documentation
octranspo.com/developers
Category
Transportation
Authentication
Not Required
Geographic Coverage
Ottawa, Ontario, Canada — National Capital Region

What You Can Build