MetroHero API Reference

Welcome to MetroHero's public API documentation! Here you can browse the APIs we currently offer. To start using our APIs, you'll need to request a unique API key from us. Please email us at contact@dcmetrohero.com to get started.

All of our public APIs are available for free. In return, we require the following:

  • You must abide by WMATA's Transit Data Terms of Use; by using our APIs, you agree to these terms of service.
  • Any data returned by or derived from data returned by our APIs must be freely available to all users of your application. Any paywalled application that utilizes our APIs must also provide a free tier with access to the same data returned by or derived from our APIs.
  • Any data returned by or derived from data returned by our APIs must be prominently credited back to MetroHero. For example, if this data is being displayed to users on a website or in an application, MetroHero must always be visually credited wherever and whenever the data appears or is used.

We reserve the right to revoke API access for anyone who does not abide by the above stipulatons. In fact, we reserve the right to revoke API access for any reason at any time, and cannot make any guarantees about the availability of our APIs nor the validity of the data returned by our APIs. For more information, see WMATA's Transit Data Terms of Use; consider our SLA (service level agreement) the same as theirs.

By default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours. These restrictions are similar to the rate limits WMATA currently has in place for their APIs, and are subject to change in the future. If you anticipate multiple users of your application, we suggest you create your own central server as a proxy to our APIs, polling and caching our data periodically to ensure you stay below our rate limits. You can then have your clients make requests to your central server rather than our servers directly, which gives you total control over how frequently calls are made to our APIs. If you still require a higher rate limit, please email us at contact@dcmetrohero.com.

Per WMATA's Transit Data Terms of Use, as of October 12th, 2017, basic user data (name, email address, API usage) may be shared with WMATA for statistical research purposes, and you may be blocked from accessing our APIs at any time, all upon WMATA's request.


WMATA is our primary upstream data provider, but does not otherwise endorse our services nor the use of our APIs. In the event that we, MetroHero, decide to stop providing our APIs permanently or temporarily, WMATA is under no obligation to provide similar APIs.

API Endpoint
https://dcmetrohero.com/api/v1
Terms of Service: https://developer.wmata.com/license
Contact: contact@dcmetrohero.com
Schemes: https
Version: v1

Metrorail

System Metrics

GET /metrorail/metrics

Gets real-time system-wide metrics, broken down by line and direction of travel. This includes everything from the number of trains and train cars to calculations like average minimum headways, train frequencies, platform wait times, and more. Data is updated about every 30 seconds.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
200 OK

System metrics successfully retrieved.

400 Bad Request

Invalid request. Make sure the required apiKey header is specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You specified a valid request, but our servers aren't yet ready to accept it. This can happen if our servers have restarted recently, or if there is otherwise a problem with our servers. Please try again soon. Alternatively, you may have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "lineMetricsByLine": {
    "RD": "object",
    "OR": {
      "lineCode": "OR",
      "expectedNumTrains": 22,
      "numTrains": 22,
      "numEightCarTrains": 11,
      "numDelayedTrains": 2,
      "numCars": 154,
      "averageTrainDelay": 120,
      "medianTrainDelay": 115,
      "minimumTrainDelay": 0,
      "maximumTrainDelay": 365,
      "averageMinimumHeadways": 6.12,
      "averageTrainFrequency": 6.12,
      "expectedTrainFrequency": 6,
      "averagePlatformWaitTime": 3.12,
      "expectedPlatformWaitTime": 3,
      "trainFrequencyStatus": "OK",
      "platformWaitTimeTrendStatus": "NEUTRAL",
      "averageHeadwayAdherence": 66.6,
      "averageScheduleAdherence": 66.6,
      "standardDeviationTrainFrequency": 1.9,
      "expectedStandardDeviationTrainFrequency": 1.8,
      "directionMetricsByDirection": {
        "1": {
          "lineCode": "OR",
          "directionNumber": 1,
          "direction": "Eastbound",
          "towardsStationName": "New Carrollton",
          "expectedNumTrains": 11,
          "numTrains": 11,
          "numEightCarTrains": 5,
          "numDelayedTrains": 1,
          "numCars": 76,
          "averageTrainDelay": 100,
          "medianTrainDelay": 95,
          "minimumTrainDelay": 0,
          "maximumTrainDelay": 365,
          "averageMinimumHeadways": 6.12,
          "averageTrainFrequency": 6.12,
          "expectedTrainFrequency": 6,
          "averagePlatformWaitTime": 3.12,
          "expectedPlatformWaitTime": 3,
          "trainFrequencyStatus": "OK",
          "platformWaitTimeTrendStatus": "NEUTRAL",
          "averageHeadwayAdherence": 66.6,
          "averageScheduleAdherence": 66.6,
          "standardDeviationTrainFrequency": 1.9,
          "expectedStandardDeviationTrainFrequency": 1.8,
          "date": "2017-06-12T08:24:26.655-04:00"
        },
        "2": "object"
      },
      "date": "2017-06-12T08:24:26.655-04:00"
    },
    "SV": "object",
    "BL": "object",
    "YL": "object",
    "GR": "object"
  },
  "date": "2017-06-12T08:24:26.655-04:00"
}

Trip Info

GET /metrorail/trips/{fromStationCode}/{toStationCode}

Gets real-time trip information given current conditions. The algorithms behind this API take, when available, both current conditions and conditions in the recent past into account--including any train delays and congestion--to make predictions about how long riders may be waiting or have been waiting for the next train to service the specified trip, as well as how long the trip might take once they're aboard. These predictions are recalculated about every 30 seconds.

Trips with station transfers are not directly supported. For example, to get trip information from Glenmont to Vienna, split the trip up into segments (e.g. Glenmont to Metro Center, then Metro Center to Vienna) and perform a separate request to this API for each segment. You can then aggregate the results across the responses of each API request however you see fit to make your own derived predictions about the trip as a whole.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
fromStationCode

The RTU station code of the origin station of the trip. For example, if you want to request trip info for the trip from Vienna (K08) to Metro Center (C01), you should specify K08 for this param. An unofficial list of valid Metrorail station codes can be found here. Only station codes for revenue stations are supported.

type
string
in
path
toStationCode

The RTU station code of the destination station of the trip. For example, if you want to request trip info for the trip from Vienna (K08) to Metro Center (C01), you should specify C01 for this param. An unofficial list of valid Metrorail station codes can be found here. Only station codes for revenue stations are supported.

type
string
in
path
200 OK

Trip info successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified. Also make sure the trip you specified doesn't require a transfer. If it does, refer to the description of this API to learn how to handle this case.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "fromStationName": "Vienna",
  "fromStationCode": "K08",
  "toStationName": "Metro Center",
  "toStationCode": "C01",
  "lineCodes": [
    "OR"
  ],
  "expectedRideTime": 26.12,
  "predictedRideTime": 30.3303,
  "timeUntilNextTrain": 2.02,
  "timeSinceLastTrain": 4.26,
  "date": "2017-06-12T08:24:26.655-04:00"
}

Train Positions

GET /metrorail/trains

Gets real-time train predictions for the entire Metrorail system. These predictions are unique per train, i.e. exactly one prediction is returned per train. This API is intended to be used as an alternative to WMATA's Train Positions API, but does not return the exact same data, nor is it in the same format. We calculate our train predictions independently of WMATA by observing train movement over time.

Train predictions are returned in no particular order.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header

Train predictions successfully retrieved.

400 Bad Request

Invalid request. Make sure the required apiKey header is specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
[
  {
    "trainId": "155",
    "Car": "8",
    "Destination": "Vienna",
    "DestinationCode": "K08",
    "DestinationName": "Vienna",
    "Group": "1",
    "Line": "Vienna",
    "LocationCode": "C01",
    "LocationName": "Metro Center",
    "Min": "1",
    "parentMin": "1",
    "minutesAway": 0.89,
    "maxMinutesAway": 1.12,
    "directionNumber": 1,
    "isScheduled": false,
    "numPositiveTags": 1,
    "numNegativeTags": 3,
    "trackNumber": 1,
    "PreviousStationCode": "D01",
    "previousStationName": "Federal Triangle",
    "secondsSinceLastMoved": 65,
    "isCurrentlyHoldingOrSlow": true,
    "secondsOffSchedule": 145,
    "trainSpeed": 23,
    "isNotOnRevenueTrack": false,
    "isKeyedDown": false,
    "wasKeyedDown": false,
    "distanceFromNextStation": 502,
    "observedDate": "Aug 11, 2017 3:51:54 PM"
  }
]

