Mobilités M (Grenoble) API
Free Grenoble public transport API with no key: tram and bus routes, stops, live arrivals and journey planning on an OpenTripPlanner backend. Tested example included.
Endpoint tested and returned HTTP 200 on 2026-08-21
What is the Mobilités M (Grenoble) API?
Mobilités M publishes a free, key-free API for public transport in the Grenoble metropolitan area. Built on OpenTripPlanner, it serves tram and bus routes with their official colours, stop lists, live arrival times and full journey planning.
Because the backend is OpenTripPlanner, the routes, stops and planning endpoints follow OTP's own conventions rather than a bespoke design — which is a real advantage if you have worked with OTP before, since the response shapes and the `agency:id` identifier format will already be familiar. `SEM:A` is the tram A operated by SEM; the prefix is the agency and the suffix the route.
Two identifiers appear side by side and they are not interchangeable. `id` is the OTP internal identifier and `gtfsId` is the one used in the published GTFS feed, so joining live API data to a downloaded timetable means matching on `gtfsId`. The `color` and `textColor` pair arrives without a leading hash, unlike several other operators in this directory, so prepend one before using them as CSS. The `pdfTimeSheet` and `pdfMap` booleans indicate whether printable material exists for a route.
Quick facts
- Base URL
https://data.mobilites-m.fr/api- Authentication
- No API key or account. Open data published by the Grenoble-Alpes Métropole mobility authority.
- Rate limit
- No published quota. Route and stop data change only with timetable revisions; cache them rather than re-fetching.
- Pricing
- Free.
- CORS
- Enabled — callable directly from browser JavaScript
- Official docs
- Read the docs
How to use the Mobilités M (Grenoble) 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. List every tram and bus route in the Grenoble network
GET https://data.mobilites-m.fr/api/routers/default/index/routes
curl 'https://data.mobilites-m.fr/api/routers/default/index/routes'const res = await fetch("https://data.mobilites-m.fr/api/routers/default/index/routes");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);import requests
res = requests.get("https://data.mobilites-m.fr/api/routers/default/index/routes", timeout=20)
res.raise_for_status()
print(res.json())[
{
"id": "SEM:A",
"gtfsId": "SEM:91",
"shortName": "A",
"longName": "Fontaine La Poya / Le Pont-de-Claix L'Étoile",
"color": "3376B8",
"textColor": "FFFFFF",
"mode": "TRAM",
"type": "TRAM",
"timeSheet": true,
"pdfTimeSheet": true,
"pdfMap": true
},
{
"id": "SEM:B",
"gtfsId": "SEM:92",
"shortName": "B",
"longName": "Grenoble Oxford / Gières Plaine des Sports",
"color": "479A45",
"textColor": "FFFFFF",
"mode": "TRAM",
"type": "TRAM",
"timeSheet": true,
"pdfTimeSheet": true,
"pdfMap": true
},
{
"id": "SEM:C",
"gtfsId": "SEM:93",
"shortName": "C",
"longName": "Seyssins Le Prisme / Saint-Martin-d'Hères Université – Condillac",
"color": "C20078",
"textColor": "FFFFFF",
"mode": "TRAM",
"type": "TRAM",
"timeSheet": true,
"pdfTimeSheet": true,
"pdfMap": true
},
{
"id": "SEM:D",
"gtfsId": "SEM:94",
"shortName": "D",
"longName": "Grenoble Gares / Saint-Martin-d'Hères Étienne Grappe",
"color": "DE9917",
"textColor": "FFFFFF",
"mode": "TRAM",
"type": "TRAM",
"timeSheet": true,
"pdfTimeSheet": true,
"pdfMap": true
},
{
"id": "SEM:E",
"gtfsId": "SEM:95",
"shortName": "E",
"longName": "Fontanil-Cornillon Palluel / Grenoble Louise Michel",
"color": "533786",
"textColor": "FFFFFF",
"mode": "TRAM",
"type": "TRAM",
"timeSheet": true,
"pdfTimeSheet": true,
"pdfMap": true
},
{
"id": "SEM:NAVA",
"gtfsId": "SEM:27",
"shortName": "NAVA",
"longNParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
(routes) | path | Optional | `/routers/default/index/routes` lists every route in the network. routes |
(one route) | path | Optional | `/routers/default/index/routes/{id}` returns a single route. SEM:A |
(stops for route) | path | Optional | `/routers/default/index/routes/{id}/stops` lists the stops a route serves. stops |
(stop times) | path | Optional | `/routers/default/index/stops/{id}/stoptimes` returns upcoming departures at a stop. |
(journey planning) | path | Optional | `/routers/default/plan?fromPlace=&toPlace=` plans a trip using OTP's planner. |
Response fields
idstring- OpenTripPlanner identifier in `agency:route` form, such as "SEM:A".
gtfsIdstring- The identifier used in the published GTFS feed. Different from `id` — this is the one to join on.
shortName / longNamestring- The label shown on the vehicle and the full description with both termini.
color / textColorstring- Official hex colours without a leading hash. Prepend `#` before using them in CSS.
mode / typestring- `TRAM`, `BUS` and so on. Both fields carry the same value in this feed.
timeSheet / pdfTimeSheet / pdfMapboolean- Whether a timetable and printable route material exist for the route.
What you can build with the Mobilités M (Grenoble) API
- Build a Grenoble route browser with official line colours
- Show live departures at a tram or bus stop
- Plan journeys across the Grenoble metropolitan network
- Join live API data to the published GTFS feed via gtfsId
- List every stop on a tram line for a route diagram
Common errors and how to fix them
Colours render as default styling
`color` has no leading hash.
Fix: Prepend `#` before applying it as CSS. Several operators include the hash and this one does not, so do not assume.
A join against GTFS finds nothing
You matched on `id` rather than `gtfsId`.
Fix: OTP's internal id and the GTFS id are different values. Use `gtfsId` whenever the other side of the join is the published feed.
404 on a route id
The identifier needs its agency prefix.
Fix: Routes are addressed as `SEM:A`, not `A`. URL-encode the colon if your client does not.
Empty stop times
Nothing is due within OTP's forward window.
Fix: The window is short by design. Use the schedule endpoints for planned times outside it, and expect nothing overnight.
Mobilités M (Grenoble) API — frequently asked questions
Is the Grenoble transport API free?
Yes, free with no key or account. It is open data published by the Grenoble-Alpes Métropole mobility authority.
What backend does it run on?
OpenTripPlanner, which is why the paths and response shapes follow OTP conventions. If you have integrated OTP elsewhere, most of what you know transfers directly.
What is the difference between id and gtfsId?
`id` is OpenTripPlanner's internal identifier and `gtfsId` is the one in the published GTFS feed. They look similar but are not the same, and joining on the wrong one silently returns nothing.
Can it plan journeys, not just list routes?
Yes. The `/routers/default/plan` endpoint is OTP's journey planner, taking origin and destination coordinates or stop ids and returning itineraries with legs and times.
Tools that pair with this API
JSON Formatter
Format, beautify and minify JSON online with 2-space, 4-space or tab indentation. Sort keys alphabetically and catch syntax errors instantly — free and private.
JSON to CSV Converter
Convert a JSON array of objects to CSV online. Automatic column headers from the union of all keys, delimiter choice and proper quoting — all in-browser.
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.
Mobilités M (Grenoble) 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.