API to query and download Metro Bilbao open resources (datasets). The available endpoints, their parameters and usage examples are described below.
https://cms.metrobilbao.eus/es/get/open_data/{lang}Returns the catalog with datasets and download links| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | Language code. Values: es | eu | en |
{
"horarios": {
"id": "0",
"titulo": "horarios",
"descripcion": "Horario de... GTFS",
"ultima_actualizacion": "1674142500",
"creado": "1666340400",
"descarga": "/get/open_data/horarios/es",
"archivo": "zip"
},
"tarifas": { ... },
"estaciones": { ... },
"noticias": { ... },
"notas_prensa": { ... },
"avisos": { ... },
"memoria_anual": { ... },
"memoria_anual_2": { ... }
}curl -s https://cms.metrobilbao.eusget/open_data/es | jq .Download files. Pagination is not supported.
/get/open_data/horarios/{lang}GTFS (google_transit.zip)| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | es | eu | en |
curl -OJ "https://cms.metrobilbao.eusget/open_data/horarios/es"/get/open_data/tickets/{lang}Rates (CSV)| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | es | eu | en |
CSV headers:_id,ticket_id,code,areas,price,age,periodicity,large_family,minimum_balance,limit_travel
curl -OJ "https://cms.metrobilbao.eusget/open_data/tickets/es"/get/open_data/estaciones/{lang}Stations(CSV)CSV headers:stop_id,stop_name,stop_lat,stop_lon,location_type,parent_station
curl -OJ "https://cms.metrobilbao.eusget/open_data/estaciones/eu"/get/open_data/noticias/{lang}News(CSV)CSV headers:title,destacada,publish_date,created,changed
get/open_data/notas_prensa/{lang}Press releases (CSV)CSV headers:title,categoria,publish_date,created,changed
/get/open_data/avisos/{lang}Warnings (CSV)CSV headers:id,title_{lang},type,station_id,is_published,created_at,publish_start_date,publish_end_date,is_in_issues_bar,finished_at
/get/open_data/json/tarifas/{lang}Rates (JSON)| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | es | eu | en |
limit | query | number | No | 1–500 (def. 50) |
offset | query | number | No | >= 0 (def. 0) |
{
"data": [{
"_id": 123,
"ticket_id": "BI50E",
"code": "BI50E",
"areas": 2,
"price": 1.35,
"age": 0,
"periodicity": 4,
"large_family": 1,
"minimum_balance": 0,
"limit_travel": 0,
"ticket_name": "Bidai 50 FN50"
}],
"meta": { "limit": 50, "offset": 0, "lang": "es", "count": "123" },
"dictionary": [ { "name": "code", "label": "code", "description": "…" } ]
}curl -s "https://cms.metrobilbao.eusget/open_data/json/tarifas/en?limit=100&offset=0" | jq ./get/open_data/json/estaciones/{lang}Stations (JSON)| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | es | eu | en |
limit | query | number | No | 1–500 (def. 50) |
offset | query | number | No | >= 0 (def. 0) |
sort | query | string | No | Ej.: stop_name,-stop_id |
fields | query | string | No | Subconjunto: stop_id,stop_name,stop_lat,stop_lon,location_type,parent_station,stop_code |
filter[...] | query | object | No | BBOX y operadores (eq,gt,gte,lt,lte,like) |
# Solo nombre y geo, orden por nombre
curl -s "https://cms.metrobilbao.eusget/open_data/json/estaciones/es?fields=stop_id,stop_name,stop_lat,stop_lon&sort=stop_name" | jq .
# Búsqueda por nombre (LIKE)
curl -s "https://cms.metrobilbao.eusget/open_data/json/estaciones/es?filter[stop_name][op]=like&filter[stop_name][value]=Deusto" | jq .
# Bounding box (Bilbao aprox.)
curl -s "https://cms.metrobilbao.eusget/open_data/json/estaciones/es?filter[bbox]=-3.03,43.23,-2.87,43.31&fields=stop_id,stop_name,stop_lat,stop_lon&sort=stop_name" | jq .Caché: public, max-age=60, stale-while-revalidate=120.
/get/open_data/json/noticias/{lang}News (JSON)| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | es | eu | en |
limit | query | number | No | def. 20 |
offset | query | number | No | def. 0 |
/get/open_data/json/notas_prensa/{lang}Press releases (JSON)| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | es | eu | en |
limit | query | number | No | def. 1000 |
offset | query | number | No | def. 0 |
Same response as News, with an extra field Category.
/get/open_data/json/avisos/{lang}Warnings (JSON)| Name | In | Type | Req. | Description |
|---|---|---|---|---|
lang | path | string | Yes | es | eu | en |
limit | query | number | No | def. 1000 |
offset | query | number | No | def. 0 |
{
"data": [
{ "id": 999, "title_es": "Corte temporal", "type": "incidencia", "station_id": 12,
"is_published": 1, "created_at": "2025-05-10 08:10:00",
"publish_start_date": "2025-05-10", "publish_end_date": "2025-05-11",
"is_in_issues_bar": 1, "finished_at": null }
],
"meta": { "count": 123, "limit": 1000, "offset": 0, "lang": "es" },
"dictionary": [ { "name": "id", "label": "ID", "description": "Identificador del aviso." } ]
}