{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/transitland/json-schema/transitland-plan-response-schema.json",
  "title": "PlanResponse",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/transitland-transit-routing-api-openapi.yml#/components/schemas/PlanResponse",
  "properties": {
    "earliestArrivals": {
      "description": "Earliest arrival time at each reachable stop. Present only when `includeEarliestArrivals` is true.",
      "items": {
        "$ref": "#/$defs/StopArrival"
      },
      "type": "array"
    },
    "plan": {
      "$ref": "#/$defs/Plan"
    }
  },
  "type": "object",
  "$defs": {
    "Itinerary": {
      "properties": {
        "distance": {
          "description": "Total distance of the itinerary (in meters).",
          "type": "number"
        },
        "duration": {
          "description": "Total duration of the itinerary in seconds.",
          "format": "int64",
          "type": "integer"
        },
        "endTime": {
          "description": "Epoch timestamp (in milliseconds) for the end time of the itinerary.",
          "format": "int64",
          "type": "integer"
        },
        "legs": {
          "description": "Segments of the trip in order, each either a walk or a single transit ride.",
          "items": {
            "$ref": "#/$defs/Leg"
          },
          "type": "array"
        },
        "startTime": {
          "description": "Epoch timestamp (in milliseconds) for the start time of the itinerary.",
          "format": "int64",
          "type": "integer"
        },
        "transfers": {
          "description": "Number of transfers in the itinerary.",
          "type": "integer"
        },
        "transitDistance": {
          "description": "Total transit distance (in meters) for the itinerary.",
          "type": "number"
        },
        "transitTime": {
          "description": "Total transit time (in seconds) for the itinerary.",
          "format": "int64",
          "type": "integer"
        },
        "waitingTime": {
          "description": "Total waiting time (in seconds) for the itinerary.",
          "format": "int64",
          "type": "integer"
        },
        "walkDistance": {
          "description": "Total walking distance (in meters) for the itinerary.",
          "type": "number"
        },
        "walkTime": {
          "description": "Total walking time (in seconds) for the itinerary.",
          "format": "int64",
          "type": "integer"
        }
      },
      "type": "object"
    },
    "Leg": {
      "properties": {
        "agencyId": {
          "description": "Transit agency identifier.",
          "type": "string"
        },
        "agencyName": {
          "description": "Transit agency name.",
          "type": "string"
        },
        "arrivalDelay": {
          "description": "The run's delay where the rider alights, in seconds. Tiles keep departures only, so this is the delay on the departure from that stop.",
          "format": "int64",
          "type": "integer"
        },
        "block_id": {
          "description": "GTFS `block_id` of the trip, when the feed sets one. Named in snake_case unlike the rest of this object, which is how the API emits it.",
          "type": "string"
        },
        "departureDelay": {
          "description": "The run's delay where the rider boards, in seconds: the departure routing used less the scheduled one.",
          "format": "int64",
          "type": "integer"
        },
        "distance": {
          "description": "Distance of the leg in meters.",
          "type": "number"
        },
        "duration": {
          "description": "Duration of the leg in seconds.",
          "format": "int64",
          "type": "integer"
        },
        "endTime": {
          "description": "Epoch timestamp (in milliseconds) for the leg's end time.",
          "format": "int64",
          "type": "integer"
        },
        "feedId": {
          "description": "GTFS feed identifier.",
          "type": "string"
        },
        "feedVersionSha1": {
          "description": "SHA-1 hash representing the GTFS feed version.",
          "pattern": "^[0-9a-f]{40}$",
          "type": "string"
        },
        "from": {
          "$ref": "#/$defs/Stop"
        },
        "headsign": {
          "description": "Destination or headsign for the transit leg.",
          "type": "string"
        },
        "intermediateStops": {
          "description": "Optional list of intermediate stops (only present on some transit legs).",
          "items": {
            "$ref": "#/$defs/Stop"
          },
          "type": "array"
        },
        "legGeometry": {
          "$ref": "#/$defs/LegGeometry"
        },
        "mode": {
          "description": "Mode of travel for the leg (e.g., WALK, RAIL).",
          "type": "string"
        },
        "realTime": {
          "description": "Whether a realtime trip update matched the leg's run.",
          "type": "boolean"
        },
        "realtimeDebug": {
          "$ref": "#/$defs/RealtimeDebug"
        },
        "routeColor": {
          "description": "Hex color code for the route.",
          "type": "string"
        },
        "routeId": {
          "description": "Identifier for the route.",
          "type": "string"
        },
        "routeLongName": {
          "description": "Long name/description of the route.",
          "type": "string"
        },
        "routeOnestopId": {
          "description": "One-stop identifier for the route.",
          "type": "string"
        },
        "routeShortName": {
          "description": "Short name of the route.",
          "type": "string"
        },
        "routeTextColor": {
          "description": "Hex text color for the route.",
          "type": "string"
        },
        "routeType": {
          "description": "Type of the transit route (e.g., 1 for rail).",
          "type": "integer"
        },
        "serviceDate": {
          "description": "The run's service date (YYYYMMDD).",
          "type": "string"
        },
        "startTime": {
          "description": "Epoch timestamp (in milliseconds) for the leg's start time.",
          "format": "int64",
          "type": "integer"
        },
        "steps": {
          "description": "List of navigation steps (structure undefined; may be empty).",
          "items": {
            "type": "object"
          },
          "type": "array"
        },
        "to": {
          "$ref": "#/$defs/Stop"
        },
        "transitLeg": {
          "description": "Indicates if the leg is a transit leg.",
          "type": "boolean"
        },
        "tripId": {
          "description": "Identifier for the transit trip.",
          "type": "string"
        }
      },
      "type": "object"
    },
    "LegGeometry": {
      "properties": {
        "length": {
          "description": "Number of points in `points`.",
          "type": "integer"
        },
        "points": {
          "description": "The leg's shape as an encoded polyline, precision 5.",
          "type": "string"
        }
      },
      "type": "object"
    },
    "Location": {
      "properties": {
        "lat": {
          "description": "Latitude coordinate.",
          "format": "double",
          "maximum": 90,
          "minimum": -90,
          "type": "number"
        },
        "lon": {
          "description": "Longitude coordinate.",
          "format": "double",
          "maximum": 180,
          "minimum": -180,
          "type": "number"
        },
        "name": {
          "description": "Name of the location (may be empty).",
          "type": "string"
        }
      },
      "type": "object"
    },
    "Plan": {
      "properties": {
        "date": {
          "description": "Epoch timestamp (in milliseconds) representing the date of the plan.",
          "format": "int64",
          "type": "integer"
        },
        "from": {
          "$ref": "#/$defs/Location"
        },
        "itineraries": {
          "description": "Candidate trips, best first. Empty when no trip was found.",
          "items": {
            "$ref": "#/$defs/Itinerary"
          },
          "type": "array"
        },
        "to": {
          "$ref": "#/$defs/Location"
        }
      },
      "type": "object"
    },
    "RealtimeDebug": {
      "description": "The trip update matched to a leg's run, with `debugRealtime` set.",
      "properties": {
        "delay": {
          "description": "The update's trip-level delay, in seconds.",
          "format": "int32",
          "type": "integer"
        },
        "scheduleRelationship": {
          "description": "The trip descriptor's schedule relationship.",
          "type": "string"
        },
        "startDate": {
          "description": "The trip descriptor's `start_date`, when given.",
          "type": "string"
        },
        "startTime": {
          "description": "The trip descriptor's `start_time`, when given.",
          "type": "string"
        },
        "timestamp": {
          "description": "The update's timestamp, in epoch milliseconds.",
          "format": "int64",
          "type": "integer"
        },
        "tripId": {
          "description": "The trip descriptor's `trip_id`.",
          "type": "string"
        }
      },
      "type": "object"
    },
    "RealtimeStopUpdate": {
      "description": "The stop time update placed at a stop, with `debugRealtime` set.",
      "properties": {
        "scheduleRelationship": {
          "description": "The update's schedule relationship.",
          "type": "string"
        },
        "stopId": {
          "description": "The update's `stop_id`, when given.",
          "type": "string"
        },
        "stopSequence": {
          "description": "The update's `stop_sequence`, when given.",
          "minimum": 0,
          "type": "integer"
        }
      },
      "type": "object"
    },
    "Stop": {
      "properties": {
        "departure": {
          "description": "Epoch timestamp (in milliseconds) for the departure time from this stop.",
          "format": "int64",
          "type": "integer"
        },
        "lat": {
          "description": "Latitude coordinate of the stop.",
          "format": "double",
          "maximum": 90,
          "minimum": -90,
          "type": "number"
        },
        "lon": {
          "description": "Longitude coordinate of the stop.",
          "format": "double",
          "maximum": 180,
          "minimum": -180,
          "type": "number"
        },
        "name": {
          "description": "Stop name (may be empty).",
          "type": "string"
        },
        "realtimeSource": {
          "description": "With `debugRealtime` set: the source of `departure`. `none` is the schedule; `time` and `delay` come from the stop's own update; `carried` is a delay carried from an earlier stop's update or the trip's own delay; `noData` and `skipped` mean the stop's update says NO_DATA or SKIPPED.",
          "enum": [
            "none",
            "time",
            "delay",
            "carried",
            "noData",
            "skipped"
          ],
          "type": "string"
        },
        "realtimeUpdate": {
          "$ref": "#/$defs/RealtimeStopUpdate"
        },
        "scheduledDeparture": {
          "description": "With `debugRealtime` set, on a transit leg's stop whose run a trip update matched: the scheduled departure, in epoch milliseconds.",
          "format": "int64",
          "type": "integer"
        },
        "stopCode": {
          "description": "Stop code.",
          "type": "string"
        },
        "stopId": {
          "description": "Stop identifier.",
          "type": "string"
        },
        "stopIndex": {
          "description": "On a transit leg's stop: the stop's position in the leg's trip, counting from 0.",
          "type": "integer"
        },
        "stopOnestopId": {
          "description": "One-stop identifier for the stop.",
          "type": "string"
        },
        "stopSequence": {
          "description": "On a transit leg's stop: the stop's GTFS `stop_sequence` in the leg's trip.",
          "type": "integer"
        }
      },
      "type": "object"
    },
    "StopArrival": {
      "properties": {
        "earliestArrival": {
          "description": "Earliest arrival time at the stop, as Unix time in seconds.",
          "format": "int64",
          "type": "integer"
        },
        "lat": {
          "description": "Latitude of the stop.",
          "format": "double",
          "maximum": 90,
          "minimum": -90,
          "type": "number"
        },
        "lon": {
          "description": "Longitude of the stop.",
          "format": "double",
          "maximum": 180,
          "minimum": -180,
          "type": "number"
        },
        "stopId": {
          "description": "GTFS stop identifier from the source feed.",
          "type": "string"
        },
        "stopName": {
          "description": "Name of the stop.",
          "type": "string"
        },
        "stop_code": {
          "description": "GTFS stop code, when the feed provides one.",
          "type": "string"
        }
      },
      "type": "object"
    }
  }
}