Train Reports

GET /metrorail/trains/tags

Gets real-time rider reports, referred to as tags, for all trains. All tags are of predefined types (e.g. 'New Train', 'Crowded', 'Smooth Ride', etc) submitted by MetroHero users. These tags expire anywhere from 15 to 60 minutes after they've been created, depending on the type of tag; only current, unexpired tags are returned by this API.

Train tags are ordered by tag type in descending order by current number of active tags.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
200 OK

Train tags successfully retrieved.

400 Bad Request

Invalid request. Make sure the required apiKey header is specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "253": "object",
  "012": {
    "numTagsByType": [
      {
        "BAD_OPERATOR": 1,
        "ISOLATED_CARS": 1,
        "NEW_TRAIN": 1,
        "BROKEN_INTERCOM": 0,
        "CROWDED": 0,
        "EMPTY": 0,
        "GOOD_OPERATOR": 0,
        "GOOD_RIDE": 0,
        "NEEDS_WORK": 0,
        "RECENTLY_OFFLOADED": 0,
        "UNCOMFORTABLE_RIDE": 0,
        "UNCOMFORTABLE_TEMPS": 0,
        "WRONG_DESTINATION": 0,
        "WRONG_NUM_CARS": 0
      }
    ],
    "numPositiveTags": 1,
    "numNegativeTags": 2
  }
}

Train Report

GET /metrorail/trains/{trainId}/tags

Gets real-time rider reports about a particular train, referred to as tags. All tags are of predefined types (e.g. 'New Train', 'Crowded', 'Smooth Ride', etc) submitted by MetroHero users. These tags expire anywhere from 15 to 60 minutes after they've been created, depending on the type of tag; only current, unexpired tags are returned by this API.

Train tags are ordered by tag type in descending order by current number of active tags.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
trainId

The AIMS internal ID of the train, as returned by WMATA's Train Positions API. This should be a three-digit string anywhere from 001 to 512.

type
string
in
path
200 OK

Train tags successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "numTagsByType": [
    {
      "BAD_OPERATOR": 1,
      "ISOLATED_CARS": 1,
      "NEW_TRAIN": 1,
      "BROKEN_INTERCOM": 0,
      "CROWDED": 0,
      "EMPTY": 0,
      "GOOD_OPERATOR": 0,
      "GOOD_RIDE": 0,
      "NEEDS_WORK": 0,
      "RECENTLY_OFFLOADED": 0,
      "UNCOMFORTABLE_RIDE": 0,
      "UNCOMFORTABLE_TEMPS": 0,
      "WRONG_DESTINATION": 0,
      "WRONG_NUM_CARS": 0
    }
  ],
  "numPositiveTags": 1,
  "numNegativeTags": 2
}

Train Predictions

GET /metrorail/stations/trains

Gets real-time and scheduled train predictions for all stations. For each station, this API returns all of the same data as WMATA's Real-Time Rail Predictions API, but with additional real-time train predictions (including, optionally, scheduled train predictions), and additional fields for those predictions, like estimated train speed and direction of travel. We calculate our train predictions independently of WMATA by observing train movement over time.

Disclaimer: None of the above should be interpretted as a claim that our data is more accurate, more complete, or more timely than WMATA's data, we are simply stating some of the factual differences between the two datasets; as with all our APIs, we make no claims as to the accuracy of the data returned.

Each set of train predictions for each station is in ascending order by minutesAway. When the request parameter includeScheduledPredictions is set to false, our data can be used as a drop-in substitute for WMATA's Real-Time Rail Predictions API.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
includeScheduledPredictions

True if you want predictions made using scheduled train data to be returned in addition to predictions made using real-time data, otherwise set to false and only predictions made using real-time data will be returned. The default is false if this isn't specified.

type
boolean
in
query
200 OK

Train predictions successfully retrieved.

400 Bad Request

Invalid request. Make sure the required apiKey header is specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "C01": [
    {
      "trainId": "155",
      "Car": "8",
      "Destination": "Vienna",
      "DestinationCode": "K08",
      "DestinationName": "Vienna",
      "Group": "1",
      "Line": "Vienna",
      "LocationCode": "C01",
      "LocationName": "Metro Center",
      "Min": "1",
      "parentMin": "1",
      "minutesAway": 0.89,
      "maxMinutesAway": 1.12,
      "directionNumber": 1,
      "isScheduled": false,
      "numPositiveTags": 1,
      "numNegativeTags": 3,
      "trackNumber": 1,
      "PreviousStationCode": "D01",
      "previousStationName": "Federal Triangle",
      "secondsSinceLastMoved": 65,
      "isCurrentlyHoldingOrSlow": true,
      "secondsOffSchedule": 145,
      "trainSpeed": 23,
      "isNotOnRevenueTrack": false,
      "isKeyedDown": false,
      "wasKeyedDown": false,
      "distanceFromNextStation": 502,
      "observedDate": "Aug 11, 2017 3:51:54 PM"
    }
  ]
}

Station Train Predictions

GET /metrorail/stations/{stationCode}/trains

Gets real-time and scheduled train predictions for a particular station. This API returns all of the same data as WMATA's Real-Time Rail Predictions API, but with additional real-time train predictions (including, optionally, scheduled train predictions), and additional fields for those predictions, like estimated train speed and direction of travel. We calculate our train predictions independently of WMATA by observing train movement over time.

Disclaimer: None of the above should be interpretted as a claim that our data is more accurate, more complete, or more timely than WMATA's data, we are simply stating some of the factual differences between the two datasets; as with all our APIs, we make no claims as to the accuracy of the data returned.

Train predictions are returned in ascending order by minutesAway. When the request parameter includeScheduledPredictions is set to false, our data can be used as a drop-in substitute for WMATA's Real-Time Rail Predictions API.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
stationCode

The RTU station code of the station. An unofficial list of valid Metrorail station codes can be found here. Only station codes for revenue stations are supported.

type
string
in
path
includeScheduledPredictions

True if you want predictions made using scheduled train data to be returned in addition to predictions made using real-time data, otherwise set to false and only predictions made using real-time data will be returned. The default is false if this isn't specified.

type
boolean
in
query

Train predictions successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
[
  {
    "trainId": "155",
    "Car": "8",
    "Destination": "Vienna",
    "DestinationCode": "K08",
    "DestinationName": "Vienna",
    "Group": "1",
    "Line": "Vienna",
    "LocationCode": "C01",
    "LocationName": "Metro Center",
    "Min": "1",
    "parentMin": "1",
    "minutesAway": 0.89,
    "maxMinutesAway": 1.12,
    "directionNumber": 1,
    "isScheduled": false,
    "numPositiveTags": 1,
    "numNegativeTags": 3,
    "trackNumber": 1,
    "PreviousStationCode": "D01",
    "previousStationName": "Federal Triangle",
    "secondsSinceLastMoved": 65,
    "isCurrentlyHoldingOrSlow": true,
    "secondsOffSchedule": 145,
    "trainSpeed": 23,
    "isNotOnRevenueTrack": false,
    "isKeyedDown": false,
    "wasKeyedDown": false,
    "distanceFromNextStation": 502,
    "observedDate": "Aug 11, 2017 3:51:54 PM"
  }
]

Station Reports

GET /metrorail/stations/tags

Gets real-time rider reports, referred to as tags, for all stations. All tags are of predefined types (e.g. 'Friendly or Helpful Staff', 'Broken Escalator', etc) and are either explicitly submitted by MetroHero users, or implicitly derived from public WMATA-related tweets on Twitter by our algorithms. These tags expire anywhere from 15 to 180 minutes after they've been created, depending on the type of tag; only current, unexpired tags are returned by this API.

Station tags are ordered by tag type in descending order by current number of active tags.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
200 OK

StationTags successfully retrieved.

400 Bad Request

