Skip to content
API reference

Public transport

Find stops near a coordinate, resolve the lines that serve each stop, and read live arrivals, alerts, and bike availability.

GET /api/v1/public_transport_stops/nearby.json?latitude=40.7306&longitude=-73.9352&radius=1

Returns stops near a coordinate, ordered by distance, with details for their lines and live availability on bike stations.

Query parameters

Name Type Required Description
latitude number Yes Origin latitude.
longitude number Yes Origin longitude.
radius integer No Radius in miles. Defaults to 1.
limit integer No Maximum records. Defaults to 20.
transport_type string No Filter by subway, bus, citi_bike, railroad, or ferry.
city_uuids[] / city_names[] array No Filter by cities.

Example request

curl --get 'https://hoodsdk.com/api/v1/public_transport_stops/nearby.json?latitude=40.7306&longitude=-73.9352&radius=1'

Example response 200 OK

[
  {
    "id": 9,
    "name": "Greenpoint Av",
    "latitude": 40.7314,
    "longitude": -73.9544,
    "transport_type": "subway",
    "lines": ["G"],
    "wheelchair_boarding": 1,
    "lines_details": [{"id": 12, "public_id": "G", "name": "G", "color": "6CBE45", "text_color": "FFFFFF"}],
    "distance": 0.3
  },
  {
    "id": 4102,
    "name": "Manhattan Av & Greenpoint Av",
    "latitude": 40.7304,
    "longitude": -73.9541,
    "transport_type": "citi_bike",
    "lines": [],
    "lines_details": [],
    "distance": 0.35,
    "live": {
      "bike_availability": {
        "as_of": "2026-08-16T11:03:12.000-04:00",
        "bikes_available": 9,
        "bikes_disabled": 1,
        "docks_available": 12,
        "docks_disabled": 0,
        "scooters_available": 2,
        "scooters_unavailable": 0,
        "renting": true,
        "returning": true,
        "installed": true
      }
    }
  }
]
GET /api/v1/public_transport_stops/closest.json?latitude=40.7306&longitude=-73.9352

Returns a representative set of the closest stops across transport modes, deduplicated by line and sorted by distance.

Each mode is queried on its own and capped (20 subway, 20 bus, 3 Citi Bike, 20 railroad, 20 ferry) so a bus-dense block cannot drown the other modes. Subway, bus, and bike use radius. Railroad and ferry use their larger mode-specific radii. Nearby and closest return station pins, not N/S platforms. Citi Bike is included even when a station has no line IDs, and each bike station carries live.bike_availability. Arrivals and alerts are on the stop endpoint, not here. Missing or blank coordinates are 400.

Query parameters

Name Type Required Description
latitude number Yes Origin latitude.
longitude number Yes Origin longitude.
radius integer No Subway, bus, and bike radius in miles. Defaults to 1.
railroad_radius integer No Railroad radius. Defaults to radius + 3.
ferry_radius integer No Ferry radius. Defaults to radius + 3.
city_uuids[] / city_names[] array No Filter by cities.

Example request

curl --get 'https://hoodsdk.com/api/v1/public_transport_stops/closest.json?latitude=40.7306&longitude=-73.9352'

Example response 200 OK

[
  {
    "id": 9,
    "name": "Greenpoint Av",
    "latitude": 40.7314,
    "longitude": -73.9544,
    "transport_type": "subway",
    "lines": ["G"],
    "wheelchair_boarding": 1,
    "lines_details": [{"id": 12, "public_id": "G", "name": "G", "color": "6CBE45", "text_color": "FFFFFF"}],
    "distance": 0.3
  },
  {
    "id": 4102,
    "name": "Manhattan Av & Greenpoint Av",
    "latitude": 40.7304,
    "longitude": -73.9541,
    "transport_type": "citi_bike",
    "lines": [],
    "lines_details": [],
    "distance": 0.35,
    "live": {
      "bike_availability": {
        "as_of": "2026-08-16T11:03:12.000-04:00",
        "bikes_available": 9,
        "bikes_disabled": 1,
        "docks_available": 12,
        "docks_disabled": 0,
        "scooters_available": 2,
        "scooters_unavailable": 0,
        "renting": true,
        "returning": true,
        "installed": true
      }
    }
  }
]
GET /api/v1/public_transport_stops/9.json

Returns one stop with the stops you can transfer to, its accessibility, the service hours of every line that serves it, and its live arrivals, alerts, and elevator outages.

Service hours use GTFS clock times, so a train leaving at 1:47 the next morning reads 25:47. Headway is the average minutes between departures on the busiest direction of that kind of day. Live sections come from cache, so this endpoint never waits on the MTA: as_of is when the feed was last polled, and it is null with an empty items list before the first poll or during an upstream outage. minutes_away is computed for your request, and a train that has already left is left out. Alerts include planned work up to two weeks ahead — check active_now to tell a live disruption from an upcoming one. A Citi Bike station returns live.bike_availability instead of arrivals data.

Query parameters

Name Type Required Description
id integer Yes Stop ID, as returned by nearby, closest, or overview.

