API Metro Bilbao

API para consultar y descargar recursos abiertos (datasets) de Metro Bilbao. A continuación se describen los endpoints disponibles, sus parámetros y ejemplos de uso.

Servidores

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

Catálogo de datasets

GET/get/open_data/{lang}Devuelve el catálogo con datasets y enlaces de descarga

Parámetros

NombreInTipoReq.Descripción
langpathstringCódigo de idioma. Valores: es | eu | en

Respuesta (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 .

Endpoints de descarga

Descargan ficheros. No admiten paginación.

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

Parámetros

NombreInTipoReq.Descripción
langpathstringes | eu | en

cURL

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

Parámetros

NombreInTipoReq.Descripción
langpathstringes | eu | en

Cabeceras CSV:_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}Estaciones(CSV)

Cabeceras CSV: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}Noticias(CSV)

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

GETget/open_data/notas_prensa/{lang}Notas de prensa (CSV)

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

GET/get/open_data/avisos/{lang}Avisos (CSV)

Cabeceras CSV:id,title_{lang},type,station_id,is_published,created_at,publish_start_date,publish_end_date,is_in_issues_bar,finished_at

Endpoints JSON de previsualización

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

Parámetros

NombreInTipoReq.Descripción
langpathstringes | eu | en
limitquerynumberNo1–500 (def. 50)
offsetquerynumberNo>= 0 (def. 0)

Ejemplo de respuesta

{
  "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}Estaciones (JSON)

Parámetros

NombreInTipoReq.Descripción
langpathstringes | 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}Noticias (JSON)

Parámetros

NombreInTipoReq.Descripción
langpathstringes | eu | en
limitquerynumberNodef. 20
offsetquerynumberNodef. 0
GET/get/open_data/json/notas_prensa/{lang}Notas de prensa (JSON)

Parámetros

NombreInTipoReq.Descripción
langpathstringes | eu | en
limitquerynumberNodef. 1000
offsetquerynumberNodef. 0

Respuesta igual a Noticias, con campo extra categoria.

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

Parámetros

NombreInTipoReq.Descripción
langpathstringes | eu | en
limitquerynumberNodef. 1000
offsetquerynumberNodef. 0

Ejemplo de respuesta

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