Invalid request. Make sure the required apiKey header is specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "A02": {
    "numTagsByType": [
      {
        "FRIENDLY_OR_HELPFUL_STAFF": 1,
        "UNCOMFORTABLE_TEMPS": 1,
        "AMPLE_SECURITY": 0,
        "BROKEN_ELEVATOR": 0,
        "BROKEN_ESCALATOR": 0,
        "CROWDED": 0,
        "EMPTY": 0,
        "LONG_WAITING_TIME": 0,
        "NEEDS_WORK": 0,
        "POSTED_TIMES_INACCURATE": 0,
        "SMOKE_OR_FIRE": 0,
        "UNFRIENDLY_OR_UNHELPFUL_STAFF": 0
      }
    ],
    "numPositiveTags": 1,
    "numNegativeTags": 1
  },
  "C05": "object"
}

Station Report

GET /metrorail/stations/{stationCode}/tags

Gets real-time rider reports about a particular station, referred to as tags. All tags are of predefined types (e.g. 'Friendly or Helpful Staff', 'Broken Escalator', etc) and are either explicitly submitted by MetroHero users, or implicitly derived from public WMATA-related tweets on Twitter by our algorithms. These tags expire anywhere from 15 to 180 minutes after they've been created, depending on the type of tag; only current, unexpired tags are returned by this API.

Station tags are ordered by tag type in descending order by current number of active tags.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
stationCode

The RTU station code of the station. An unofficial list of valid Metrorail station codes can be found here. Only station codes for revenue stations are supported.

type
string
in
path
200 OK

Station tags successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "numTagsByType": [
    {
      "FRIENDLY_OR_HELPFUL_STAFF": 1,
      "UNCOMFORTABLE_TEMPS": 1,
      "AMPLE_SECURITY": 0,
      "BROKEN_ELEVATOR": 0,
      "BROKEN_ESCALATOR": 0,
      "CROWDED": 0,
      "EMPTY": 0,
      "LONG_WAITING_TIME": 0,
      "NEEDS_WORK": 0,
      "POSTED_TIMES_INACCURATE": 0,
      "SMOKE_OR_FIRE": 0,
      "UNFRIENDLY_OR_UNHELPFUL_STAFF": 0
    }
  ],
  "numPositiveTags": 1,
  "numNegativeTags": 1
}

Metrobus (BETA)

Route Metrics

GET /metrobus/routes/{routeId}/metrics

Gets real-time route metrics given current conditions. This includes data like headway and schedule deviation, and can be used to assess how well a particular route is performing. Data is updated no more frequently than every 2 seconds.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
routeId

The base bus route ID, as defined by the route IDs returned by WMATA's Bus Routes API, except we don't support variants, e.g. 10Av1 (use 10A instead).

type
string
in
path
200 OK

Route metrics successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "headwayDeviation": 460.12,
  "percentageAcceptableHeadways": 52.11,
  "averageScheduleDeviation": 2.53,
  "date": "2017-06-12T08:24:26.655-04:00"
}

Bus Positions

GET /metrobus/routes/{routeId}/buses

Gets real-time bus predictions for a particular route.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
routeId

The base bus route ID, as defined by the route IDs returned by WMATA's Bus Routes API, except we don't support variants, e.g. 10Av1 (use 10A instead).

type
string
in
path
200 OK

Bus predictions successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
[
  {
    "id": "6236",
    "latitude": 38.901482,
    "longitude": -77.032219,
    "destinationName": "LAFAYETTE SQUARE",
    "tripDirection": "WEST",
    "deviationFromSchedule": 2,
    "lastPositionUpdateString": "2017-08-22T13:36:22",
    "previousStopId": "1001191",
    "previousStopName": "I ST NW + 14TH ST NW",
    "nextStopId": "1001185",
    "nextStopName": "I ST NW + 15TH ST NW",
    "normalizedDistanceToNextStop": 0.952850788114076,
    "estimatedTimeToNextStop": 52,
    "estimatedDistanceFromPreviousStop": 11,
    "estimatedDistanceToNextStop": 213,
    "numStopsAway": 2,
    "scheduledArrival": "2017-08-22T13:45:30",
    "routeId": "X2",
    "timeToBusInFront": 373,
    "timeFromBusBehind": 674,
    "numPositiveTags": 1,
    "numNegativeTags": 0
  }
]

Bus Reports

GET /metrobus/buses/tags

Gets real-time rider reports, referred to as tags, for all buses. All tags are of predefined types (e.g. 'Good Operator', 'Disruptive Rider', 'Skipping Stops', etc) submitted by MetroHero users. These tags expire anywhere from 15 to 180 minutes after they've been created, depending on the type of tag; only current, unexpired tags are returned by this API.

Bus tags are ordered by tag type in descending order by current number of active tags.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
200 OK

Bus tags successfully retrieved.

400 Bad Request

Invalid request. Make sure the required apiKey header is specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "5401": {
    "numTagsByType": [
      {
        "BAD_OPERATOR": 1,
        "DISRUPTIVE_RIDER": 1,
        "GOOD_OPERATOR": 1,
        "COMFORTABLE_TEMPS": 0,
        "CROWDED": 0,
        "EMPTY": 0,
        "COMFORTABLE_RIDE": 0,
        "NEEDS_WORK": 0,
        "RECENTLY_OFFLOADED": 0,
        "UNCOMFORTABLE_RIDE": 0,
        "UNCOMFORTABLE_TEMPS": 0,
        "WRONG_DESTINATION": 0,
        "SKIPPING_STOPS": 0
      }
    ],
    "numPositiveTags": 1,
    "numNegativeTags": 2
  },
  "5415": "object"
}

Bus Report

GET /metrobus/buses/{busId}/tags

Gets real-time rider reports about a particular bus, referred to as tags. All tags are of predefined types (e.g. 'Good Operator', 'Disruptive Rider', 'Skipping Stops', etc) submitted by MetroHero users. These tags expire anywhere from 15 to 180 minutes after they've been created, depending on the type of tag; only current, unexpired tags are returned by this API.

Bus tags are ordered by tag type in descending order by current number of active tags.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
busId

The unique four-digit vehicle ID of the bus. This is the same ID that can be seen inside and outside the physical bus itself.

type
string
in
path
200 OK

Bus tags successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "numTagsByType": [
    {
      "BAD_OPERATOR": 1,
      "DISRUPTIVE_RIDER": 1,
      "GOOD_OPERATOR": 1,
      "COMFORTABLE_TEMPS": 0,
      "CROWDED": 0,
      "EMPTY": 0,
      "COMFORTABLE_RIDE": 0,
      "NEEDS_WORK": 0,
      "RECENTLY_OFFLOADED": 0,
      "UNCOMFORTABLE_RIDE": 0,
      "UNCOMFORTABLE_TEMPS": 0,
      "WRONG_DESTINATION": 0,
      "SKIPPING_STOPS": 0
    }
  ],
  "numPositiveTags": 1,
  "numNegativeTags": 2
}

Bus Predictions

GET /metrobus/stops/{stopKey}/buses

Gets real-time and scheduled bus predictions for a particular stop.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
stopKey

The bus stop ID and the bus stop name, concatenated with a '='. For example: '4000167=DUKE ST + WALKER ST'. This is case sensitive. Some bus stops don't have an ID or they share an ID with another stop (e.g. 0), but they do have a unique name, hence this contrived "stop key" concept.

type
string
in
path
200 OK

Bus predictions successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
[
  {
    "id": "6236",
    "latitude": 38.901482,
    "longitude": -77.032219,
    "destinationName": "LAFAYETTE SQUARE",
    "tripDirection": "WEST",
    "deviationFromSchedule": 2,
    "lastPositionUpdateString": "2017-08-22T13:36:22",
    "previousStopId": "1001191",
    "previousStopName": "I ST NW + 14TH ST NW",
    "nextStopId": "1001185",
    "nextStopName": "I ST NW + 15TH ST NW",
    "normalizedDistanceToNextStop": 0.952850788114076,
    "estimatedTimeToNextStop": 52,
    "estimatedDistanceFromPreviousStop": 11,
    "estimatedDistanceToNextStop": 213,
    "numStopsAway": 2,
    "scheduledArrival": "2017-08-22T13:45:30",
    "routeId": "X2",
    "timeToBusInFront": 373,
    "timeFromBusBehind": 674,
    "numPositiveTags": 1,
    "numNegativeTags": 0
  }
]

Stop Report

GET /metrobus/stops/{stopKey}/tags

Gets real-time rider reports about a particular stop, referred to as tags. All tags are of predefined types (e.g. 'Empty', 'Clean', 'Crowded', etc) submitted by MetroHero users. These tags expire anywhere from 15 to 180 minutes after they've been created, depending on the type of tag; only current, unexpired tags are returned by this API.

