Swiss Public Transport API
Free Swiss public transport API with no key: connections, departure boards and station search across trains, buses, trams and boats, with live delay data. Tested example included.
Endpoint tested and returned HTTP 200 on 2026-08-21
What is the Swiss Public Transport API?
The Swiss public transport API (transport.opendata.ch) is a free, key-free journey planner covering every train, bus, tram, funicular and boat in Switzerland. It returns connections between any two stops with departure and arrival times, platforms, changes and live delay prognosis.
Switzerland's public transport is famously integrated, and so is its data: one API covers SBB trains, regional buses, city trams, mountain funiculars and lake boats through a single search. You can plan a journey from a village bus stop to a major station without knowing which operators are involved.
Two things make this API notably pleasant to use. Station names work as free text — "Zurich" resolves without you needing to look up ID 8503000 first — which removes the lookup step most transport APIs force on you. And every leg carries a `prognosis` object holding live expected times alongside the scheduled ones, plus a `delay` field in minutes, so real-time status comes back in the same call as the timetable rather than from a second endpoint.
Quick facts
- Base URL
https://transport.opendata.ch/v1- Authentication
- No API key or account. It is a community-run wrapper over the official Swiss timetable data, not an SBB-operated service.
- Rate limit
- Roughly 1,000 requests per day per IP. Heavy users are directed to the official opentransportdata.swiss platform.
- Pricing
- Free.
- CORS
- Enabled — callable directly from browser JavaScript
- Official docs
- Read the docs
How to use the Swiss Public Transport API
Every request below was executed against the live API on 2026-08-21, and the response shown is the real body it returned — not an illustration.
1. Find the next connection from Zurich to Bern
GET https://transport.opendata.ch/v1/connections?from=Zurich&to=Bern&limit=1
curl 'https://transport.opendata.ch/v1/connections?from=Zurich&to=Bern&limit=1'const res = await fetch("https://transport.opendata.ch/v1/connections?from=Zurich&to=Bern&limit=1");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);import requests
res = requests.get("https://transport.opendata.ch/v1/connections?from=Zurich&to=Bern&limit=1", timeout=20)
res.raise_for_status()
print(res.json()){
"connections": [
{
"from": {
"station": {
"id": "8503000",
"name": "Zürich HB",
"score": null,
"coordinate": {
"type": "WGS84",
"x": 47.377847,
"y": 8.540502
},
"distance": null
},
"arrival": null,
"arrivalTimestamp": null,
"departure": "2026-08-21T09:32:00+0200",
"departureTimestamp": 1787297520,
"delay": 0,
"platform": "32",
"prognosis": {
"platform": null,
"arrival": null,
"departure": "2026-08-21T09:32:00+0200",
"capacity1st": null,
"capacity2nd": null
},
"realtimeAvailability": null,
"location": {
"id": "8503000",
"name": "Zürich HB",
"score": null,
"coordinate": {
"type": "WGS84",
"x": 47.377847,
"y": 8.540502
},
"distance": null
}
},
"to": {
"station": {
"id": "8507000",
"name": "Bern",
"score": null,
"coordinate": {
"type": "WGS84",
"x": 46.948823,
"y": 7.439123
},
"distance": null
},
"arrival": "2026-08-21T10:28:00+0200",
"arrivalTimestamp": 1787300880,
"departure": null,
"departureTimestamp": null,
"delay": null,
"platform": "8",
"prognosis": {
"platform": null,
"arrival": null,
"departure": null,Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
from | query | Required | Departure stop. Accepts a free-text station name or a stop id. Zurich |
to | query | Required | Destination stop, in the same format. Bern |
limit | query | Optional | How many connections to return, up to 16. 1 |
date / time | query | Optional | Departure date (`YYYY-MM-DD`) and time (`HH:MM`). Defaults to now. 2026-08-21 |
isArrivalTime | query | Optional | Set to 1 to treat `time` as a desired arrival rather than departure. 1 |
transportations | query | Optional | Restrict modes: `train`, `tram`, `ship`, `bus`, `cableway`. train |
Response fields
connections[].from / toobject- Origin and destination legs, each with the resolved `station` (id, name, coordinates), platform and timestamps.
departure / arrivalstring- Scheduled times as ISO 8601 with a Swiss timezone offset.
departureTimestampinteger- The same moment as Unix seconds, which is easier to compare than the offset string.
delayinteger- Live delay in minutes. Zero means on time; null means no real-time data is available for that leg.
prognosisobject- Live expected platform and times, which override the scheduled values when they differ.
platformstring- Departure platform. Check `prognosis.platform` too — last-minute platform changes appear there first.
sectionsarray- The individual legs of a journey, including which service operates each and where changes occur.
What you can build with the Swiss Public Transport API
- Build a departure board for a Swiss station or office lobby
- Add journey planning to a Swiss travel or events app
- Alert commuters when their usual connection is delayed
- Calculate realistic travel times for scheduling and logistics
Common errors and how to fix them
Ambiguous station name
The free-text name matched several stops.
Fix: Use the `/locations?query=` endpoint to resolve a name to a specific stop id, then pass the id instead.
429
Daily request limit exceeded.
Fix: Cache timetable queries — scheduled times change only when the timetable does. For high volume, move to the official opentransportdata.swiss platform.
Empty connections array
No service runs between those stops at that time.
Fix: Late at night or on Sundays many routes do not operate. Widen the time window before assuming an error.
Swiss Public Transport API — frequently asked questions
Is the Swiss transport API free?
Yes, free with no API key, at roughly 1,000 requests per day per IP. It is a community-run wrapper over official Swiss timetable data; heavier users are pointed at the official opentransportdata.swiss platform.
Does it include live delays?
Yes. Every leg carries a `delay` field in minutes and a `prognosis` object with live expected times and platforms. That means real-time status arrives in the same response as the timetable, without a second call.
Do I need station IDs?
No, and that is one of its nicer properties — `from=Zurich` works directly. If a name is ambiguous, resolve it first through the `/locations` endpoint and pass the returned stop id instead.
What transport modes are covered?
All of them: SBB and regional trains, city trams, buses, funiculars, cable cars and lake boats, searchable together. The `transportations` parameter narrows to specific modes when you need it.
Tools that pair with this API
Time Zone Converter
Convert any date and time between world time zones. See UTC offsets, daylight saving handled automatically, and compare multiple zones at once.
Timestamp Converter
Convert timestamps to human-readable dates and dates back to timestamps. Auto-detects seconds vs milliseconds, shows local, UTC and ISO 8601 formats.
Time Duration Calculator
Add or subtract hours, minutes and seconds, or sum a list of durations into a total shown in h:m:s and in total seconds. Free and 100% in-browser.
Swiss Public Transport is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-21; always check the official documentation before relying on this API in production, as terms and limits can change.