Ruter APIreise.ruter.no ↗
Search Oslo transit stops and get real-time bus, tram, and metro departures from Ruter's network via 3 endpoints covering NSR stop IDs, platforms, and alerts.
What is the Ruter API?
The Ruter (reise.ruter.no) API exposes 3 endpoints for accessing real-time public transit data across Oslo and the surrounding region. Use search_stop to find stops by name and retrieve their NSR stop place IDs, then pass those IDs to get_departures or get_bus_arrivals for live schedules including platform, line, destination, and real-time arrival times across buses, trams, and metro lines.
curl -X GET 'https://api.parse.bot/scraper/795ebd94-5170-4a6d-8562-c97f6d8f9c08/search_stop?query=Jernbanetorget&latitude=59.911&longitude=10.75' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace reise-ruter-no-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Ruter Bus Arrivals — search stops, get departures, get bus arrivals."""
from parse_apis.Ruter_Bus_Arrivals_API import Ruter, TransportMode, StopNotFound
client = Ruter()
# Search for stops matching a name — limit caps total items fetched.
for stop in client.stops.search(query="Jernbanetorget", limit=3):
print(stop.name, stop.id, stop.distance)
# Drill down into the first SearchStopPlace result's departures.
stop = client.stop(id="NSR:StopPlace:58366")
for dep in stop.departures.list(transport_mode=TransportMode.BUS, limit=3):
print(dep.line.line_number, dep.line.destination, dep.expected_time, dep.realtime_status)
# Get bus-only arrivals via the sub-resource.
for bus in stop.bus_arrivals.list(limit=3):
print(bus.bus_number, bus.bus_name, bus.destination, bus.expected_time)
# Typed error handling for a non-existent stop.
try:
bad_stop = client.stop(id="NSR:StopPlace:00000")
list(bad_stop.departures.list(limit=1))
except StopNotFound as exc:
print(f"Stop not found: {exc.stop_id}")
print("exercised: stops.search / stop.departures.list / stop.bus_arrivals.list / StopNotFound")
Full-text search over transit stops by name. Returns stop places with IDs, coordinates, transport modes, and fare zones. Each result carries a type discriminator (SearchStopPlace, Place, PointOfInterest_v2). Only SearchStopPlace entries include transport_modes and zone. The returned stop ID feeds get_departures and get_bus_arrivals.
| Param | Type | Description |
|---|---|---|
| queryrequired | string | Search query for stop name (e.g. 'Jernbanetorget', 'Majorstuen', 'Oslo S') |
| latitude | number | Latitude coordinate for distance-based sorting of results |
| longitude | number | Longitude coordinate for distance-based sorting of results |
{
"type": "object",
"fields": {
"stops": "array of stop objects with id, name, location, type, transport_modes, and zone info",
"total": "integer total number of stops returned"
},
"sample": {
"data": {
"stops": [
{
"id": "NSR:StopPlace:58366",
"name": "Jernbanetorget",
"type": "SearchStopPlace",
"zone": {
"id": "RUT:FareZone:4",
"name": "1"
},
"distance": 0.082,
"location": {
"latitude": 59.911898,
"longitude": 10.75038
},
"description": "Oslo",
"transport_modes": [
{
"mode": "Metro",
"sub_mode": null
},
{
"mode": "Tram",
"sub_mode": null
},
{
"mode": "Bus",
"sub_mode": null
}
]
}
],
"total": 7
},
"status": "success"
}
}About the Ruter API
Stop Search and Identification
The search_stop endpoint accepts a query string (e.g. 'Jernbanetorget' or 'Oslo S') and returns an array of stop objects, each containing an id (in NSR stop place format), name, location (latitude/longitude), type, transport_modes, and fare zone information. Passing optional latitude and longitude parameters sorts results by distance, which is useful when building location-aware apps. The total field tells you how many stops matched.
Departures Across All Modes
The get_departures endpoint takes an NSR stop_id and returns a full departure board for that stop. Results include a departures array where each entry carries platform, line, scheduled and real-time times, and realtime status. You can filter by transport_mode ('Bus', 'Tram', or 'Metro') and set a start_time in ISO 8601 format to retrieve future schedules. The response also includes a top-level alerts array for service disruptions and a transport_modes array showing which modes operate at that stop.
Bus-Specific Arrivals
The get_bus_arrivals endpoint is scoped to bus departures only and accepts either a stop_id or a stop_name — if you provide a name, it auto-resolves to the correct stop. Each entry in bus_arrivals includes bus_number, destination, platform, scheduled and real-time times, and realtime_status. The response also returns stop_name and location coordinates so you don't need a separate lookup. Like get_departures, it accepts an optional start_time for forward-looking queries.
The Ruter API is a managed, monitored endpoint for reise.ruter.no — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when reise.ruter.no changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official reise.ruter.no API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Display a live departure board for any Oslo bus stop using real-time times from
get_bus_arrivals. - Build a transit app that auto-completes stop names and resolves NSR stop IDs via
search_stop. - Filter
get_departuresbytransport_mode: 'Metro'to show only T-bane lines at a given stop. - Surface active service alerts from the
alertsfield inget_departuresbefore showing a departure list. - Sort nearby stops by distance by passing user GPS coordinates to
search_stopaslatitudeandlongitude. - Check future schedules for any stop by setting
start_timeto a specific ISO 8601 datetime. - Show fare zone information alongside stop results to help users estimate trip costs.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Ruter have an official developer API?+
What does `get_departures` return that `get_bus_arrivals` does not?+
get_departures covers all transport modes — Bus, Tram, and Metro — and includes a top-level alerts array for service disruptions and a transport_modes list for the stop. get_bus_arrivals is scoped to buses only but adds convenience by accepting a stop_name string and auto-resolving it to an NSR stop ID without a separate search_stop call.How far ahead do departure results reach?+
start_time (defaulting to now) and covers upcoming scheduled services from Ruter's network. There is no documented upper time window exposed in the response schema, so very distant future queries may return fewer or no results depending on how far Ruter's timetable data extends.