Stop tags are ordered by tag type in descending order by current number of active tags.

apiKey

Your unique API key, provided by us. If you don't have one yet, email us at contact@dcmetrohero.com.

type
string
in
header
stopKey

The bus stop ID and the bus stop name, concatenated with a '='. For example: '4000167=DUKE ST + WALKER ST'. This is case sensitive. Some bus stops don't have an ID or they share an ID with another stop (e.g. 0), but they do have a unique name, hence this contrived "stop key" concept.

type
string
in
path
200 OK

Stop tags successfully retrieved.

400 Bad Request

Invalid request. Make sure the apiKey header and all other required parameters are specified.

401 Unauthorized

You either didn't specify an API key, or the API key you specified was invalid or rejected. Please email us at contact@dcmetrohero.com for assistance.

503 Service Unavailable

You have exceeded our rate limits: by default, all users are limited to 10 calls to any of our APIs per second, and 50,000 calls per 24 hours.

Response Content-Types: application/json
Response Example (200 OK)
{
  "numTagsByType": [
    {
      "EMPTY": 2,
      "CLEAN": 0,
      "CROWDED": 0,
      "LONG_WAITING_TIME": 0,
      "POSTED_TIMES_INACCURATE": 0,
      "NEEDS_WORK": 0,
      "RECENTLY_SKIPPED": 0
    }
  ],
  "numPositiveTags": 2,
  "numNegativeTags": 0
}

Schema Definitions

SystemMetrics: object

lineMetricsByLine: object

Line-specific metrics by line code.

date: string (date-time)

The ISO 8601-formatted datetime this data is from.

Example
{
  "lineMetricsByLine": {
    "RD": "object",
    "OR": {
      "lineCode": "OR",
      "expectedNumTrains": 22,
      "numTrains": 22,
      "numEightCarTrains": 11,
      "numDelayedTrains": 2,
      "numCars": 154,
      "averageTrainDelay": 120,
      "medianTrainDelay": 115,
      "minimumTrainDelay": 0,
      "maximumTrainDelay": 365,
      "averageMinimumHeadways": 6.12,
      "averageTrainFrequency": 6.12,
      "expectedTrainFrequency": 6,
      "averagePlatformWaitTime": 3.12,
      "expectedPlatformWaitTime": 3,
      "trainFrequencyStatus": "OK",
      "platformWaitTimeTrendStatus": "NEUTRAL",
      "averageHeadwayAdherence": 66.6,
      "averageScheduleAdherence": 66.6,
      "standardDeviationTrainFrequency": 1.9,
      "expectedStandardDeviationTrainFrequency": 1.8,
      "directionMetricsByDirection": {
        "1": {
          "lineCode": "OR",
          "directionNumber": 1,
          "direction": "Eastbound",
          "towardsStationName": "New Carrollton",
          "expectedNumTrains": 11,
          "numTrains": 11,
          "numEightCarTrains": 5,
          "numDelayedTrains": 1,
          "numCars": 76,
          "averageTrainDelay": 100,
          "medianTrainDelay": 95,
          "minimumTrainDelay": 0,
          "maximumTrainDelay": 365,
          "averageMinimumHeadways": 6.12,
          "averageTrainFrequency": 6.12,
          "expectedTrainFrequency": 6,
          "averagePlatformWaitTime": 3.12,
          "expectedPlatformWaitTime": 3,
          "trainFrequencyStatus": "OK",
          "platformWaitTimeTrendStatus": "NEUTRAL",
          "averageHeadwayAdherence": 66.6,
          "averageScheduleAdherence": 66.6,
          "standardDeviationTrainFrequency": 1.9,
          "expectedStandardDeviationTrainFrequency": 1.8,
          "date": "2017-06-12T08:24:26.655-04:00"
        },
        "2": "object"
      },
      "date": "2017-06-12T08:24:26.655-04:00"
    },
    "SV": "object",
    "BL": "object",
    "YL": "object",
    "GR": "object"
  },
  "date": "2017-06-12T08:24:26.655-04:00"
}

LineMetrics: object

Line metrics for a specific line.

lineCode: string RD, OR, SV, BL, YL, GR

The line code associated with this data.

expectedNumTrains: integer (int32)

The number of active trains scheduled to be in revenue service, calculated using WMATA's schedule data.

numTrains: integer (int32)

The number of active trains in revenue service.

numEightCarTrains: integer (int32)

The number of active 8-car trains in revenue service.

numDelayedTrains: integer (int32)

The number of active trains in revenue service with a cumulative trip time delay of 5 minutes or more, accumulated during their trip so far by holding and/or moving slowly.

numCars: integer (int32)

The number of train cars in active revenue service, as calculated using numTrains and numEightCarTrains.

averageTrainDelay: integer (int32)

The average cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

medianTrainDelay: integer (int32)

The median cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

minimumTrainDelay: integer (int32)

The minimum cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

maximumTrainDelay: integer (int32)

The maximum cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

averageMinimumHeadways: number (double)

The average predicted headways, i.e. the average travel time between each pair of back-to-back trains given their current positions, and not taking any short-term delays/congestion into account. If there are less than two trains in active revenue service (numTrains), this will be null. (in minutes)

averageTrainFrequency: number (double)

The average observed frequency of trains arriving at stations, i.e. the average time between trains. This may be null if there is not sufficient data yet. (in minutes)

expectedTrainFrequency: number (double)

The expected time between trains, as calculated using WMATA's schedule data. (in minutes)

averagePlatformWaitTime: number (double)

The average wait time on station platforms for a train, calculated by us using the following formula: (μ (1 + σ² / μ²) / 2), where μ and σ are respectively the mean and standard deviation of the time headways between observed train arrivals at stations. We optimistically assume every rider is able to board the first train they're waiting for, which is not always the case, but WMATA does not make any real-time ridership data available for us to use. This may be null if there is not sufficient data yet. (in minutes)

expectedPlatformWaitTime: number (double)

The expected platform wait time, as calculated using WMATA's schedule data plugged into the formula mentioned in the description of averagePlatformWaitTime. (in minutes)

trainFrequencyStatus: string OK, SLOW, DELAYED

The average train frequency (averageTrainFrequency) compared to the expected train frequency (expectedTrainFrequency). If the difference between the average train frequency minus the expected train frequency is less than or equal to one minute, OK is used; if the difference is greater than one minute but less than or equal to two minutes, DELAYED is used; otherwise, OK is used. This may be null if there is not sufficient data yet.

platformWaitTimeTrendStatus: string DECREASING, NEUTRAL, INCREASING

The trend of the average platform wait time (averagePlatformWaitTime) over the last 15 minutes. This may be null if there is not sufficient data yet.

averageHeadwayAdherence: number (double)

Estimated headway adherence of trains, calculated by comparing observed train arrivals at each station to WMATA's schedule data, expressed as a percentage between 0 and 100. We consider a train to be adhering to scheduled headways if the time between the last train\'s arrival and this train\'s arrival is less than or equal to one full expected headway, plus 2 minutes. This may be null if there is not sufficient data yet.

averageScheduleAdherence: number (double)

Estimated schedule adherence of trains, calculated by comparing observed train arrivals at each station to WMATA's schedule data, expressed as a percentage between 0 and 100. We consider a train as adhering to schedule if it arrives within (+/−) 2 minutes of schedule. This may be null if there is not sufficient data yet.

standardDeviationTrainFrequency: number (double)

Train spacing consistency, i.e. the observed variance in the frequency at which trains are arriving at stations. Technically, this is the standard deviation of those frequencies. This may be null if there is not sufficient data yet. (in minutes)

expectedStandardDeviationTrainFrequency: number (double)

Expected train spacing consistency, i.e. the expected variance in the frequency at which trains are arriving at stations. Technically, this is the standard deviation of those expected frequencies calculated using WMATA's schedule data. (in minutes)

directionMetricsByDirection: object

Line and direction-specific metrics by direction number.

date: string (date-time)

The ISO 8601-formatted datetime this data is from.