Example request

curl --get 'https://hoodsdk.com/api/v1/public_transport_stops/9.json'

Example response 200 OK

{
  "id": 9,
  "external_id": "G26",
  "transport_type": "subway",
  "name": "Greenpoint Av",
  "latitude": 40.7314,
  "longitude": -73.9544,
  "lines": ["G"],
  "wheelchair_boarding": 1,
  "stop_code": "G26",
  "parent_station": null,
  "location_type": 1,
  "lines_details": [
    {
      "id": 12,
      "public_id": "G",
      "name": "G",
      "color": "6CBE45",
      "text_color": "FFFFFF",
      "service_summary": {
        "weekday": {"first_departure": "05:03", "last_departure": "25:47", "trip_count": 232, "headway_minutes": 6}
      }
    }
  ],
  "transfers": [
    {"transfer_type": 2, "min_transfer_time": 180, "stop": {"id": 14, "external_id": "L10", "name": "Nassau Av"}}
  ],
  "live": {
    "arrivals": {
      "as_of": "2026-08-16T11:04:00.000-04:00",
      "items": [
        {"line_public_id": "G", "direction": "N", "trip_id": "064150_G..N", "arrival_at": "2026-08-16T11:08:30.000-04:00", "minutes_away": 4}
      ]
    },
    "alerts": {
      "as_of": "2026-08-16T11:00:00.000-04:00",
      "items": [
        {
          "id": "lmm:alert:123",
          "alert_type": "Delays",
          "header": "Northbound G trains are running with delays",
          "description": null,
          "url": null,
          "cause": null,
          "effect": null,
          "active_now": true,
          "line_public_ids": ["G"],
          "stop_external_ids": ["G26"],
          "active_period": {"start": "2026-08-16T10:41:00.000-04:00", "end": null},
          "updated_at": "2026-08-16T10:52:00.000-04:00"
        }
      ]
    },
    "elevator_outages": {
      "as_of": "2026-08-16T10:15:00.000-04:00",
      "items": [
        {
          "equipment_id": "EL234",
          "equipment_type": "EL",
          "serving": "Manhattan-bound platform to mezzanine",
          "reason": "Scheduled maintenance",
          "ada": true,
          "upcoming": false,
          "maintenance": true,
          "out_since": "2026-08-16T06:00:00.000-04:00",
          "estimated_return": "2026-08-16T17:00:00.000-04:00"
        }
      ]
    }
  }
}
GET /api/v1/public_transport_lines/12.json

Returns one line with its stops in order for each direction, a GeoJSON shape you can draw on a map, and the alerts currently affecting the route.

Follow the id in any stop's lines_details to get here. Stops are stations, not N/S platforms. The shape carries one linestring per direction. Both the shape and the stop order come from a representative trip, so they describe the line's typical run rather than any single scheduled trip. travel_time_seconds is the ride from the previous stop on that run, and is null on the first stop. live.alerts holds every cached alert naming this route, including ones scoped to particular stations — the stop endpoint returns the narrower per-station view.

Query parameters

Name Type Required Description
id integer Yes Line ID, as returned in lines_details.

Example request

curl --get 'https://hoodsdk.com/api/v1/public_transport_lines/12.json'

Example response 200 OK

{
  "id": 12,
  "public_id": "G",
  "transport_type": "subway",
  "name": "G",
  "color": "6CBE45",
  "text_color": "FFFFFF",
  "service_summary": {
    "weekday": {"first_departure": "05:03", "last_departure": "25:47", "last_arrival": "26:21", "trip_count": 232, "headway_minutes": 6},
    "saturday": {"first_departure": "05:31", "last_departure": "25:44", "last_arrival": "26:18", "trip_count": 180, "headway_minutes": 8}
  },
  "shape": {
    "type": "MultiLineString",
    "coordinates": [[[-73.9544, 40.7314], [-73.9505, 40.7371]]]
  },
  "live": {
    "alerts": {
      "as_of": "2026-08-16T11:00:00.000-04:00",
      "items": [
        {
          "id": "lmm:alert:123",
          "alert_type": "Delays",
          "header": "Northbound G trains are running with delays",
          "description": null,
          "url": null,
          "cause": null,
          "effect": null,
          "active_now": true,
          "line_public_ids": ["G"],
          "stop_external_ids": ["G26"],
          "active_period": {"start": "2026-08-16T10:41:00.000-04:00", "end": null},
          "updated_at": "2026-08-16T10:52:00.000-04:00"
        }
      ]
    }
  },
  "directions": [
    {
      "direction_id": 0,
      "stops": [
        {"stop_sequence": 1, "travel_time_seconds": null, "id": 9, "external_id": "G26", "name": "Greenpoint Av", "latitude": 40.7314, "longitude": -73.9544},
        {"stop_sequence": 2, "travel_time_seconds": 120, "id": 14, "external_id": "G28", "name": "Nassau Av", "latitude": 40.7245, "longitude": -73.9511}
      ]
    }
  ]
}