Metro Bilbao API

API to query and download Metro Bilbao open resources (datasets). The available endpoints, their parameters and usage examples are described below.

Servers

Base URLhttps://cms.metrobilbao.eus/es

Dataset catalog

GET/get/open_data/{lang}Returns the catalog with datasets and download links

Parameters

NameInTypeReq.Description
langpathstringYesLanguage code. Values: es | eu | en

Response (200)

{
  "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

curl -s https://cms.metrobilbao.eusget/open_data/es | jq .

Download endpoints

Download files. Pagination is not supported.

GET/get/open_data/horarios/{lang}GTFS (google_transit.zip)

Parameters

NameInTypeReq.Description
langpathstringYeses | eu | en

cURL

curl -OJ "https://cms.metrobilbao.eusget/open_data/horarios/es"
GET/get/open_data/tickets/{lang}Rates (CSV)

Parameters

NameInTypeReq.Description
langpathstringYeses | 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/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/get/open_data/noticias/{lang}News(CSV)

CSV headers:title,destacada,publish_date,created,changed

GETget/open_data/notas_prensa/{lang}Press releases (CSV)

CSV headers:title,categoria,publish_date,created,changed

GET/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

JSON preview endpoints

GET/get/open_data/json/tarifas/{lang}Rates (JSON)

Parameters

NameInTypeReq.Description
langpathstringYeses | eu | en
limitquerynumberNo1–500 (def. 50)
offsetquerynumberNo>= 0 (def. 0)

Example response

{
  "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

curl -s "https://cms.metrobilbao.eusget/open_data/json/tarifas/en?limit=100&offset=0" | jq .
GET/get/open_data/json/estaciones/{lang}Stations (JSON)

Parameters

NameInTypeReq.Description
langpathstringYeses | eu | en
limitquerynumberNo1–500 (def. 50)
offsetquerynumberNo>= 0 (def. 0)
sortquerystringNoEj.: stop_name,-stop_id
fieldsquerystringNoSubconjunto: stop_id,stop_name,stop_lat,stop_lon,location_type,parent_station,stop_code
filter[...]queryobjectNoBBOX 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/get/open_data/json/noticias/{lang}News (JSON)

Parameters

NameInTypeReq.Description
langpathstringYeses | eu | en
limitquerynumberNodef. 20
offsetquerynumberNodef. 0
GET/get/open_data/json/notas_prensa/{lang}Press releases (JSON)

Parameters

NameInTypeReq.Description
langpathstringYeses | eu | en
limitquerynumberNodef. 1000
offsetquerynumberNodef. 0

Same response as News, with an extra field Category.

GET/get/open_data/json/avisos/{lang}Warnings (JSON)

Parameters

NameInTypeReq.Description
langpathstringYeses | eu | en
limitquerynumberNodef. 1000
offsetquerynumberNodef. 0

Example response

{
  "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." } ]
}