Example
{
  "lineCode": "OR",
  "expectedNumTrains": 22,
  "numTrains": 22,
  "numEightCarTrains": 11,
  "numDelayedTrains": 2,
  "numCars": 154,
  "averageTrainDelay": 120,
  "medianTrainDelay": 115,
  "minimumTrainDelay": 0,
  "maximumTrainDelay": 365,
  "averageMinimumHeadways": 6.12,
  "averageTrainFrequency": 6.12,
  "expectedTrainFrequency": 6,
  "averagePlatformWaitTime": 3.12,
  "expectedPlatformWaitTime": 3,
  "trainFrequencyStatus": "OK",
  "platformWaitTimeTrendStatus": "NEUTRAL",
  "averageHeadwayAdherence": 66.6,
  "averageScheduleAdherence": 66.6,
  "standardDeviationTrainFrequency": 1.9,
  "expectedStandardDeviationTrainFrequency": 1.8,
  "directionMetricsByDirection": {
    "1": {
      "lineCode": "OR",
      "directionNumber": 1,
      "direction": "Eastbound",
      "towardsStationName": "New Carrollton",
      "expectedNumTrains": 11,
      "numTrains": 11,
      "numEightCarTrains": 5,
      "numDelayedTrains": 1,
      "numCars": 76,
      "averageTrainDelay": 100,
      "medianTrainDelay": 95,
      "minimumTrainDelay": 0,
      "maximumTrainDelay": 365,
      "averageMinimumHeadways": 6.12,
      "averageTrainFrequency": 6.12,
      "expectedTrainFrequency": 6,
      "averagePlatformWaitTime": 3.12,
      "expectedPlatformWaitTime": 3,
      "trainFrequencyStatus": "OK",
      "platformWaitTimeTrendStatus": "NEUTRAL",
      "averageHeadwayAdherence": 66.6,
      "averageScheduleAdherence": 66.6,
      "standardDeviationTrainFrequency": 1.9,
      "expectedStandardDeviationTrainFrequency": 1.8,
      "date": "2017-06-12T08:24:26.655-04:00"
    },
    "2": "object"
  },
  "date": "2017-06-12T08:24:26.655-04:00"
}

DirectionMetrics: object

Direction metrics for a specific line and direction. This may be null if there are no trains going in this direction.

lineCode: string RD, OR, SV, BL, YL, GR

The line code associated with this data.

directionNumber: integer (int32) 1, 2

The direction number associated with this data.

direction: string

A human-readable name for the cardinal direction trains are generally headed in.

towardsStationName: string

A human-readable name for the terminal station trains are generally headed towards.

expectedNumTrains: integer (int32)

The number of active trains scheduled to be in revenue service, calculated using WMATA's schedule data.

numTrains: integer (int32)

The number of active trains in revenue service.

numEightCarTrains: integer (int32)

The number of active 8-car trains in revenue service.

numDelayedTrains: integer (int32)

The number of active trains in revenue service with a cumulative trip time delay of 5 minutes or more, accumulated during their trip so far by holding and/or moving slowly.

numCars: integer (int32)

The number of train cars in active revenue service, as calculated using numTrains and numEightCarTrains.

averageTrainDelay: integer (int32)

The average cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

medianTrainDelay: integer (int32)

The median cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

minimumTrainDelay: integer (int32)

The minimum cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

maximumTrainDelay: integer (int32)

The maximum cumulative trip time delay of trains in active revenue service. If there are no trains in active revenue service (numTrains), this will be null. (in seconds)

averageMinimumHeadways: number (double)

The average predicted headways, i.e. the average travel time between each pair of back-to-back trains given their current positions, and not taking any short-term delays/congestion into account. If there are less than two trains in active revenue service (numTrains), this will be null. (in minutes)

averageTrainFrequency: number (double)

The average observed frequency of trains arriving at stations, i.e. the average time between trains. This may be null if there is not sufficient data yet. (in minutes)

expectedTrainFrequency: number (double)

The expected time between trains, as calculated using WMATA's schedule data. (in minutes)

averagePlatformWaitTime: number (double)

The average wait time on station platforms for a train, calculated by us using the following formula: (μ (1 + σ² / μ²) / 2), where μ and σ are respectively the mean and standard deviation of the time headways between observed train arrivals at stations. We optimistically assume every rider is able to board the first train they're waiting for, which is not always the case, but WMATA does not make any real-time ridership data available for us to use. This may be null if there is not sufficient data yet. (in minutes)

expectedPlatformWaitTime: number (double)

The expected platform wait time, as calculated using WMATA's schedule data plugged into the formula mentioned in the description of averagePlatformWaitTime. (in minutes)

trainFrequencyStatus: string OK, SLOW, DELAYED

The average train frequency (averageTrainFrequency) compared to the expected train frequency (expectedTrainFrequency). If the difference between the average train frequency minus the expected train frequency is less than or equal to one minute, OK is used; if the difference is greater than one minute but less than or equal to two minutes, DELAYED is used; otherwise, OK is used. This may be null if there is not sufficient data yet.

platformWaitTimeTrendStatus: string DECREASING, NEUTRAL, INCREASING

The trend of the average platform wait time (averagePlatformWaitTime) over the last 15 minutes. This may be null if there is not sufficient data yet.

averageHeadwayAdherence: number (double)

Estimated headway adherence of trains, calculated by comparing observed train arrivals at each station to WMATA's schedule data, expressed as a percentage between 0 and 100. We consider a train to be adhering to scheduled headways if the time between the last train\'s arrival and this train\'s arrival is less than or equal to one full expected headway, plus 2 minutes. This may be null if there is not sufficient data yet.

averageScheduleAdherence: number (double)

Estimated schedule adherence of trains, calculated by comparing observed train arrivals at each station to WMATA's schedule data, expressed as a percentage between 0 and 100. We consider a train as adhering to schedule if it arrives within (+/−) 2 minutes of schedule. This may be null if there is not sufficient data yet.

standardDeviationTrainFrequency: number (double)

Train spacing consistency, i.e. the observed variance in the frequency at which trains are arriving at stations. Technically, this is the standard deviation of those frequencies. This may be null if there is not sufficient data yet. (in minutes)

expectedStandardDeviationTrainFrequency: number (double)

Expected train spacing consistency, i.e. the expected variance in the frequency at which trains are arriving at stations. Technically, this is the standard deviation of those expected frequencies calculated using WMATA's schedule data. (in minutes)

date: string (date-time)

The ISO 8601-formatted datetime this data is from.

Example
{
  "lineCode": "OR",
  "directionNumber": 1,
  "direction": "Eastbound",
  "towardsStationName": "New Carrollton",
  "expectedNumTrains": 11,
  "numTrains": 11,
  "numEightCarTrains": 5,
  "numDelayedTrains": 1,
  "numCars": 76,
  "averageTrainDelay": 100,
  "medianTrainDelay": 95,
  "minimumTrainDelay": 0,
  "maximumTrainDelay": 365,
  "averageMinimumHeadways": 6.12,
  "averageTrainFrequency": 6.12,
  "expectedTrainFrequency": 6,
  "averagePlatformWaitTime": 3.12,
  "expectedPlatformWaitTime": 3,
  "trainFrequencyStatus": "OK",
  "platformWaitTimeTrendStatus": "NEUTRAL",
  "averageHeadwayAdherence": 66.6,
  "averageScheduleAdherence": 66.6,
  "standardDeviationTrainFrequency": 1.9,
  "expectedStandardDeviationTrainFrequency": 1.8,
  "date": "2017-06-12T08:24:26.655-04:00"
}

TripInfo: object

fromStationName: string

The name of the origin station (fromStation) of the trip.

fromStationCode: string

The RTU station code of the origin station (fromStation) of the trip.

toStationName: string

The name of the destination station (toStation) of the trip.

toStationCode: string

The RTU station code of the destination station (toStation) of the trip.

lineCodes: string[]

A list of line codes of lines that normally service this trip. This does not take current conditions into account and is basically static data; if different lines are servicing this trip than usual due to track work or something, those temporary service changes are not reflected here.

expectedRideTime: number (double)

How long the ride is expected to take based on the median trip time of up to 30 days' worth of data about this trip. (in minutes)

predictedRideTime: number (double)

Predicted ride time once a rider is aboard the next train to service this trip, based on current conditions and/or conditions in the recent past. This may be null if there is not sufficient data yet. (in minutes)

timeUntilNextTrain: number (double)

Predicted wait time remaining from the origin station's platform for the next train to service this trip, based on current conditions and/or conditions in the recent past. 0 means the next train is currently boarding at the origin station of the trip. (in minutes)

timeSinceLastTrain: number (double)

How long ago a train headed towards the destination station last departed the origin station. (in minutes)

date: string (date-time)

The ISO 8601-formatted datetime this data is from.

Example
{
  "fromStationName": "Vienna",
  "fromStationCode": "K08",
  "toStationName": "Metro Center",
  "toStationCode": "C01",
  "lineCodes": [
    "OR"
  ],
  "expectedRideTime": 26.12,
  "predictedRideTime": 30.3303,
  "timeUntilNextTrain": 2.02,
  "timeSinceLastTrain": 4.26,
  "date": "2017-06-12T08:24:26.655-04:00"
}

TrainPrediction: object

trainId: string

If this prediction is based on real-time train data and not scheduled train data, i.e. if isScheduled is false, then this is the AIMS internal ID of the train, as defined by WMATA's Train Positions API as a three-digit string anywhere from 001 to 512. Otherwise, this is a unique trip ID, like '58633'.

Car: string

The number of cars that make up this train. Can be 'N/A' indicating that for whatever reason, the number of cars is not known.

Destination: string

A human-readable name of the destination station of this train. Unlike WMATA's Real-Time Rail Predictions API, this is the same as DestinationName, not an abbreviated version of the destination station name.

DestinationCode: string

The RTU station code of the destination station of this train.

DestinationName: string

A human-readable name of the destination station of this train.

Group: string 1, 2

Indicates which side of the tracks ('1' for track 1, '2' for track 2) the train is on.

Line: string RD, OR, SV, BL, YL, GR

The line code of the line this train is servicing.

LocationCode: string

The RTU station code of the current or next station this train is or will be servicing next.

LocationName: string

A human-readable name of the current or next station this train is or will be servicing next.

Min: string

The predicted arrival time of the train at the station passed into the request to the API that returns this prediction--or, if that's not applicable, the predicted arrival time of the train at the station it will be servicing next--expressed as the nearest whole number of minutes (e.g. '3'), or as 'ARR' for arriving (if the prediction has the train less than or equal to 30 seconds away), or as 'BRD' for boarding. Alternatively, if this prediction is based on scheduled train data and not real-time train data, i.e. if isScheduled is true, a time is used instead--'11:30' for 11:30am or 11:30pm, for example. If an arrival prediction time is not available for this train, '?' will be returned instead.

parentMin: string

The predicted arrival time of the train at the station it will be servicing next, expressed as the nearest whole number of minutes (e.g. '3'), or as 'ARR' for arriving (if the prediction has the train less than or equal to 30 seconds away), or as 'BRD' for boarding. Alternatively, if this prediction is based on scheduled train data and not real-time train data, i.e. if isScheduled is true, a time is used instead--'11:30' for 11:30am or 11:30pm, for example. If an arrival prediction time is not available for this train, '?' will be returned instead. This is null if the request to the API that returns this prediction does not specify a station to get a prediction for; in that case, use Min instead.

minutesAway: number (double)

The predicted arrival time of the train at the station it will be servicing next. It can be null if the previous station a train came from (PreviousStationCode) cannot be determined from its current or any previous position. (in minutes)

maxMinutesAway: number (double)

The theoretical maximum predicted arrival time of the train at the station it will be servicing next from the station it serviced previously. This can be used to normalize minutesAway. This is null if this prediction is based on scheduled train data and not real-time train data, i.e. if isScheduled is true. It can also be null if the previous station a train came from (PreviousStationCode) cannot be determined from its current or any previous position. (in minutes)

directionNumber: number (int32) 1, 2

Like Group, this corresponds to either track 1 or 2, however this represents the direction the train is currently headed in, not the track it is currently on. Thus, this and Group can be different if, for example, this train is moving through a single-tracking area.

isScheduled: boolean

True if this prediction is based on scheduled train data and not real-time train data, otherwise false.

numPositiveTags: number (int32)

The number of positive tags, as made by MetroHero users, currently active for this train. See the TrainTags model defintion for more info.

numNegativeTags: number (int32)

The number of negative tags, as made by MetroHero users, currently active for this train. See the TrainTags model defintion for more info.

trackNumber: number (int32) 1, 2

Indicates which side of the tracks (1 for track 1, 2 for track 2) the train is on. The same as Group, but an integer instead of a string.

PreviousStationCode: string

The RTU station code of the previous station this train previously serviced last based on its current position. Note that this is not necessarily the actual station the train previously serviced if, for example, the train turned around after visiting its previous station.

previousStationName: string

A human-readable name of the previous station this train previously serviced last based on its current position. Note that this is not necessarily the actual station the train previously serviced if, for example, the train turned around after visiting its previous station.

secondsSinceLastMoved: number (int32)

The number of seconds since Min changed last. (in seconds)

isCurrentlyHoldingOrSlow: boolean

True if secondsSinceLastMoved exceeds that of expected, i.e. Min has not changed for more than 30 seconds if Min is 'ARR', or, if Min is something else, if it has not changed for more than 60 seconds. Otherwise, it's false.

secondsOffSchedule: number (int32)

The running total delay this train has accumulated during its trip so far, not including the current value of secondsSinceLastMoved. This resets once the train completes its trip. (in seconds)

trainSpeed: number (int32)

The estimated speed this train was last observed traveling at. This is very heuristic in nature and is calculated at the track circuit level by observing the train's movement between data updates from WMATA. (in miles per hour)

isNotOnRevenueTrack: boolean

True if the train is on non-revenue track after having last been observed on revenue track, otherwise false. If this is true, the rest of this prediction (e.g. Min, secondsSinceLastMoved, etc) reflect the train's state when it was last observed on revenue track, not its current state on non-revenue track.

isKeyedDown: boolean

True if we believe the train to be powered down, i.e. if it hasn't moved from its current position for 30 minutes or more.

wasKeyedDown: boolean

True if we believe the train to have been powered down recently (not considering isKeyedDown), i.e. if at some point during its current trip from one station to another neighboring station, the train did not move from its position for 30 minutes or more.

distanceFromNextStation: number (int32)

The estimated track distance away this train is from its next station stop, calculated using real track circuit lengths. This is 0 if the train is currently boarding at a station. Can be null if the next station stop (LocationCode) cannot be determined, or if an estimated distance is otherwise not available. (in feet)

observedDate: string (date-time)

A poorly-formatted date for when this prediction was made.

Example
{
  "trainId": "155",
  "Car": "8",
  "Destination": "Vienna",
  "DestinationCode": "K08",
  "DestinationName": "Vienna",
  "Group": "1",
  "Line": "Vienna",
  "LocationCode": "C01",
  "LocationName": "Metro Center",
  "Min": "1",
  "parentMin": "1",
  "minutesAway": 0.89,
  "maxMinutesAway": 1.12,
  "directionNumber": 1,
  "isScheduled": false,
  "numPositiveTags": 1,
  "numNegativeTags": 3,
  "trackNumber": 1,
  "PreviousStationCode": "D01",
  "previousStationName": "Federal Triangle",
  "secondsSinceLastMoved": 65,
  "isCurrentlyHoldingOrSlow": true,
  "secondsOffSchedule": 145,
  "trainSpeed": 23,
  "isNotOnRevenueTrack": false,
  "isKeyedDown": false,
  "wasKeyedDown": false,
  "distanceFromNextStation": 502,
  "observedDate": "Aug 11, 2017 3:51:54 PM"
}

TrainTags: object

numTagsByType: NumTrainTagsByType

Ordered by tag type in descending order by number of tags.

numPositiveTags: integer (int32)

The number of tags with positive sentiment currently active for the specified train.

numNegativeTags: integer (int32)

The number of tags with negative sentiment currently active for the specified train.

Example
{
  "numTagsByType": [
    {
      "BAD_OPERATOR": 1,
      "ISOLATED_CARS": 1,
      "NEW_TRAIN": 1,
      "BROKEN_INTERCOM": 0,
      "CROWDED": 0,
      "EMPTY": 0,
      "GOOD_OPERATOR": 0,
      "GOOD_RIDE": 0,
      "NEEDS_WORK": 0,
      "RECENTLY_OFFLOADED": 0,
      "UNCOMFORTABLE_RIDE": 0,
      "UNCOMFORTABLE_TEMPS": 0,
      "WRONG_DESTINATION": 0,
      "WRONG_NUM_CARS": 0
    }
  ],
  "numPositiveTags": 1,
  "numNegativeTags": 2
}

NumTrainTagsByType: object

BAD_OPERATOR: integer (int32)

The number of 'BAD_OPERATOR' tags currently active for the specified train. A 'BAD_OPERATOR' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

ISOLATED_CARS: integer (int32)

The number of 'ISOLATED_CARS' tags currently active for the specified train. A 'ISOLATED_CARS' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

NEW_TRAIN: integer (int32)

The number of 'NEW_TRAIN' tags currently active for the specified train. A 'NEW_TRAIN' tag is considered to be of positive sentiment, and tags of this type expire after 60 minutes.

BROKEN_INTERCOM: integer (int32)

The number of 'BROKEN_INTERCOM' tags currently active for the specified train. A 'BROKEN_INTERCOM' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

CROWDED: integer (int32)

The number of 'CROWDED' tags currently active for the specified train. A 'CROWDED' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

EMPTY: integer (int32)

The number of 'EMPTY' tags currently active for the specified train. A 'EMPTY' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

GOOD_OPERATOR: integer (int32)

The number of 'GOOD_OPERATOR' tags currently active for the specified train. A 'GOOD_OPERATOR' tag is considered to be of positive sentiment, and tags of this type expire after 60 minutes.

GOOD_RIDE: integer (int32)

The number of 'GOOD_RIDE' tags currently active for the specified train. A 'GOOD_RIDE' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

NEEDS_WORK: integer (int32)

The number of 'NEEDS_WORK' tags currently active for the specified train. A 'NEEDS_WORK' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

RECENTLY_OFFLOADED: integer (int32)

The number of 'RECENTLY_OFFLOADED' tags currently active for the specified train. A 'RECENTLY_OFFLOADED' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

UNCOMFORTABLE_RIDE: integer (int32)

The number of 'UNCOMFORTABLE_RIDE' tags currently active for the specified train. A 'UNCOMFORTABLE_RIDE' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

UNCOMFORTABLE_TEMPS: integer (int32)

The number of 'UNCOMFORTABLE_TEMPS' tags currently active for the specified train. A 'UNCOMFORTABLE_TEMPS' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

WRONG_DESTINATION: integer (int32)

The number of 'WRONG_DESTINATION' tags currently active for the specified train. A 'WRONG_DESTINATION' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

WRONG_NUM_CARS: integer (int32)

The number of 'WRONG_NUM_CARS' tags currently active for the specified train. A 'WRONG_NUM_CARS' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

Example
{
  "BAD_OPERATOR": 1,
  "ISOLATED_CARS": 1,
  "NEW_TRAIN": 1,
  "BROKEN_INTERCOM": 0,
  "CROWDED": 0,
  "EMPTY": 0,
  "GOOD_OPERATOR": 0,
  "GOOD_RIDE": 0,
  "NEEDS_WORK": 0,
  "RECENTLY_OFFLOADED": 0,
  "UNCOMFORTABLE_RIDE": 0,
  "UNCOMFORTABLE_TEMPS": 0,
  "WRONG_DESTINATION": 0,
  "WRONG_NUM_CARS": 0
}

StationTags: object

numTagsByType: NumStationTagsByType

Ordered by tag type in descending order by number of tags.

numPositiveTags: integer (int32)

The number of tags with positive sentiment currently active for the specified station.

numNegativeTags: integer (int32)

The number of tags with negative sentiment currently active for the specified station.

Example
{
  "numTagsByType": [
    {
      "FRIENDLY_OR_HELPFUL_STAFF": 1,
      "UNCOMFORTABLE_TEMPS": 1,
      "AMPLE_SECURITY": 0,
      "BROKEN_ELEVATOR": 0,
      "BROKEN_ESCALATOR": 0,
      "CROWDED": 0,
      "EMPTY": 0,
      "LONG_WAITING_TIME": 0,
      "NEEDS_WORK": 0,
      "POSTED_TIMES_INACCURATE": 0,
      "SMOKE_OR_FIRE": 0,
      "UNFRIENDLY_OR_UNHELPFUL_STAFF": 0
    }
  ],
  "numPositiveTags": 1,
  "numNegativeTags": 1
}

NumStationTagsByType: object

FRIENDLY_OR_HELPFUL_STAFF: integer (int32)

The number of 'FRIENDLY_OR_HELPFUL_STAFF' tags currently active for the specified station. A 'FRIENDLY_OR_HELPFUL_STAFF' tag is considered to be of positive sentiment, and tags of this type expire after 60 minutes.

UNCOMFORTABLE_TEMPS: integer (int32)

The number of 'UNCOMFORTABLE_TEMPS' tags currently active for the specified station. A 'UNCOMFORTABLE_TEMPS' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

AMPLE_SECURITY: integer (int32)

The number of 'AMPLE_SECURITY' tags currently active for the specified station. A 'AMPLE_SECURITY' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

BROKEN_ELEVATOR: integer (int32)

The number of 'BROKEN_ELEVATOR' tags currently active for the specified station. A 'BROKEN_ELEVATOR' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

BROKEN_ESCALATOR: integer (int32)

The number of 'BROKEN_ESCALATOR' tags currently active for the specified station. A 'BROKEN_ESCALATOR' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

CROWDED: integer (int32)

The number of 'CROWDED' tags currently active for the specified station. A 'CROWDED' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

EMPTY: integer (int32)

The number of 'EMPTY' tags currently active for the specified station. A 'EMPTY' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

LONG_WAITING_TIME: integer (int32)

The number of 'LONG_WAITING_TIME' tags currently active for the specified station. A 'LONG_WAITING_TIME' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

NEEDS_WORK: integer (int32)

The number of 'NEEDS_WORK' tags currently active for the specified station. A 'NEEDS_WORK' tag is considered to be of negative sentiment, and tags of this type expire after 180 minutes.

POSTED_TIMES_INACCURATE: integer (int32)

The number of 'POSTED_TIMES_INACCURATE' tags currently active for the specified station. A 'POSTED_TIMES_INACCURATE' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

SMOKE_OR_FIRE: integer (int32)

The number of 'SMOKE_OR_FIRE' tags currently active for the specified station. A 'SMOKE_OR_FIRE' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

UNFRIENDLY_OR_UNHELPFUL_STAFF: integer (int32)

The number of 'UNFRIENDLY_OR_UNHELPFUL_STAFF' tags currently active for the specified station. A 'UNFRIENDLY_OR_UNHELPFUL_STAFF' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

Example
{
  "FRIENDLY_OR_HELPFUL_STAFF": 1,
  "UNCOMFORTABLE_TEMPS": 1,
  "AMPLE_SECURITY": 0,
  "BROKEN_ELEVATOR": 0,
  "BROKEN_ESCALATOR": 0,
  "CROWDED": 0,
  "EMPTY": 0,
  "LONG_WAITING_TIME": 0,
  "NEEDS_WORK": 0,
  "POSTED_TIMES_INACCURATE": 0,
  "SMOKE_OR_FIRE": 0,
  "UNFRIENDLY_OR_UNHELPFUL_STAFF": 0
}

RouteMetrics: object

headwayDeviation: number (double)

The standard deviation of bus headways, where each bus headway is measured from one bus to the next bus behind it that is servicing the same route and direction. (in seconds)

percentageAcceptableHeadways: number (double)

The percentage of bus headways that are between 0.5x and 1.5x the average bus headway; headways within that range are considered acceptable.

averageScheduleDeviation: number (double)

The standard deviation of how deviated from schedule buses are. (in minutes)

date: string (date-time)

The ISO 8601-formatted datetime this data is from.

Example
{
  "headwayDeviation": 460.12,
  "percentageAcceptableHeadways": 52.11,
  "averageScheduleDeviation": 2.53,
  "date": "2017-06-12T08:24:26.655-04:00"
}

BusPrediction: object

id: string

If this prediction is based on real-time bus data and not scheduled bus data, i.e. if scheduledArrival is null, then this is the unique four-digit vehicle ID of the bus, i.e. the same ID that can be seen inside and outside the physical bus itself. Otherwise, this is a unique trip ID like '922289620'.

latitude: number (double)
longitude: number (double)
destinationName: string
tripDirection: string
deviationFromSchedule: number (int32')
lastPositionUpdateString: string
previousStopId: string
previousStopName: string
nextStopId: string
nextStopName: string
normalizedDistanceToNextStop: number (double)
estimatedTimeToNextStop: number (int32)
estimatedDistanceFromPreviousStop: number (int32)
estimatedDistanceToNextStop: number (int32)
numStopsAway: number (int32)
scheduledArrival: string (date-time)

The scheduled arrival time for this bus at the specified stop passed into the request to the API that returns this prediction. If this prediction is not based on scheduled bus data, or if no stop is passed into the request to the API that returns this prediction, then this is null.

routeId: string
timeToBusInFront: number (int32)
timeFromBusBehind: number (int32)
numPositiveTags: number (int32)

The number of positive tags, as made by MetroHero users, currently active for this train. See the BusTags model defintion for more info.

numNegativeTags: number (int32)

The number of negative tags, as made by MetroHero users, currently active for this train. See the BusTags model defintion for more info.

Example
{
  "id": "6236",
  "latitude": 38.901482,
  "longitude": -77.032219,
  "destinationName": "LAFAYETTE SQUARE",
  "tripDirection": "WEST",
  "deviationFromSchedule": 2,
  "lastPositionUpdateString": "2017-08-22T13:36:22",
  "previousStopId": "1001191",
  "previousStopName": "I ST NW + 14TH ST NW",
  "nextStopId": "1001185",
  "nextStopName": "I ST NW + 15TH ST NW",
  "normalizedDistanceToNextStop": 0.952850788114076,
  "estimatedTimeToNextStop": 52,
  "estimatedDistanceFromPreviousStop": 11,
  "estimatedDistanceToNextStop": 213,
  "numStopsAway": 2,
  "scheduledArrival": "2017-08-22T13:45:30",
  "routeId": "X2",
  "timeToBusInFront": 373,
  "timeFromBusBehind": 674,
  "numPositiveTags": 1,
  "numNegativeTags": 0
}

BusTags: object

numTagsByType: NumBusTagsByType

Ordered by tag type in descending order by number of tags.

numPositiveTags: integer (int32)

The number of tags with positive sentiment currently active for the specified bus.

numNegativeTags: integer (int32)

The number of tags with negative sentiment currently active for the specified bus.

Example
{
  "numTagsByType": [
    {
      "BAD_OPERATOR": 1,
      "DISRUPTIVE_RIDER": 1,
      "GOOD_OPERATOR": 1,
      "COMFORTABLE_TEMPS": 0,
      "CROWDED": 0,
      "EMPTY": 0,
      "COMFORTABLE_RIDE": 0,
      "NEEDS_WORK": 0,
      "RECENTLY_OFFLOADED": 0,
      "UNCOMFORTABLE_RIDE": 0,
      "UNCOMFORTABLE_TEMPS": 0,
      "WRONG_DESTINATION": 0,
      "SKIPPING_STOPS": 0
    }
  ],
  "numPositiveTags": 1,
  "numNegativeTags": 2
}

NumBusTagsByType: object

BAD_OPERATOR: integer (int32)

The number of 'BAD_OPERATOR' tags currently active for the specified bus. A 'BAD_OPERATOR' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

DISRUPTIVE_RIDER: integer (int32)

The number of 'DISRUPTIVE_RIDER' tags currently active for the specified bus. A 'DISRUPTIVE_RIDER' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

GOOD_OPERATOR: integer (int32)

The number of 'GOOD_OPERATOR' tags currently active for the specified bus. A 'GOOD_OPERATOR' tag is considered to be of positive sentiment, and tags of this type expire after 60 minutes.

COMFORTABLE_TEMPS: integer (int32)

The number of 'COMFORTABLE_TEMPS' tags currently active for the specified bus. A 'COMFORTABLE_TEMPS' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

CROWDED: integer (int32)

The number of 'CROWDED' tags currently active for the specified bus. A 'CROWDED' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

EMPTY: integer (int32)

The number of 'EMPTY' tags currently active for the specified bus. A 'EMPTY' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

COMFORTABLE_RIDE: integer (int32)

The number of 'COMFORTABLE_RIDE' tags currently active for the specified bus. A 'COMFORTABLE_RIDE' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

NEEDS_WORK: integer (int32)

The number of 'NEEDS_WORK' tags currently active for the specified bus. A 'NEEDS_WORK' tag is considered to be of negative sentiment, and tags of this type expire after 60 minutes.

RECENTLY_OFFLOADED: integer (int32)

The number of 'RECENTLY_OFFLOADED' tags currently active for the specified bus. A 'RECENTLY_OFFLOADED' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

UNCOMFORTABLE_RIDE: integer (int32)

The number of 'UNCOMFORTABLE_RIDE' tags currently active for the specified bus. A 'UNCOMFORTABLE_RIDE' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

UNCOMFORTABLE_TEMPS: integer (int32)

The number of 'UNCOMFORTABLE_TEMPS' tags currently active for the specified bus. A 'UNCOMFORTABLE_TEMPS' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

WRONG_DESTINATION: integer (int32)

The number of 'WRONG_DESTINATION' tags currently active for the specified bus. A 'WRONG_DESTINATION' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

SKIPPING_STOPS: integer (int32)

The number of 'SKIPPING_STOPS' tags currently active for the specified bus. A 'SKIPPING_STOPS' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

Example
{
  "BAD_OPERATOR": 1,
  "DISRUPTIVE_RIDER": 1,
  "GOOD_OPERATOR": 1,
  "COMFORTABLE_TEMPS": 0,
  "CROWDED": 0,
  "EMPTY": 0,
  "COMFORTABLE_RIDE": 0,
  "NEEDS_WORK": 0,
  "RECENTLY_OFFLOADED": 0,
  "UNCOMFORTABLE_RIDE": 0,
  "UNCOMFORTABLE_TEMPS": 0,
  "WRONG_DESTINATION": 0,
  "SKIPPING_STOPS": 0
}

StopTags: object

numTagsByType: NumStopTagsByType

Ordered by tag type in descending order by number of tags.

numPositiveTags: integer (int32)

The number of tags with positive sentiment currently active for the specified stop.

numNegativeTags: integer (int32)

The number of tags with negative sentiment currently active for the specified stop.

Example
{
  "numTagsByType": [
    {
      "EMPTY": 2,
      "CLEAN": 0,
      "CROWDED": 0,
      "LONG_WAITING_TIME": 0,
      "POSTED_TIMES_INACCURATE": 0,
      "NEEDS_WORK": 0,
      "RECENTLY_SKIPPED": 0
    }
  ],
  "numPositiveTags": 2,
  "numNegativeTags": 0
}

NumStopTagsByType: object

EMPTY: integer (int32)

The number of 'EMPTY' tags currently active for the specified bus. A 'EMPTY' tag is considered to be of positive sentiment, and tags of this type expire after 30 minutes.

CLEAN: integer (int32)

The number of 'CLEAN' tags currently active for the specified bus. A 'CLEAN' tag is considered to be of positive sentiment, and tags of this type expire after 180 minutes.

CROWDED: integer (int32)

The number of 'CROWDED' tags currently active for the specified bus. A 'CROWDED' tag is considered to be of negative sentiment, and tags of this type expire after 30 minutes.

LONG_WAITING_TIME: integer (int32)

The number of 'LONG_WAITING_TIME' tags currently active for the specified bus. A 'LONG_WAITING_TIME' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

POSTED_TIMES_INACCURATE: integer (int32)

The number of 'POSTED_TIMES_INACCURATE' tags currently active for the specified bus. A 'POSTED_TIMES_INACCURATE' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

NEEDS_WORK: integer (int32)

The number of 'NEEDS_WORK' tags currently active for the specified bus. A 'NEEDS_WORK' tag is considered to be of negative sentiment, and tags of this type expire after 180 minutes.

RECENTLY_SKIPPED: integer (int32)

The number of 'RECENTLY_SKIPPED' tags currently active for the specified bus. A 'RECENTLY_SKIPPED' tag is considered to be of negative sentiment, and tags of this type expire after 15 minutes.

Example
{
  "EMPTY": 2,
  "CLEAN": 0,
  "CROWDED": 0,
  "LONG_WAITING_TIME": 0,
  "POSTED_TIMES_INACCURATE": 0,
  "NEEDS_WORK": 0,
  "RECENTLY_SKIPPED": 0
}