{
  "components": {
    "responses": {
      "BadRequest": {
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        },
        "description": "The request is invalid (`invalid-request`, `secret-key-in-url`)"
      },
      "Forbidden": {
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        },
        "description": "The key lacks the scope, or the origin is not registered for it (`missing-scope`, `origin-not-allowed`)"
      },
      "InternalError": {
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        },
        "description": "The server failed (`internal`)"
      },
      "TooManyRequests": {
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        },
        "description": "Rate limit or monthly cap reached; see `Retry-After` (`rate-limited`, `monthly-cap-reached`)",
        "headers": {
          "retry-after": {
            "description": "Seconds to wait before retrying.",
            "schema": {
              "type": "integer"
            }
          }
        }
      },
      "Unauthorized": {
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        },
        "description": "No API key, or an unknown or revoked one (`missing-api-key`, `invalid-api-key`)"
      },
      "Unavailable": {
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        },
        "description": "No data version loaded yet, key store unavailable, or timed out; retry (`data-not-loaded`, `key-store-unavailable`, `timeout`)",
        "headers": {
          "retry-after": {
            "description": "Seconds to wait before retrying.",
            "schema": {
              "type": "integer"
            }
          }
        }
      }
    },
    "schemas": {
      "Algorithm": {
        "description": "Which search answered.",
        "enum": [
          "dijkstra",
          "phast"
        ],
        "type": "string"
      },
      "AlongObject": {
        "description": "An object on the route.",
        "properties": {
          "km": {
            "description": "Km along the route (from its start).",
            "format": "double",
            "type": "number"
          },
          "object": {
            "$ref": "#/components/schemas/Feature",
            "description": "The object, as `GET /v1/infra/objects/{id}` answers it."
          }
        },
        "required": [
          "km",
          "object"
        ],
        "type": "object"
      },
      "AlongRouteRequest": {
        "additionalProperties": false,
        "description": "The body of `POST /v1/infra/along-route`: a route as in `POST /v1/route`.",
        "example": {
          "from": {
            "station": "AK"
          },
          "profile": "freight-electric-de",
          "to": {
            "station": "AH"
          },
          "types": [
            "signal",
            "level_crossing"
          ]
        },
        "properties": {
          "avoid": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AvoidInput",
                "description": "Lines and areas the route must not use."
              },
              {
                "type": "null"
              }
            ]
          },
          "from": {
            "$ref": "#/components/schemas/Location"
          },
          "no_reversal": {
            "description": "The train never reverses.",
            "type": "boolean"
          },
          "profile": {
            "description": "A built-in vehicle profile (`GET /v1/route/profiles`).",
            "type": [
              "string",
              "null"
            ]
          },
          "reversal_min": {
            "description": "Minutes a reversal costs (default 20).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "to": {
            "$ref": "#/components/schemas/Location"
          },
          "types": {
            "description": "Object types to list (as `GET /v1/infra/objects`' `types`); empty:\nevery type found on the route's track nodes.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "vehicle": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VehicleInput",
                "description": "Overrides of the profile's vehicle."
              },
              {
                "type": "null"
              }
            ]
          },
          "via": {
            "description": "Places to pass in order (at most 10).",
            "items": {
              "$ref": "#/components/schemas/Location"
            },
            "type": "array"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "type": "object"
      },
      "AlongRouteResponse": {
        "description": "The answer of `POST /v1/infra/along-route`.",
        "properties": {
          "data_version": {
            "type": "string"
          },
          "geometry": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LineString"
              },
              {
                "type": "null"
              }
            ]
          },
          "lines": {
            "description": "The lines in travel order, km along the route.",
            "items": {
              "$ref": "#/components/schemas/LineRun"
            },
            "type": "array"
          },
          "no_route": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/NoRouteOut",
                "description": "Why there is no route (as `POST /v1/route`)."
              },
              {
                "type": "null"
              }
            ]
          },
          "objects": {
            "description": "Infrastructure objects on the route's track nodes, in travel order.",
            "items": {
              "$ref": "#/components/schemas/AlongObject"
            },
            "type": "array"
          },
          "profile": {
            "type": [
              "string",
              "null"
            ]
          },
          "route": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RouteOut",
                "description": "Distance, routing time and legs (as `POST /v1/route`); absent without a route."
              },
              {
                "type": "null"
              }
            ]
          },
          "sections": {
            "description": "Stretches of equal infrastructure and track count in travel order,\nkm along the route; empty without a route.",
            "items": {
              "$ref": "#/components/schemas/TrackSection"
            },
            "type": "array"
          },
          "status": {
            "$ref": "#/components/schemas/RouteStatus"
          },
          "stops": {
            "description": "The places as resolved: from, via …, to.",
            "items": {
              "$ref": "#/components/schemas/ResolvedPlace"
            },
            "type": "array"
          },
          "tracks_method": {
            "description": "How `tracks` is counted.",
            "type": "string"
          },
          "vehicle": {
            "$ref": "#/components/schemas/Vehicle",
            "description": "The effective vehicle."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "data_version",
          "status",
          "stops",
          "vehicle",
          "sections",
          "lines",
          "objects",
          "tracks_method",
          "warnings"
        ],
        "type": "object"
      },
      "AttrChange": {
        "description": "One attribute before and after (null: not set). Tags are strings;\n`geometry` is a `[lon, lat]` point or `{points, length_m}`.",
        "properties": {
          "new": {},
          "old": {}
        },
        "required": [
          "old",
          "new"
        ],
        "type": "object"
      },
      "AvoidInput": {
        "additionalProperties": false,
        "description": "What a route must not use.",
        "properties": {
          "areas": {
            "description": "GeoJSON Polygons or MultiPolygons (bare geometries or Features),\n`[lon, lat]`: track inside or crossing them is avoided.",
            "items": {
              "type": "object"
            },
            "type": "array"
          },
          "lines": {
            "description": "Line numbers (`railway:ref`, e.g. `1720`), compared without spaces and case.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "BandProperties": {
        "description": "The band a feature belongs to.",
        "properties": {
          "bucket": {
            "description": "Its upper edge, in `unit`.",
            "format": "double",
            "type": "number"
          },
          "from": {
            "description": "Its lower edge.",
            "format": "double",
            "type": "number"
          },
          "track_km": {
            "description": "Kilometres of track in the band (network features only).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "unit": {
            "$ref": "#/components/schemas/BucketUnit"
          }
        },
        "required": [
          "bucket",
          "from",
          "unit"
        ],
        "type": "object"
      },
      "BatchItem": {
        "properties": {
          "error": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Problem",
                "description": "With status `error`: the problem `POST /v1/route` would answer with."
              },
              {
                "type": "null"
              }
            ]
          },
          "index": {
            "minimum": 0,
            "type": "integer"
          },
          "route": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/RouteResponse"
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/components/schemas/BatchStatus"
          }
        },
        "required": [
          "index",
          "status"
        ],
        "type": "object"
      },
      "BatchRequest": {
        "additionalProperties": false,
        "description": "Many routes for one vehicle; the options apply to all of them.",
        "example": {
          "profile": "passenger-emu-15kv",
          "routes": [
            {
              "from": {
                "station": "AK"
              },
              "to": {
                "station": "AFL"
              }
            },
            {
              "from": {
                "station": "AK"
              },
              "to": {
                "station": "AL"
              }
            }
          ]
        },
        "properties": {
          "alternatives": {
            "description": "Alternative routes to add (0–3): noticeably different, at most 40 % longer in time.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "avoid": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AvoidInput",
                "description": "Lines and areas the route must not use."
              },
              {
                "type": "null"
              }
            ]
          },
          "charges": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChargesInput",
                "description": "The train of the charges estimate."
              },
              {
                "type": "null"
              }
            ]
          },
          "include": {
            "description": "Parts of each route to include.",
            "items": {
              "$ref": "#/components/schemas/Part"
            },
            "type": "array"
          },
          "no_reversal": {
            "description": "The train never reverses.",
            "type": "boolean"
          },
          "profile": {
            "description": "A built-in vehicle profile (`GET /v1/route/profiles`); default:\nany track of 1,435 mm gauge, a passenger train's characteristics.",
            "type": [
              "string",
              "null"
            ]
          },
          "reversal_min": {
            "description": "Minutes a reversal costs (default 20); trains reverse only near stations.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "routes": {
            "items": {
              "$ref": "#/components/schemas/BatchStops"
            },
            "type": "array"
          },
          "vehicle": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VehicleInput",
                "description": "Overrides of the profile's vehicle."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "routes"
        ],
        "type": "object"
      },
      "BatchResponse": {
        "description": "The answer of `POST /v1/route/batch`, in request order.",
        "properties": {
          "routes": {
            "items": {
              "$ref": "#/components/schemas/BatchItem"
            },
            "type": "array"
          },
          "summary": {
            "$ref": "#/components/schemas/BatchSummary"
          }
        },
        "required": [
          "routes",
          "summary"
        ],
        "type": "object"
      },
      "BatchStatus": {
        "description": "One batch item's outcome.",
        "enum": [
          "ok",
          "no_route",
          "error"
        ],
        "type": "string"
      },
      "BatchStops": {
        "additionalProperties": false,
        "description": "One route of a batch.",
        "properties": {
          "from": {
            "$ref": "#/components/schemas/Location"
          },
          "to": {
            "$ref": "#/components/schemas/Location"
          },
          "via": {
            "items": {
              "$ref": "#/components/schemas/Location"
            },
            "type": "array"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "type": "object"
      },
      "BatchSummary": {
        "properties": {
          "errors": {
            "minimum": 0,
            "type": "integer"
          },
          "no_route": {
            "minimum": 0,
            "type": "integer"
          },
          "ok": {
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "no_route",
          "errors"
        ],
        "type": "object"
      },
      "Binary": {
        "description": "Binary content (a tile, glyphs, an image), for the documentation.",
        "format": "binary",
        "type": "string"
      },
      "BlockerKind": {
        "description": "Kinds of constraint a stretch of track violates.",
        "enum": [
          "electrification",
          "gauge",
          "track_class",
          "gauging",
          "train_protection",
          "avoid_line",
          "avoid_area"
        ],
        "type": "string"
      },
      "BlockerOut": {
        "description": "A stretch of the unconstrained route the vehicle may not use.",
        "properties": {
          "from_km": {
            "description": "Along the unconstrained route.",
            "format": "double",
            "type": "number"
          },
          "geometry": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LineGeometry"
              },
              {
                "type": "null"
              }
            ]
          },
          "kind": {
            "$ref": "#/components/schemas/BlockerKind"
          },
          "line": {
            "description": "Line number; absent for track without one.",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "reason": {
            "description": "E.g. `not electrified (rinf)`.",
            "type": "string"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "kind",
          "reason",
          "from_km",
          "to_km"
        ],
        "type": "object"
      },
      "BorderCrossingOut": {
        "description": "Where the route passes from one country into the next.",
        "properties": {
          "from_country": {
            "type": "string"
          },
          "km": {
            "format": "double",
            "type": "number"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "source": {
            "description": "`osm` (railway=border node), `rinf` (RINF sections meet) or `estimate`.",
            "type": "string"
          },
          "to_country": {
            "type": "string"
          }
        },
        "required": [
          "from_country",
          "to_country",
          "km",
          "lon",
          "lat",
          "source"
        ],
        "type": "object"
      },
      "BucketUnit": {
        "description": "The unit of the buckets.",
        "enum": [
          "minutes",
          "km"
        ],
        "type": "string"
      },
      "CalibrationError": {
        "description": "Leave-one-out errors of the km markers (m).",
        "properties": {
          "max": {
            "format": "double",
            "type": "number"
          },
          "p95": {
            "format": "double",
            "type": "number"
          },
          "rms": {
            "format": "double",
            "type": "number"
          },
          "samples": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "rms",
          "p95",
          "max",
          "samples"
        ],
        "type": "object"
      },
      "CalibrationGap": {
        "description": "A stretch of a line with weaker km.",
        "properties": {
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "kind": {
            "description": "`missing_geometry`, `no_markers` (over 2 km between markers), `extrapolated`.",
            "type": "string"
          },
          "length_m": {
            "format": "double",
            "type": "number"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "kind",
          "from_km",
          "to_km",
          "length_m"
        ],
        "type": "object"
      },
      "CapacityOut": {
        "description": "Capacity indicators along the route: only what the data has.",
        "properties": {
          "line_categories": {
            "items": {
              "$ref": "#/components/schemas/CategoryStretchOut"
            },
            "type": "array"
          },
          "note": {
            "type": "string"
          },
          "stretches": {
            "items": {
              "$ref": "#/components/schemas/CapacityStretchOut"
            },
            "type": "array"
          },
          "summary": {
            "$ref": "#/components/schemas/CapacitySummaryOut"
          }
        },
        "required": [
          "stretches",
          "line_categories",
          "summary",
          "note"
        ],
        "type": "object"
      },
      "CapacityStretchOut": {
        "description": "A stretch with one number of tracks.",
        "properties": {
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "layout": {
            "description": "`single`, `double`, `multiple` or `unknown`.",
            "type": "string"
          },
          "max_speed_kmh": {
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "min_speed_kmh": {
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "source": {
            "description": "`rinf`, `osm` or `unknown`.",
            "type": "string"
          },
          "speed_known_km": {
            "format": "double",
            "type": "number"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          },
          "tracks": {
            "description": "0 = unknown.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "from_km",
          "to_km",
          "distance_km",
          "tracks",
          "layout",
          "source",
          "speed_known_km"
        ],
        "type": "object"
      },
      "CapacitySummaryOut": {
        "properties": {
          "by_line_category": {
            "items": {
              "$ref": "#/components/schemas/CategoryKmOut"
            },
            "type": "array"
          },
          "double_track_km": {
            "format": "double",
            "type": "number"
          },
          "multiple_track_km": {
            "format": "double",
            "type": "number"
          },
          "single_track_km": {
            "format": "double",
            "type": "number"
          },
          "single_track_share": {
            "description": "Of the km with a known number of tracks.",
            "format": "double",
            "type": "number"
          },
          "unknown_tracks_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "single_track_km",
          "double_track_km",
          "multiple_track_km",
          "unknown_tracks_km",
          "single_track_share",
          "by_line_category"
        ],
        "type": "object"
      },
      "CategoryKmOut": {
        "properties": {
          "category": {
            "type": "string"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "category",
          "distance_km"
        ],
        "type": "object"
      },
      "CategoryStretchOut": {
        "description": "A stretch with one RINF TSI line category.",
        "properties": {
          "category": {
            "description": "As in RINF (`P4;F1`), or `unknown`.",
            "type": "string"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "source": {
            "type": "string"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "from_km",
          "to_km",
          "distance_km",
          "category",
          "source"
        ],
        "type": "object"
      },
      "CellStatus": {
        "description": "What a cell says.",
        "enum": [
          "ok",
          "blocked",
          "not_connected",
          "same_location"
        ],
        "type": "string"
      },
      "ChangeOut": {
        "description": "A change of electrification or train protection system.",
        "properties": {
          "from": {
            "description": "E.g. `15 kV 16.7 Hz`, `LZB+PZB`, `none`, `unknown`.",
            "type": "string"
          },
          "kind": {
            "description": "`electrification` or `train_protection`.",
            "type": "string"
          },
          "km": {
            "format": "double",
            "type": "number"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "to": {
            "type": "string"
          }
        },
        "required": [
          "km",
          "kind",
          "from",
          "to",
          "lon",
          "lat"
        ],
        "type": "object"
      },
      "ChangeVersion": {
        "description": "One version of the feed's range with its counts (unfiltered).",
        "properties": {
          "added": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "changed": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "created": {
            "description": "When it was built (RFC 3339).",
            "type": [
              "string",
              "null"
            ]
          },
          "previous": {
            "description": "The version its changes are against (\"\" for the first).",
            "type": "string"
          },
          "removed": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "version",
          "previous",
          "added",
          "removed",
          "changed"
        ],
        "type": "object"
      },
      "ChangesResponse": {
        "description": "The answer of `GET /v1/changes`.",
        "properties": {
          "attribution": {
            "type": "string"
          },
          "changes": {
            "items": {
              "$ref": "#/components/schemas/FeedChange"
            },
            "type": "array"
          },
          "data_version": {
            "type": "string"
          },
          "limit": {
            "minimum": 0,
            "type": "integer"
          },
          "next_cursor": {
            "description": "More changes: pass this as `cursor` (with the same query).",
            "type": [
              "string",
              "null"
            ]
          },
          "returned": {
            "minimum": 0,
            "type": "integer"
          },
          "versions": {
            "items": {
              "$ref": "#/components/schemas/ChangeVersion"
            },
            "type": "array"
          }
        },
        "required": [
          "versions",
          "changes",
          "returned",
          "limit",
          "data_version",
          "attribution"
        ],
        "type": "object"
      },
      "ChargeAppliedOut": {
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "description": "`percent` or `per_train_km`.",
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "per_train_km": {
            "description": "Its effect on the price.",
            "format": "double",
            "type": "number"
          },
          "value": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "value",
          "per_train_km"
        ],
        "type": "object"
      },
      "ChargeGapOut": {
        "properties": {
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "im": {
            "type": "string"
          },
          "im_code": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          }
        },
        "required": [
          "im",
          "distance_km",
          "reason"
        ],
        "type": "object"
      },
      "ChargeSourceOut": {
        "description": "Where a price table's figures come from.",
        "properties": {
          "published": {
            "type": "string"
          },
          "retrieved": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "title",
          "url",
          "retrieved"
        ],
        "type": "object"
      },
      "ChargeStretchOut": {
        "description": "A stretch on one IM's track and its estimate.",
        "properties": {
          "adjustments": {
            "items": {
              "$ref": "#/components/schemas/ChargeAppliedOut"
            },
            "type": "array"
          },
          "amount": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "base_price_per_train_km": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "currency": {
            "type": "string"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "estimated": {
            "type": "boolean"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "im": {
            "type": "string"
          },
          "im_code": {
            "type": "string"
          },
          "im_source": {
            "type": "string"
          },
          "needs_review": {
            "type": "boolean"
          },
          "price_per_train_km": {
            "description": "Base plus adjustments.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "reason": {
            "description": "Why not.",
            "type": "string"
          },
          "segment": {
            "type": "string"
          },
          "segment_name": {
            "type": "string"
          },
          "source": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChargeSourceOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "table": {
            "type": "string"
          },
          "table_version": {
            "type": "string"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          },
          "unit": {
            "type": "string"
          }
        },
        "required": [
          "im",
          "im_source",
          "from_km",
          "to_km",
          "distance_km",
          "estimated"
        ],
        "type": "object"
      },
      "ChargeTableOut": {
        "description": "A price table the estimate used.",
        "properties": {
          "currency": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "im": {
            "type": "string"
          },
          "im_code": {
            "type": "string"
          },
          "needs_review": {
            "type": "boolean"
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/ChargeSourceOut"
            },
            "type": "array"
          },
          "status": {
            "description": "`approved` or `provisional`.",
            "type": "string"
          },
          "timetable_year": {
            "format": "int32",
            "type": "integer"
          },
          "unit": {
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "im_code",
          "im",
          "timetable_year",
          "version",
          "status",
          "currency",
          "unit",
          "needs_review",
          "sources",
          "notes"
        ],
        "type": "object"
      },
      "ChargeTotalOut": {
        "properties": {
          "amount": {
            "format": "double",
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "estimated_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "currency",
          "amount",
          "estimated_km"
        ],
        "type": "object"
      },
      "ChargeTrainType": {
        "description": "Market segment of the charges estimate.",
        "enum": [
          "freight",
          "light_engine",
          "passenger"
        ],
        "type": "string"
      },
      "ChargesInput": {
        "additionalProperties": false,
        "description": "The train the charges are estimated for (implies `include: charges`).",
        "properties": {
          "adjustments": {
            "description": "Adjustment ids to apply instead of the tables' defaults (`[]`: none).",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "date": {
            "description": "`YYYY-MM-DD`.",
            "type": [
              "string",
              "null"
            ]
          },
          "gross_weight_t": {
            "description": "Gross (wagon train) weight (t); default the vehicle's mass, else typical.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "segment": {
            "description": "A segment id of the price tables, instead of train type and weight.",
            "type": [
              "string",
              "null"
            ]
          },
          "timetable_year": {
            "description": "The timetable year; default the one `date` (or today) falls in.",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "train_type": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChargeTrainType",
                "description": "Default freight."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "type": "object"
      },
      "ChargesOut": {
        "description": "Estimated track access charges.",
        "properties": {
          "complete": {
            "description": "Every km estimated.",
            "type": "boolean"
          },
          "currency": {
            "type": "string"
          },
          "disclaimer": {
            "type": "string"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "estimate": {
            "description": "Always true.",
            "type": "boolean"
          },
          "estimated_km": {
            "format": "double",
            "type": "number"
          },
          "gross_weight_source": {
            "description": "`charges`, `vehicle` or `typical`.",
            "type": "string"
          },
          "gross_weight_t": {
            "format": "double",
            "type": "number"
          },
          "needs_review": {
            "description": "A table used is marked needs_review.",
            "type": "boolean"
          },
          "not_estimated": {
            "items": {
              "$ref": "#/components/schemas/ChargeGapOut"
            },
            "type": "array"
          },
          "not_estimated_km": {
            "format": "double",
            "type": "number"
          },
          "segment": {
            "type": "string"
          },
          "stretches": {
            "items": {
              "$ref": "#/components/schemas/ChargeStretchOut"
            },
            "type": "array"
          },
          "tables": {
            "items": {
              "$ref": "#/components/schemas/ChargeTableOut"
            },
            "type": "array"
          },
          "timetable_period_from": {
            "type": "string"
          },
          "timetable_period_to": {
            "type": "string"
          },
          "timetable_year": {
            "format": "int32",
            "type": "integer"
          },
          "timetable_year_source": {
            "description": "`timetable_year`, `date` or `today`.",
            "type": "string"
          },
          "total": {
            "description": "With one currency.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "totals": {
            "items": {
              "$ref": "#/components/schemas/ChargeTotalOut"
            },
            "type": "array"
          },
          "train_type": {
            "$ref": "#/components/schemas/ChargeTrainType"
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "estimate",
          "disclaimer",
          "timetable_year",
          "timetable_year_source",
          "timetable_period_from",
          "timetable_period_to",
          "train_type",
          "gross_weight_t",
          "gross_weight_source",
          "totals",
          "distance_km",
          "estimated_km",
          "not_estimated_km",
          "complete",
          "stretches",
          "not_estimated",
          "tables",
          "needs_review",
          "warnings"
        ],
        "type": "object"
      },
      "CodeMatch": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PlaceOut"
          },
          {
            "properties": {
              "matched_as": {
                "description": "Which kind of code matched: `ds100`, `uopid` or `uic`.",
                "type": "string"
              }
            },
            "required": [
              "matched_as"
            ],
            "type": "object"
          }
        ],
        "description": "A place found by its code."
      },
      "CodeMatches": {
        "description": "A page of places with a code.",
        "properties": {
          "next_cursor": {
            "description": "The cursor of the next page; `null` on the last.",
            "type": [
              "string",
              "null"
            ]
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/CodeMatch"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "type": "object"
      },
      "CountryOut": {
        "description": "A stretch of the route in one country.",
        "properties": {
          "country": {
            "description": "ISO 3166-1 alpha-2, or `unknown`.",
            "type": "string"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "source": {
            "description": "`rinf`, `osm` (operator), `stations` (nearest station) or `unknown`.",
            "type": "string"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "country",
          "from_km",
          "to_km",
          "distance_km",
          "source"
        ],
        "type": "object"
      },
      "DatasetInfo": {
        "description": "The data version being served.",
        "example": {
          "built_at": "2026-11-05T02:00:00Z",
          "edges": 402118,
          "format": 1,
          "nodes": 1843211,
          "segments": 2101532,
          "stale": false,
          "version": "20261105-0200"
        },
        "properties": {
          "built_at": {
            "description": "When the version was built (RFC 3339, UTC), if known.",
            "type": [
              "string",
              "null"
            ]
          },
          "edges": {
            "description": "Compressed edges (track between junctions).",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "format": {
            "description": "The artifact format.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "nodes": {
            "description": "Track nodes in the network.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "segments": {
            "description": "Track segments.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "stale": {
            "description": "Served from the local cache because the data store is unreachable.",
            "type": "boolean"
          },
          "version": {
            "description": "The data version; every response names it in `X-Data-Version`.",
            "type": "string"
          }
        },
        "required": [
          "version",
          "format",
          "stale",
          "nodes",
          "edges",
          "segments"
        ],
        "type": "object"
      },
      "DeliveryView": {
        "description": "A delivery's state.",
        "properties": {
          "attempts": {
            "format": "int32",
            "type": "integer"
          },
          "created_at": {
            "type": "string"
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "event": {
            "description": "`changes` or `test`.",
            "type": "string"
          },
          "id": {
            "description": "`dlv_…`, also in the event's `id` and the `Railroute-Delivery` header.",
            "type": "string"
          },
          "last_attempt_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_status": {
            "description": "HTTP status of the last attempt.",
            "format": "int32",
            "type": [
              "integer",
              "null"
            ]
          },
          "next_attempt_at": {
            "description": "While pending.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "description": "`pending`, `delivered` or `failed`.",
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "event",
          "version",
          "status",
          "attempts",
          "created_at"
        ],
        "type": "object"
      },
      "ElecKeyword": {
        "enum": [
          "any",
          "none"
        ],
        "type": "string"
      },
      "ElecSystemSpec": {
        "additionalProperties": false,
        "description": "One electrification system the vehicle can draw power from.",
        "properties": {
          "frequency_hz": {
            "description": "Hz, 0 = DC; absent: any.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "voltage_v": {
            "description": "Volts; absent or 0: any.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "Electrification": {
        "description": "`\"any\"` (any electrified track), `\"none\"` (no electrification needed)\nor the systems the vehicle supports (any one suffices).",
        "oneOf": [
          {
            "$ref": "#/components/schemas/ElecKeyword"
          },
          {
            "items": {
              "$ref": "#/components/schemas/ElecSystemSpec"
            },
            "type": "array"
          }
        ]
      },
      "EstimateOut": {
        "description": "The estimated running time of a route: an estimate, not a timetable.",
        "properties": {
          "avg_speed_kmh": {
            "format": "double",
            "type": "number"
          },
          "dwell_min": {
            "format": "double",
            "type": "number"
          },
          "gradients": {
            "$ref": "#/components/schemas/GradientsOut"
          },
          "is_estimate": {
            "description": "Always true.",
            "type": "boolean"
          },
          "method": {
            "type": "string"
          },
          "note": {
            "type": "string"
          },
          "reversal_min": {
            "format": "double",
            "type": "number"
          },
          "running_min": {
            "format": "double",
            "type": "number"
          },
          "segments": {
            "description": "Per section (with `sections`).",
            "items": {
              "$ref": "#/components/schemas/RunSegmentOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "speed_profile": {
            "description": "`[km, km/h, limit km/h]` where the speed changes phase or by 2 km/h.",
            "items": {
              "items": {
                "format": "double",
                "type": "number"
              },
              "type": "array"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "stops": {
            "description": "Halts between start and end (stops at via points, reversals).",
            "minimum": 0,
            "type": "integer"
          },
          "top_speed_kmh": {
            "format": "double",
            "type": "number"
          },
          "total_min": {
            "description": "Running + dwell + reversal.",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "is_estimate",
          "total_min",
          "running_min",
          "dwell_min",
          "reversal_min",
          "stops",
          "avg_speed_kmh",
          "top_speed_kmh",
          "method",
          "note",
          "gradients"
        ],
        "type": "object"
      },
      "Feature": {
        "description": "An infrastructure object as a GeoJSON Feature.",
        "properties": {
          "geometry": {
            "$ref": "#/components/schemas/Geometry"
          },
          "id": {
            "description": "The object's ID.",
            "type": "string"
          },
          "properties": {
            "$ref": "#/components/schemas/ObjectProperties"
          },
          "type": {
            "description": "Always `Feature`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "id",
          "geometry",
          "properties"
        ],
        "type": "object"
      },
      "FeaturePage": {
        "description": "A page of objects: a GeoJSON FeatureCollection.",
        "properties": {
          "features": {
            "description": "The objects, in ID order.",
            "items": {
              "$ref": "#/components/schemas/Feature"
            },
            "type": "array"
          },
          "next_cursor": {
            "description": "The cursor of the next page; `null` on the last.",
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "description": "Always `FeatureCollection`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "features"
        ],
        "type": "object"
      },
      "FeedChange": {
        "description": "A change with the version it came with.",
        "properties": {
          "attributes": {
            "additionalProperties": {
              "$ref": "#/components/schemas/AttrChange"
            },
            "description": "changed: the attributes that differ; added: all (old null); removed: all (new null).",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "bbox": {
            "description": "minLon, minLat, maxLon, maxLat.",
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": "array"
          },
          "change": {
            "description": "`added`, `removed` or `changed`.",
            "type": "string"
          },
          "id": {
            "description": "The object, as in the infrastructure API: `way/…`, `node/…`, `rinf-op/…`.",
            "type": "string"
          },
          "lines": {
            "description": "Line refs of the track way, or of the track through the object.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "name": {
            "type": "string"
          },
          "point": {
            "description": "lon, lat on the object (new version; removed: old).",
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": "array"
          },
          "type": {
            "description": "Object type (`track`, `signal`, …).",
            "type": "string"
          },
          "version": {
            "type": "string"
          }
        },
        "required": [
          "version",
          "id",
          "type",
          "change",
          "lines",
          "point",
          "bbox",
          "attributes"
        ],
        "type": "object"
      },
      "Geometry": {
        "description": "A GeoJSON geometry: `Point`, `LineString` or `Polygon`.",
        "properties": {
          "coordinates": {
            "description": "GeoJSON coordinates ([lon, lat], 7 decimals).",
            "type": "object"
          },
          "type": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "coordinates"
        ],
        "type": "object"
      },
      "GradientsOut": {
        "description": "Whether the estimate knew the gradients.",
        "properties": {
          "known": {
            "type": "boolean"
          },
          "note": {
            "type": "string"
          }
        },
        "required": [
          "known",
          "note"
        ],
        "type": "object"
      },
      "Health": {
        "description": "`GET /healthz`.",
        "properties": {
          "status": {
            "description": "Always `ok`.",
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "type": "object"
      },
      "ImDistanceOut": {
        "description": "The distance on one infrastructure manager's track.",
        "properties": {
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "im": {
            "type": "string"
          },
          "im_code": {
            "type": "string"
          },
          "share": {
            "description": "Of the route's length.",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "im",
          "distance_km",
          "share"
        ],
        "type": "object"
      },
      "ImOut": {
        "description": "A stretch of the route with one infrastructure manager.",
        "properties": {
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "im": {
            "description": "Name, or `unknown`.",
            "type": "string"
          },
          "im_code": {
            "type": "string"
          },
          "source": {
            "description": "`rinf`, `osm` (operator tag) or `unknown`.",
            "type": "string"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "im",
          "source",
          "from_km",
          "to_km",
          "distance_km"
        ],
        "type": "object"
      },
      "InfraMatch": {
        "description": "An infrastructure search result.",
        "properties": {
          "category": {
            "description": "The search category (`siding`, `yard`, …).",
            "type": "string"
          },
          "id": {
            "description": "The object: `GET /v1/infra/objects/{id}`.",
            "type": "string"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "object_ids": {
            "description": "Every object merged into this result (the ways of one tunnel), the first being `id`.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "object_type": {
            "description": "The object's type in `/v1/infra/objects` (a siding is a `track`).",
            "type": "string"
          },
          "ref": {
            "type": [
              "string",
              "null"
            ]
          },
          "score": {
            "description": "Higher is better.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "source": {
            "description": "`osm`, `rinf` or `osm+rinf`.",
            "type": "string"
          }
        },
        "required": [
          "id",
          "category",
          "object_type",
          "lat",
          "lon",
          "source",
          "score",
          "object_ids"
        ],
        "type": "object"
      },
      "InfraMatches": {
        "description": "A page of infrastructure search results.",
        "properties": {
          "next_cursor": {
            "description": "The cursor of the next page; `null` on the last.",
            "type": [
              "string",
              "null"
            ]
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/InfraMatch"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "type": "object"
      },
      "IsoStation": {
        "description": "A station or RINF operational point within reach (one within 300 m of\nthe track reached, as `POST /v1/route` lists the places it passes).",
        "properties": {
          "bucket": {
            "description": "The band: its upper edge.",
            "format": "double",
            "type": "number"
          },
          "distance_m": {
            "description": "Its length (m).",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "ds100": {
            "type": "string"
          },
          "duration_s": {
            "description": "Running time of the route there (s).",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "kind": {
            "type": "string"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "uic": {
            "type": "string"
          },
          "uopid": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "kind",
          "lat",
          "lon",
          "duration_s",
          "distance_m",
          "bucket"
        ],
        "type": "object"
      },
      "IsochroneRequest": {
        "additionalProperties": false,
        "description": "The body of `POST /v1/isochrone`.",
        "example": {
          "buckets": [
            60,
            120
          ],
          "max_minutes": 120,
          "origin": {
            "station": "AH"
          },
          "polygons": true,
          "profile": "passenger-emu-15kv"
        },
        "properties": {
          "avoid": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AvoidInput",
                "description": "Lines and areas not to use, as in `POST /v1/route`."
              },
              {
                "type": "null"
              }
            ]
          },
          "bucket_unit": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/BucketUnit",
                "description": "Absent: minutes if `max_minutes` is given, else km."
              },
              {
                "type": "null"
              }
            ]
          },
          "buckets": {
            "description": "Upper edges of the bands in `bucket_unit`, ascending (at most 10);\nthe last is the outer limit. Absent: one band up to the limit.",
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "max_km": {
            "description": "Distance limit (km, at most 1,000).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_minutes": {
            "description": "Time limit (minutes, at most 720).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_stations": {
            "description": "Stations listed at most (default 500, at most 5,000).",
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "no_reversal": {
            "description": "The train never reverses.",
            "type": "boolean"
          },
          "origin": {
            "$ref": "#/components/schemas/Location",
            "description": "A place, as in `POST /v1/route` (`station`, `lon` + `lat`, or `osm_node`)."
          },
          "polygons": {
            "description": "Also return polygons around the track reached (an approximation).",
            "type": "boolean"
          },
          "profile": {
            "description": "A built-in vehicle profile (`GET /v1/route/profiles`); default: any\ntrack of 1,435 mm gauge.",
            "type": [
              "string",
              "null"
            ]
          },
          "reversal_min": {
            "description": "Minutes a reversal costs (default 20); trains reverse only near stations.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "vehicle": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VehicleInput",
                "description": "Overrides of the profile's vehicle, as in `POST /v1/route`."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "origin"
        ],
        "type": "object"
      },
      "IsochroneResult": {
        "description": "The answer of `POST /v1/isochrone`.",
        "properties": {
          "algorithm": {
            "$ref": "#/components/schemas/Algorithm"
          },
          "bucket_unit": {
            "$ref": "#/components/schemas/BucketUnit"
          },
          "buckets": {
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": "array"
          },
          "data_version": {
            "type": "string"
          },
          "max_km": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_minutes": {
            "description": "The effective limits.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "network": {
            "$ref": "#/components/schemas/LineCollection",
            "description": "One `MultiLineString` per band: the track reached in it, the last\nstretch cut at the limit."
          },
          "origin": {
            "$ref": "#/components/schemas/ResolvedPlace",
            "description": "The origin as resolved, with where it meets usable track."
          },
          "polygons": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PolygonCollection",
                "description": "With `polygons`: per band the area within about 2 km of the track\nreached up to it."
              },
              {
                "type": "null"
              }
            ]
          },
          "profile": {
            "description": "The built-in profile used, if any.",
            "type": [
              "string",
              "null"
            ]
          },
          "stations": {
            "description": "Nearest first (in the bucket unit), one per name.",
            "items": {
              "$ref": "#/components/schemas/IsoStation"
            },
            "type": "array"
          },
          "stations_truncated": {
            "type": "boolean"
          },
          "vehicle": {
            "$ref": "#/components/schemas/Vehicle",
            "description": "The effective vehicle."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "data_version",
          "origin",
          "vehicle",
          "bucket_unit",
          "buckets",
          "algorithm",
          "network",
          "stations",
          "stations_truncated",
          "warnings"
        ],
        "type": "object"
      },
      "JobStatus": {
        "description": "Where a job is.",
        "enum": [
          "queued",
          "running",
          "done",
          "failed"
        ],
        "type": "string"
      },
      "KmAccuracy": {
        "description": "How well a km value is known.",
        "properties": {
          "class": {
            "description": "`interpolated` (between km markers), `extrapolated` (beyond the\nfirst/last marker), `near_km_jump`, `missing_geometry`.",
            "type": "string"
          },
          "estimated_error_m": {
            "description": "Estimated error of the km (m).",
            "format": "double",
            "type": "number"
          },
          "nearest_marker_m": {
            "description": "Distance to the nearest km marker used (m).",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "class",
          "nearest_marker_m",
          "estimated_error_m"
        ],
        "type": "object"
      },
      "KmJump": {
        "description": "A km jump (\"Kilometersprung\"): the km changes abruptly here.",
        "properties": {
          "km_after": {
            "format": "double",
            "type": "number"
          },
          "km_before": {
            "format": "double",
            "type": "number"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "located": {
            "description": "`marker`: a stone shows both km; `estimated`: midway between the markers either side.",
            "type": "string"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "uncertain_m": {
            "description": "How far off the position may be (m).",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "km_before",
          "km_after",
          "lat",
          "lon",
          "located",
          "uncertain_m"
        ],
        "type": "object"
      },
      "KmPosition": {
        "description": "A point at a km of a line.",
        "properties": {
          "accuracy": {
            "$ref": "#/components/schemas/KmAccuracy"
          },
          "bearing_deg": {
            "description": "The direction of increasing km there.",
            "format": "double",
            "type": "number"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "lat",
          "lon",
          "bearing_deg",
          "accuracy"
        ],
        "type": "object"
      },
      "KmRangeOut": {
        "description": "A km range.",
        "properties": {
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "from_km",
          "to_km"
        ],
        "type": "object"
      },
      "LegEstimateOut": {
        "properties": {
          "reversal_min": {
            "format": "double",
            "type": "number"
          },
          "running_min": {
            "format": "double",
            "type": "number"
          },
          "total_min": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "total_min",
          "running_min",
          "reversal_min"
        ],
        "type": "object"
      },
      "LegOut": {
        "description": "One leg: from a place to the next.",
        "properties": {
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "duration_min": {
            "description": "Running time at min(line speed, max speed), plus reversals.",
            "format": "double",
            "type": "number"
          },
          "estimate": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LegEstimateOut",
                "description": "The leg's share of the estimate (with `estimate`)."
              },
              {
                "type": "null"
              }
            ]
          },
          "from": {
            "description": "Index into `stops`.",
            "minimum": 0,
            "type": "integer"
          },
          "reversals": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "to": {
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "from",
          "to",
          "distance_km",
          "duration_min",
          "reversals"
        ],
        "type": "object"
      },
      "LineCalibration": {
        "description": "How well a line's km are calibrated.",
        "properties": {
          "coverage": {
            "description": "Share of the line within 2 km of a marker on both sides.",
            "format": "double",
            "type": "number"
          },
          "error_m": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CalibrationError"
              },
              {
                "type": "null"
              }
            ]
          },
          "gaps": {
            "items": {
              "$ref": "#/components/schemas/CalibrationGap"
            },
            "type": "array"
          },
          "km_jumps": {
            "items": {
              "$ref": "#/components/schemas/KmJump"
            },
            "type": "array"
          },
          "km_ranges": {
            "description": "The km covered, per continuous piece of the line.",
            "items": {
              "$ref": "#/components/schemas/KmRangeOut"
            },
            "type": "array"
          },
          "length_km": {
            "format": "double",
            "type": "number"
          },
          "markers": {
            "description": "Km markers near the line, and those used.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "markers_used": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "note": {
            "description": "The same in words.",
            "type": "string"
          },
          "quality": {
            "description": "`good`, `fair` or `poor`.",
            "type": "string"
          }
        },
        "required": [
          "quality",
          "note",
          "markers",
          "markers_used",
          "length_km",
          "km_ranges",
          "km_jumps",
          "gaps",
          "coverage"
        ],
        "type": "object"
      },
      "LineCollection": {
        "description": "GeoJSON `FeatureCollection` of lines.",
        "properties": {
          "features": {
            "items": {
              "$ref": "#/components/schemas/LineFeature"
            },
            "type": "array"
          },
          "type": {
            "description": "`FeatureCollection`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "features"
        ],
        "type": "object"
      },
      "LineFeature": {
        "description": "A GeoJSON feature: the track of one band.",
        "properties": {
          "geometry": {
            "$ref": "#/components/schemas/MultiLineString"
          },
          "properties": {
            "$ref": "#/components/schemas/BandProperties"
          },
          "type": {
            "description": "`Feature`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "properties",
          "geometry"
        ],
        "type": "object"
      },
      "LineGeometry": {
        "description": "A GeoJSON LineString.",
        "properties": {
          "coordinates": {
            "description": "`[lon, lat]` positions, 6 decimals.",
            "items": {
              "items": {
                "format": "double",
                "type": "number"
              },
              "type": "array"
            },
            "type": "array"
          },
          "type": {
            "description": "Always `LineString`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "coordinates"
        ],
        "type": "object"
      },
      "LineInfra": {
        "description": "A line's infrastructure.",
        "properties": {
          "calibration": {
            "$ref": "#/components/schemas/LineCalibration"
          },
          "gradients_known": {
            "description": "Gradients are not in the data (OSM rarely maps them, the RINF attributes fetched have none).",
            "type": "boolean"
          },
          "length_m": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "description": "Line number.",
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "operator": {
            "type": [
              "string",
              "null"
            ]
          },
          "pieces": {
            "items": {
              "$ref": "#/components/schemas/LinePiece"
            },
            "type": "array"
          },
          "tracks_method": {
            "description": "How `tracks` is counted.",
            "type": "string"
          }
        },
        "required": [
          "line",
          "length_m",
          "pieces",
          "tracks_method",
          "gradients_known",
          "calibration"
        ],
        "type": "object"
      },
      "LineKm": {
        "description": "A line near the point and the point's km on it.",
        "properties": {
          "accuracy": {
            "$ref": "#/components/schemas/KmAccuracy"
          },
          "calibration": {
            "$ref": "#/components/schemas/LineCalibration"
          },
          "distance_m": {
            "description": "From the point to the line (m).",
            "format": "double",
            "type": "number"
          },
          "km": {
            "format": "double",
            "type": "number"
          },
          "lat": {
            "description": "The point projected onto the line.",
            "format": "double",
            "type": "number"
          },
          "line": {
            "type": "string"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "offset_m": {
            "description": "Right (+) or left (−) of the line in the direction of increasing km (m).",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "line",
          "km",
          "offset_m",
          "distance_m",
          "lat",
          "lon",
          "accuracy",
          "calibration"
        ],
        "type": "object"
      },
      "LineKms": {
        "description": "A page of lines near a point.",
        "properties": {
          "next_cursor": {
            "description": "The cursor of the next page; `null` on the last.",
            "type": [
              "string",
              "null"
            ]
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/LineKm"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "type": "object"
      },
      "LineOut": {
        "description": "A stretch of the route on one line, in travel order (under 200 m and\ntrack without a line number left out).",
        "properties": {
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "type": "string"
          },
          "name": {
            "description": "The OSM line relation's name, where linear referencing knows it.",
            "type": "string"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "line",
          "from_km",
          "to_km"
        ],
        "type": "object"
      },
      "LinePiece": {
        "description": "One continuous piece of a line (a calibrated chain, or the km range asked for).",
        "properties": {
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "geometry": {
            "$ref": "#/components/schemas/LineString"
          },
          "km_jumps": {
            "items": {
              "$ref": "#/components/schemas/KmJump"
            },
            "type": "array"
          },
          "length_m": {
            "format": "double",
            "type": "number"
          },
          "sections": {
            "description": "Stretches of equal infrastructure and track count, in line km.",
            "items": {
              "$ref": "#/components/schemas/TrackSection"
            },
            "type": "array"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "from_km",
          "to_km",
          "length_m",
          "geometry",
          "sections",
          "km_jumps"
        ],
        "type": "object"
      },
      "LinePosition": {
        "description": "The points at a km of a line.",
        "properties": {
          "calibration": {
            "$ref": "#/components/schemas/LineCalibration"
          },
          "km": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "offset_m": {
            "format": "double",
            "type": "number"
          },
          "positions": {
            "description": "Usually one; several where a km jump repeats a range of km.",
            "items": {
              "$ref": "#/components/schemas/KmPosition"
            },
            "type": "array"
          }
        },
        "required": [
          "line",
          "km",
          "offset_m",
          "positions",
          "calibration"
        ],
        "type": "object"
      },
      "LineRun": {
        "description": "A line passed along a route or matched path.",
        "properties": {
          "from_km": {
            "description": "Km along the path (not line km).",
            "format": "double",
            "type": "number"
          },
          "line": {
            "description": "Line number.",
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "line",
          "from_km",
          "to_km"
        ],
        "type": "object"
      },
      "LineSegment": {
        "description": "The stretch of a line between two km.",
        "properties": {
          "calibration": {
            "$ref": "#/components/schemas/LineCalibration"
          },
          "from": {
            "$ref": "#/components/schemas/KmPosition"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "geometry": {
            "$ref": "#/components/schemas/LineString",
            "description": "From `from_km` to `to_km`."
          },
          "km_jumps_crossed": {
            "items": {
              "$ref": "#/components/schemas/KmJump"
            },
            "type": "array"
          },
          "length_m": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "sections": {
            "description": "Stretches of equal infrastructure, in line km, in travel order.",
            "items": {
              "$ref": "#/components/schemas/TrackSection"
            },
            "type": "array"
          },
          "to": {
            "$ref": "#/components/schemas/KmPosition"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "line",
          "from_km",
          "to_km",
          "length_m",
          "geometry",
          "sections",
          "from",
          "to",
          "km_jumps_crossed",
          "calibration"
        ],
        "type": "object"
      },
      "LineString": {
        "description": "A GeoJSON LineString.",
        "properties": {
          "coordinates": {
            "description": "[lon, lat] pairs, 6 decimals.",
            "items": {
              "items": {
                "format": "double",
                "type": "number"
              },
              "type": "array"
            },
            "type": "array"
          },
          "type": {
            "description": "Always `LineString`.",
            "example": "LineString",
            "type": "string"
          }
        },
        "required": [
          "type",
          "coordinates"
        ],
        "type": "object"
      },
      "LineSummaries": {
        "description": "A page of lines.",
        "properties": {
          "next_cursor": {
            "description": "The cursor of the next page; `null` on the last.",
            "type": [
              "string",
              "null"
            ]
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/LineSummary"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "type": "object"
      },
      "LineSummary": {
        "description": "A calibrated line.",
        "properties": {
          "km_ranges": {
            "description": "The km covered, per continuous piece.",
            "items": {
              "$ref": "#/components/schemas/KmRangeOut"
            },
            "type": "array"
          },
          "length_km": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "description": "Line number.",
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "operator": {
            "type": [
              "string",
              "null"
            ]
          },
          "quality": {
            "description": "`good`, `fair` or `poor` (see `calibration` of the other endpoints).",
            "type": "string"
          }
        },
        "required": [
          "line",
          "quality",
          "length_km",
          "km_ranges"
        ],
        "type": "object"
      },
      "Location": {
        "additionalProperties": false,
        "description": "A place: give exactly one of `station`, `lon` + `lat`, or `osm_node`.",
        "example": {
          "station": "AH"
        },
        "properties": {
          "dwell_min": {
            "description": "Via points only: minutes the train stands here (a stop in the\nrunning time estimate).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "lat": {
            "description": "Latitude (WGS 84), with `lon`.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "lon": {
            "description": "Longitude (WGS 84), with `lat`.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "osm_node": {
            "description": "An OpenStreetMap node on the track.",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "station": {
            "description": "A station or operational point by code: DS100/RL100 (`AH`), UOPID\n(`DE000AH`) or UIC (`8002549`).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "MatchBreak": {
        "description": "Where the path is interrupted between two sections.",
        "properties": {
          "after_point": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "before_point": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "distance_m": {
            "description": "Straight line (m).",
            "format": "double",
            "type": "number"
          },
          "duration_s": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "reason": {
            "type": "string"
          }
        },
        "required": [
          "after_point",
          "before_point",
          "distance_m",
          "reason"
        ],
        "type": "object"
      },
      "MatchGap": {
        "description": "A stretch without usable GPS fixes (tunnel, station hall) the path bridges.",
        "properties": {
          "distance_km": {
            "description": "Along the path.",
            "format": "double",
            "type": "number"
          },
          "duration_s": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "from_point": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "points": {
            "description": "Points in between without a usable fix.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "to_point": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "from_point",
          "to_point",
          "distance_km",
          "points"
        ],
        "type": "object"
      },
      "MatchInfo": {
        "description": "How a search result matched.",
        "properties": {
          "class": {
            "description": "The match class, best first: `exact` (the name as typed), `code`\n(written as codes are: `AH`), `name` (the whole name, normalised:\nabbreviations, umlauts), `main_station` (\"leipzig\" → Leipzig Hbf),\n`prefix`, `words` (every word starts a word of the name), `substring`,\n`code_word` (a code typed like a word: \"Bad\"), `folded` (only with\ndiacritics dropped), `typo` (a suggestion; up to 2 edits).",
            "type": "string"
          },
          "score": {
            "description": "Higher is better; results are sorted by it (then more lines nearby).",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "class",
          "score"
        ],
        "type": "object"
      },
      "MatchOptionsOut": {
        "description": "The options used.",
        "properties": {
          "gps_accuracy_m": {
            "format": "double",
            "type": "number"
          },
          "max_speed_kmh": {
            "format": "double",
            "type": "number"
          },
          "search_radius_m": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "gps_accuracy_m",
          "search_radius_m",
          "max_speed_kmh"
        ],
        "type": "object"
      },
      "MatchPoint": {
        "description": "One input point and where it was matched.",
        "properties": {
          "confidence": {
            "description": "Posterior probability of the matched line (0–1).",
            "format": "double",
            "type": "number"
          },
          "distance_m": {
            "description": "From the point to its matched position (m).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "index": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "description": "The track's line number.",
            "type": [
              "string",
              "null"
            ]
          },
          "line_km": {
            "description": "Km on that line (linear referencing).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "line_km_accuracy": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/KmAccuracy"
              },
              {
                "type": "null"
              }
            ]
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "matched_lat": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "matched_lon": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "path_km": {
            "description": "Km along the matched path.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "section": {
            "format": "int64",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "speed_kmh": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "state": {
            "description": "`matched`, `interpolated` (no usable fix, placed along the path),\n`outlier` (dropped by the model), `unmatched` (no track near).",
            "type": "string"
          },
          "time": {
            "description": "RFC 3339, if the point has a time.",
            "type": [
              "string",
              "null"
            ]
          },
          "track": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MatchTrack"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "index",
          "lat",
          "lon",
          "state",
          "confidence"
        ],
        "type": "object"
      },
      "MatchResponse": {
        "description": "The matched path.",
        "properties": {
          "breaks": {
            "items": {
              "$ref": "#/components/schemas/MatchBreak"
            },
            "type": "array"
          },
          "confidence": {
            "description": "Mean point confidence.",
            "format": "double",
            "type": "number"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "duration_s": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "format": {
            "description": "The trace format read: `gpx`, `geojson`, `csv`.",
            "type": "string"
          },
          "gps_gaps": {
            "items": {
              "$ref": "#/components/schemas/MatchGap"
            },
            "type": "array"
          },
          "ok": {
            "description": "At least one section was matched.",
            "type": "boolean"
          },
          "options": {
            "$ref": "#/components/schemas/MatchOptionsOut"
          },
          "points": {
            "items": {
              "$ref": "#/components/schemas/MatchPoint"
            },
            "type": "array"
          },
          "reason": {
            "description": "Why nothing matched (`ok` false).",
            "type": [
              "string",
              "null"
            ]
          },
          "sections": {
            "items": {
              "$ref": "#/components/schemas/MatchSection"
            },
            "type": "array"
          },
          "stats": {
            "$ref": "#/components/schemas/MatchStats"
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "ok",
          "format",
          "options",
          "confidence",
          "distance_km",
          "stats",
          "sections",
          "breaks",
          "gps_gaps",
          "points",
          "warnings"
        ],
        "type": "object"
      },
      "MatchSection": {
        "description": "A continuous stretch of the matched path.",
        "properties": {
          "confidence": {
            "format": "double",
            "type": "number"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "duration_s": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "from_km": {
            "description": "Km along the whole matched path.",
            "format": "double",
            "type": "number"
          },
          "from_point": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "geometry": {
            "$ref": "#/components/schemas/LineString"
          },
          "infra": {
            "description": "Stretches of equal infrastructure, km along the path.",
            "items": {
              "$ref": "#/components/schemas/TrackSection"
            },
            "type": "array"
          },
          "lines": {
            "description": "The lines passed, km along the path.",
            "items": {
              "$ref": "#/components/schemas/LineRun"
            },
            "type": "array"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          },
          "to_point": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "from_point",
          "to_point",
          "from_km",
          "to_km",
          "distance_km",
          "confidence",
          "geometry",
          "lines",
          "infra"
        ],
        "type": "object"
      },
      "MatchStats": {
        "description": "Points by state.",
        "properties": {
          "interpolated": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "matched": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "outliers": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "points": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "unmatched": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "points",
          "matched",
          "interpolated",
          "outliers",
          "unmatched"
        ],
        "type": "object"
      },
      "MatchTrack": {
        "description": "The track a point is matched to.",
        "properties": {
          "alternatives": {
            "description": "Other plausible tracks (`way/<osm id>`), most likely first.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "ambiguous": {
            "description": "Parallel tracks can't be told apart here.",
            "type": "boolean"
          },
          "id": {
            "description": "The track object (`way/<osm id>`).",
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "track_ref": {
            "description": "`railway:track_ref`, only where the track is distinguishable.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "ambiguous",
          "alternatives"
        ],
        "type": "object"
      },
      "MatrixJob": {
        "properties": {
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "data_version": {
            "description": "The data version it is computed on.",
            "type": "string"
          },
          "elements": {
            "description": "Units billed when it was accepted.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "error": {
            "description": "Why it failed.",
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "description": "When it is deleted (an hour after it finished).",
            "type": [
              "string",
              "null"
            ]
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "job_id": {
            "description": "The job's id.",
            "type": "string"
          },
          "poll_url": {
            "description": "Where to poll it (also in `Location`).",
            "type": "string"
          },
          "progress": {
            "description": "Share done, 0–1.",
            "format": "float",
            "type": "number"
          },
          "result": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/MatrixResult",
                "description": "The result, once done (as the synchronous answer)."
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/components/schemas/JobStatus"
          }
        },
        "required": [
          "job_id",
          "status",
          "progress",
          "elements",
          "poll_url",
          "data_version",
          "created_at"
        ],
        "type": "object"
      },
      "MatrixRequest": {
        "additionalProperties": false,
        "description": "The body of `POST /v1/matrix`.",
        "example": {
          "destinations": [
            {
              "station": "AL"
            }
          ],
          "origins": [
            {
              "station": "AH"
            },
            {
              "lat": 54.3151,
              "lon": 10.1317
            }
          ],
          "profile": "freight-electric-de",
          "vehicle": {
            "max_speed_kmh": 90
          }
        },
        "properties": {
          "async": {
            "description": "Run as a job even if the matrix is small enough to answer at once.",
            "type": "boolean"
          },
          "avoid": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AvoidInput",
                "description": "Lines and areas the routes must not use, as in `POST /v1/route`."
              },
              {
                "type": "null"
              }
            ]
          },
          "destinations": {
            "description": "Up to 1,000 places; absent: the origins.",
            "items": {
              "$ref": "#/components/schemas/Location"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "no_reversal": {
            "description": "The train never reverses.",
            "type": "boolean"
          },
          "origins": {
            "description": "Up to 1,000 places, as in `POST /v1/route` (`station`, `lon` + `lat`, or `osm_node`).",
            "items": {
              "$ref": "#/components/schemas/Location"
            },
            "type": "array"
          },
          "profile": {
            "description": "A built-in vehicle profile (`GET /v1/route/profiles`); default: any\ntrack of 1,435 mm gauge.",
            "type": [
              "string",
              "null"
            ]
          },
          "reversal_min": {
            "description": "Minutes a reversal costs (default 20); trains reverse only near stations.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "vehicle": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VehicleInput",
                "description": "Overrides of the profile's vehicle, as in `POST /v1/route`."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "origins"
        ],
        "type": "object"
      },
      "MatrixResult": {
        "description": "A matrix: per origin (row) and destination (column).",
        "properties": {
          "data_version": {
            "type": "string"
          },
          "destinations": {
            "items": {
              "$ref": "#/components/schemas/ResolvedPlace"
            },
            "type": "array"
          },
          "distances_m": {
            "description": "Metres along that route; `null`: no route.",
            "items": {
              "items": {
                "format": "int32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "type": "array"
            },
            "type": "array"
          },
          "durations_s": {
            "description": "Seconds of the routing cost: min(line speed, the vehicle's\n`max_speed_kmh`), service track counted three times, reversals at\n`reversal_min`; `null`: no route. Equal to `duration_min` of\n`POST /v1/route` except on service track, which the route counts\nonce (and neither is the route's `estimate`).",
            "items": {
              "items": {
                "format": "int32",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "type": "array"
            },
            "type": "array"
          },
          "elements": {
            "description": "Origins × destinations (billed units).",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "origins": {
            "description": "The places as resolved, with where they meet usable track\n(`snapped`; absent: no track this vehicle may use within 1.5 km).",
            "items": {
              "$ref": "#/components/schemas/ResolvedPlace"
            },
            "type": "array"
          },
          "profile": {
            "description": "The built-in profile used, if any.",
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "items": {
              "items": {
                "$ref": "#/components/schemas/CellStatus"
              },
              "type": "array"
            },
            "type": "array"
          },
          "summary": {
            "$ref": "#/components/schemas/MatrixSummary"
          },
          "vehicle": {
            "$ref": "#/components/schemas/Vehicle",
            "description": "The effective vehicle."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "data_version",
          "origins",
          "destinations",
          "vehicle",
          "durations_s",
          "distances_m",
          "status",
          "summary",
          "elements"
        ],
        "type": "object"
      },
      "MatrixSummary": {
        "description": "Cells by status.",
        "properties": {
          "blocked": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "not_connected": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "ok": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "same_location": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "blocked",
          "not_connected",
          "same_location"
        ],
        "type": "object"
      },
      "MultiLineString": {
        "description": "GeoJSON `MultiLineString`.",
        "properties": {
          "coordinates": {
            "description": "Lines of `[lon, lat]`.",
            "items": {
              "items": {
                "items": {
                  "format": "double",
                  "type": "number"
                },
                "type": "array"
              },
              "type": "array"
            },
            "type": "array"
          },
          "type": {
            "description": "`MultiLineString`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "coordinates"
        ],
        "type": "object"
      },
      "MultiPolygon": {
        "description": "GeoJSON `MultiPolygon`.",
        "properties": {
          "coordinates": {
            "description": "Polygons of rings of `[lon, lat]`: the outer ring counter-clockwise, holes clockwise.",
            "items": {
              "items": {
                "items": {
                  "items": {
                    "format": "double",
                    "type": "number"
                  },
                  "type": "array"
                },
                "type": "array"
              },
              "type": "array"
            },
            "type": "array"
          },
          "type": {
            "description": "`MultiPolygon`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "coordinates"
        ],
        "type": "object"
      },
      "NearLineKm": {
        "description": "A point's line and km.",
        "properties": {
          "accuracy": {
            "$ref": "#/components/schemas/KmAccuracy"
          },
          "calibration_quality": {
            "description": "`good`, `fair` or `poor`; the full report: `/v1/linref/locate`.",
            "type": "string"
          },
          "distance_m": {
            "format": "double",
            "type": "number"
          },
          "km": {
            "format": "double",
            "type": "number"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "type": "string"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "offset_m": {
            "description": "Right (+) or left (−) of the line in the direction of increasing km (m).",
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "line",
          "km",
          "offset_m",
          "distance_m",
          "lat",
          "lon",
          "accuracy",
          "calibration_quality"
        ],
        "type": "object"
      },
      "NearPlace": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PlaceOut"
          },
          {
            "properties": {
              "distance_m": {
                "format": "double",
                "type": "number"
              }
            },
            "required": [
              "distance_m"
            ],
            "type": "object"
          }
        ],
        "description": "The nearest place and its distance."
      },
      "NearTrack": {
        "description": "The track nearest to a point.",
        "properties": {
          "distance_m": {
            "format": "double",
            "type": "number"
          },
          "id": {
            "description": "The track object (`way/<osm id>`).",
            "type": "string"
          },
          "lat": {
            "description": "The point projected onto the track.",
            "format": "double",
            "type": "number"
          },
          "line": {
            "description": "Line number(s) (`railway:ref`, several separated by `;`).",
            "type": [
              "string",
              "null"
            ]
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "service": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "distance_m",
          "lat",
          "lon"
        ],
        "type": "object"
      },
      "NoRouteOut": {
        "description": "Why there is no route.",
        "properties": {
          "blockers": {
            "description": "The stretches of the unconstrained route that block it.",
            "items": {
              "$ref": "#/components/schemas/BlockerOut"
            },
            "type": "array"
          },
          "leg": {
            "description": "The first leg (0-based) that cannot be completed.",
            "minimum": 0,
            "type": "integer"
          },
          "reason": {
            "description": "One line: the constraint that blocks the most track, with its longest stretch.",
            "type": "string"
          },
          "unconstrained": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/UnconstrainedOut",
                "description": "The leg's route ignoring the vehicle's constraints and what is avoided, if any."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "leg",
          "reason",
          "blockers"
        ],
        "type": "object"
      },
      "ObjectProperties": {
        "description": "The properties of an object, its sources kept apart.",
        "properties": {
          "derived": {
            "description": "Values computed from both, each with its source (`*_source`).",
            "type": "object"
          },
          "osm": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "OSM tags.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "rinf": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "RINF attributes.",
            "propertyNames": {
              "type": "string"
            },
            "type": "object"
          },
          "type": {
            "description": "The object type: `track`, `tunnel`, `bridge`, `station`,\n`operational_point`, `platform`, `signal`, `switch`, `level_crossing`,\n`yard`, `freight_terminal`, `depot`, `border_point`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "osm",
          "rinf",
          "derived"
        ],
        "type": "object"
      },
      "Objective": {
        "description": "What the solver minimises.",
        "enum": [
          "duration",
          "distance"
        ],
        "type": "string"
      },
      "OperationalPointOut": {
        "description": "A RINF operational point.",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "description": "`era:opType`: `station`, `passenger stop`, `junction` …",
            "type": [
              "string",
              "null"
            ]
          },
          "uopid": {
            "type": "string"
          }
        },
        "required": [
          "uopid",
          "name"
        ],
        "type": "object"
      },
      "OptimizationJob": {
        "properties": {
          "created_at": {
            "description": "RFC 3339.",
            "type": "string"
          },
          "data_version": {
            "description": "The data version it is computed on.",
            "type": "string"
          },
          "elements": {
            "description": "Units billed when it was accepted.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "error": {
            "description": "Why it failed.",
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "description": "When it is deleted (an hour after it finished).",
            "type": [
              "string",
              "null"
            ]
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "job_id": {
            "description": "The job's id.",
            "type": "string"
          },
          "poll_url": {
            "description": "Where to poll it (also in `Location`).",
            "type": "string"
          },
          "progress": {
            "description": "Share done, 0–1.",
            "format": "float",
            "type": "number"
          },
          "result": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/OptimizeResult",
                "description": "The result, once done (as the synchronous answer)."
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "$ref": "#/components/schemas/JobStatus"
          }
        },
        "required": [
          "job_id",
          "status",
          "progress",
          "elements",
          "poll_url",
          "data_version",
          "created_at"
        ],
        "type": "object"
      },
      "OptimizeJob": {
        "additionalProperties": false,
        "description": "A single stop: `delivery` is loaded at the vehicle's start and unloaded\nhere, `pickup` loaded here and carried to the end.",
        "properties": {
          "delivery": {
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": "array"
          },
          "id": {
            "type": "string"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "pickup": {
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": "array"
          },
          "service_s": {
            "format": "int64",
            "type": "integer"
          },
          "time_windows": {
            "description": "Service starts within one of these `[start, end]`; none: any time.",
            "items": {
              "items": {
                "format": "int64",
                "type": "integer"
              },
              "type": "array"
            },
            "type": "array"
          }
        },
        "required": [
          "id",
          "location"
        ],
        "type": "object"
      },
      "OptimizeRequest": {
        "additionalProperties": false,
        "description": "The body of `POST /v1/optimize`.",
        "example": {
          "jobs": [
            {
              "delivery": [
                5
              ],
              "id": "j1",
              "location": {
                "station": "AK"
              },
              "service_s": 1800
            }
          ],
          "vehicles": [
            {
              "capacity": [
                20
              ],
              "id": "loco-1",
              "start": {
                "station": "AMAS"
              }
            }
          ]
        },
        "properties": {
          "async": {
            "description": "Run as a job even if small enough to answer at once.",
            "type": "boolean"
          },
          "avoid": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AvoidInput",
                "description": "Lines and areas no vehicle may use, as in `POST /v1/route`."
              },
              {
                "type": "null"
              }
            ]
          },
          "jobs": {
            "items": {
              "$ref": "#/components/schemas/OptimizeJob"
            },
            "type": "array"
          },
          "objective": {
            "$ref": "#/components/schemas/Objective"
          },
          "shipments": {
            "items": {
              "$ref": "#/components/schemas/OptimizeShipment"
            },
            "type": "array"
          },
          "time_limit_s": {
            "description": "Seconds the solver may search (default 5, at most 60).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "vehicles": {
            "items": {
              "$ref": "#/components/schemas/OptimizeVehicle"
            },
            "type": "array"
          }
        },
        "required": [
          "vehicles"
        ],
        "type": "object"
      },
      "OptimizeResult": {
        "description": "The answer of an optimization.",
        "properties": {
          "data_version": {
            "type": "string"
          },
          "elements": {
            "description": "Matrix elements computed (billed units).",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "locations": {
            "description": "Distinct locations in order of first use; steps refer to them by\nindex. `snapped`: where the first vehicle's profile meets the track.",
            "items": {
              "$ref": "#/components/schemas/ResolvedPlace"
            },
            "type": "array"
          },
          "objective": {
            "$ref": "#/components/schemas/Objective"
          },
          "routes": {
            "description": "The vehicles used, in request order.",
            "items": {
              "$ref": "#/components/schemas/OptimizeRoute"
            },
            "type": "array"
          },
          "solver": {
            "$ref": "#/components/schemas/SolverStats"
          },
          "summary": {
            "$ref": "#/components/schemas/OptimizeSummary"
          },
          "unassigned": {
            "items": {
              "$ref": "#/components/schemas/OptimizeUnassigned"
            },
            "type": "array"
          }
        },
        "required": [
          "data_version",
          "objective",
          "locations",
          "routes",
          "unassigned",
          "summary",
          "solver",
          "elements"
        ],
        "type": "object"
      },
      "OptimizeRoute": {
        "description": "A vehicle's route.",
        "properties": {
          "distance_m": {
            "format": "int64",
            "type": "integer"
          },
          "duration_s": {
            "description": "Running time.",
            "format": "int64",
            "type": "integer"
          },
          "end_time": {
            "description": "Arrival at the end, or departure from the last stop.",
            "format": "int64",
            "type": "integer"
          },
          "service_s": {
            "format": "int64",
            "type": "integer"
          },
          "start_time": {
            "description": "Departure from the start.",
            "format": "int64",
            "type": "integer"
          },
          "steps": {
            "items": {
              "$ref": "#/components/schemas/OptimizeStep"
            },
            "type": "array"
          },
          "vehicle": {
            "type": "string"
          },
          "waiting_s": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "vehicle",
          "steps",
          "distance_m",
          "duration_s",
          "waiting_s",
          "service_s",
          "start_time",
          "end_time"
        ],
        "type": "object"
      },
      "OptimizeShipment": {
        "additionalProperties": false,
        "description": "`amount` from `pickup` to `delivery`, on one vehicle.",
        "properties": {
          "amount": {
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": "array"
          },
          "delivery": {
            "$ref": "#/components/schemas/ShipmentStop"
          },
          "id": {
            "type": "string"
          },
          "pickup": {
            "$ref": "#/components/schemas/ShipmentStop"
          }
        },
        "required": [
          "id",
          "pickup",
          "delivery"
        ],
        "type": "object"
      },
      "OptimizeStep": {
        "description": "A step of a route; `distance_m` and `duration_s` are the leg from the\nprevious step.",
        "properties": {
          "arrival": {
            "format": "int64",
            "type": "integer"
          },
          "departure": {
            "format": "int64",
            "type": "integer"
          },
          "distance_m": {
            "format": "int64",
            "type": "integer"
          },
          "duration_s": {
            "format": "int64",
            "type": "integer"
          },
          "id": {
            "description": "The job's or shipment's id.",
            "type": [
              "string",
              "null"
            ]
          },
          "load": {
            "description": "Load after the step.",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": "array"
          },
          "location": {
            "description": "Index into `locations`.",
            "minimum": 0,
            "type": "integer"
          },
          "service_s": {
            "format": "int64",
            "type": "integer"
          },
          "type": {
            "$ref": "#/components/schemas/StepType"
          },
          "waiting_s": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "type",
          "location",
          "arrival",
          "waiting_s",
          "service_s",
          "departure",
          "load",
          "distance_m",
          "duration_s"
        ],
        "type": "object"
      },
      "OptimizeSummary": {
        "description": "Totals.",
        "properties": {
          "assigned": {
            "description": "Jobs and shipments.",
            "minimum": 0,
            "type": "integer"
          },
          "cost": {
            "description": "The objective: seconds of running time, or metres.",
            "format": "int64",
            "type": "integer"
          },
          "distance_m": {
            "format": "int64",
            "type": "integer"
          },
          "duration_s": {
            "format": "int64",
            "type": "integer"
          },
          "routes": {
            "minimum": 0,
            "type": "integer"
          },
          "service_s": {
            "format": "int64",
            "type": "integer"
          },
          "unassigned": {
            "minimum": 0,
            "type": "integer"
          },
          "waiting_s": {
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "cost",
          "routes",
          "assigned",
          "unassigned",
          "distance_m",
          "duration_s",
          "waiting_s",
          "service_s"
        ],
        "type": "object"
      },
      "OptimizeUnassigned": {
        "description": "A job or shipment left out.",
        "properties": {
          "id": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "reason": {
            "$ref": "#/components/schemas/UnassignedReason"
          },
          "type": {
            "description": "`job` or `shipment`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "id",
          "reason",
          "message"
        ],
        "type": "object"
      },
      "OptimizeVehicle": {
        "additionalProperties": false,
        "description": "A train with its constraints.",
        "properties": {
          "capacity": {
            "description": "Per dimension (wagons, tonnes, …); every vehicle has the same dimensions.",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": "array"
          },
          "end": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Location",
                "description": "Absent: the route ends at its last stop."
              },
              {
                "type": "null"
              }
            ]
          },
          "id": {
            "type": "string"
          },
          "no_reversal": {
            "description": "The train never reverses.",
            "type": "boolean"
          },
          "profile": {
            "description": "A built-in vehicle profile (`GET /v1/route/profiles`); default: any\ntrack of 1,435 mm gauge.",
            "type": [
              "string",
              "null"
            ]
          },
          "reversal_min": {
            "description": "Minutes a reversal costs (default 20); trains reverse only near stations.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "start": {
            "$ref": "#/components/schemas/Location",
            "description": "A place, as in `POST /v1/route` (`station`, `lon` + `lat`, or `osm_node`)."
          },
          "time_window": {
            "description": "`[earliest start, latest end]` (s).",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "vehicle": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VehicleInput",
                "description": "Overrides of the profile's vehicle, as in `POST /v1/route`."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "start"
        ],
        "type": "object"
      },
      "Part": {
        "description": "Parts of a route a request can ask for (`include`); none by default.",
        "enum": [
          "geometry",
          "polyline",
          "segments",
          "sections",
          "lines",
          "operational_points",
          "countries",
          "infrastructure_managers",
          "changes",
          "estimate",
          "speed_profile",
          "charges",
          "capacity",
          "all"
        ],
        "type": "string"
      },
      "PlaceCode": {
        "description": "A code of a place.",
        "properties": {
          "code": {
            "type": "string"
          },
          "kind": {
            "description": "`ds100`, `uopid` or `uic`.",
            "type": "string"
          }
        },
        "required": [
          "code",
          "kind"
        ],
        "type": "object"
      },
      "PlaceDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PlaceOut"
          },
          {
            "properties": {
              "operational_points": {
                "description": "Its RINF operational points (UOPIDs) with their RINF names and types.",
                "items": {
                  "$ref": "#/components/schemas/OperationalPointOut"
                },
                "type": "array"
              },
              "platforms": {
                "$ref": "#/components/schemas/Platforms"
              },
              "stations": {
                "description": "The OSM station objects merged into the place (a station mapped twice).",
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            },
            "required": [
              "stations",
              "operational_points",
              "platforms"
            ],
            "type": "object"
          }
        ],
        "description": "A place with everything known about it."
      },
      "PlaceMatch": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PlaceOut"
          },
          {
            "properties": {
              "match": {
                "$ref": "#/components/schemas/MatchInfo"
              }
            },
            "required": [
              "match"
            ],
            "type": "object"
          }
        ],
        "description": "A place found by search."
      },
      "PlaceMatches": {
        "description": "A page of places found.",
        "properties": {
          "next_cursor": {
            "description": "The cursor of the next page; `null` on the last.",
            "type": [
              "string",
              "null"
            ]
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/PlaceMatch"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "type": "object"
      },
      "PlaceOut": {
        "description": "A place: an OSM station or halt (with its RINF operational points where\nlinked by DS100 code), or a RINF operational point without OSM station.",
        "example": {
          "aliases": [
            "Kiel Hbf"
          ],
          "codes": [
            {
              "code": "AK",
              "kind": "ds100"
            },
            {
              "code": "DE000AK",
              "kind": "uopid"
            },
            {
              "code": "8000199",
              "kind": "uic"
            }
          ],
          "country": "DE",
          "ds100": "AK",
          "id": "node/2414223574",
          "kind": "station",
          "lat": 54.315,
          "lines": [
            "1023",
            "1030"
          ],
          "lon": 10.13158,
          "name": "Kiel Hauptbahnhof",
          "source": "osm+rinf",
          "uic": "8000199",
          "uopid": "DE000AK"
        },
        "properties": {
          "aliases": {
            "description": "Other names (RINF's name of a linked station).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "codes": {
            "description": "Every code of the place.",
            "items": {
              "$ref": "#/components/schemas/PlaceCode"
            },
            "type": "array"
          },
          "country": {
            "description": "ISO 3166-1 alpha-2, from the UOPID or UIC code.",
            "type": [
              "string",
              "null"
            ]
          },
          "ds100": {
            "description": "The first DS100 (RL100) code.",
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "description": "The place's infrastructure object (`/v1/infra/objects/{id}`, `/v1/places/{id}`):\n`node/<osm id>` of its OSM station, or `rinf-op/<UOPID>`.",
            "type": "string"
          },
          "kind": {
            "description": "`station`, `halt` or `operational_point`.",
            "type": "string"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lines": {
            "description": "Line numbers of the track within 300 m (more lines: a more important place).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "source": {
            "description": "`osm`, `rinf` (operational point only) or `osm+rinf` (linked).",
            "type": "string"
          },
          "uic": {
            "type": [
              "string",
              "null"
            ]
          },
          "uopid": {
            "description": "The first linked RINF operational point.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "lat",
          "lon",
          "source",
          "codes",
          "aliases",
          "lines"
        ],
        "type": "object"
      },
      "Platforms": {
        "description": "A station's platforms: OSM platforms (length, height, tracks), linked to\nthe RINF platform edges of its operational points.",
        "properties": {
          "count": {
            "description": "OSM platforms, else RINF platform edges.",
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "heights_cm": {
            "description": "Distinct heights, ascending.",
            "items": {
              "format": "int32",
              "minimum": 0,
              "type": "integer"
            },
            "type": "array"
          },
          "max_length_m": {
            "description": "`null` = unknown.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "platforms": {
            "items": {
              "$ref": "#/components/schemas/StationPlatform"
            },
            "type": "array"
          },
          "rinf_platforms": {
            "items": {
              "$ref": "#/components/schemas/RinfPlatformEdge"
            },
            "type": "array"
          },
          "tracks": {
            "description": "The platform tracks.",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "count",
          "heights_cm",
          "tracks",
          "platforms",
          "rinf_platforms"
        ],
        "type": "object"
      },
      "PolygonCollection": {
        "description": "GeoJSON `FeatureCollection` of polygons.",
        "properties": {
          "features": {
            "items": {
              "$ref": "#/components/schemas/PolygonFeature"
            },
            "type": "array"
          },
          "type": {
            "description": "`FeatureCollection`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "features"
        ],
        "type": "object"
      },
      "PolygonFeature": {
        "description": "A GeoJSON feature: the area around the track up to one band.",
        "properties": {
          "geometry": {
            "$ref": "#/components/schemas/MultiPolygon"
          },
          "properties": {
            "$ref": "#/components/schemas/BandProperties"
          },
          "type": {
            "description": "`Feature`.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "properties",
          "geometry"
        ],
        "type": "object"
      },
      "Problem": {
        "description": "An RFC 9457 problem details object.",
        "example": {
          "detail": "this key allows 600 requests per minute; retry in 1 s",
          "status": 429,
          "title": "Rate limit exceeded",
          "type": "https://routing.gleisklar.de/problems/rate-limited"
        },
        "properties": {
          "detail": {
            "description": "What went wrong in this request.",
            "type": [
              "string",
              "null"
            ]
          },
          "errors": {
            "description": "Individual problems with the request's parameters or body.",
            "items": {
              "$ref": "#/components/schemas/ProblemItem"
            },
            "type": "array"
          },
          "status": {
            "description": "The HTTP status code.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "title": {
            "description": "Short summary of the problem type (the same for every occurrence).",
            "type": "string"
          },
          "type": {
            "description": "URI of the problem type; stable, one per kind of error.",
            "type": "string"
          }
        },
        "required": [
          "type",
          "title",
          "status"
        ],
        "type": "object"
      },
      "ProblemItem": {
        "description": "One problem with a request parameter or a part of the request body.",
        "properties": {
          "detail": {
            "description": "What is wrong with it.",
            "type": "string"
          },
          "parameter": {
            "description": "The query or path parameter concerned.",
            "type": [
              "string",
              "null"
            ]
          },
          "pointer": {
            "description": "JSON Pointer (RFC 6901) to the part of the request body concerned.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "detail"
        ],
        "type": "object"
      },
      "ProfileInfo": {
        "description": "A built-in vehicle profile.",
        "properties": {
          "description": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "vehicle": {
            "$ref": "#/components/schemas/Vehicle"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "vehicle"
        ],
        "type": "object"
      },
      "ProfilesResponse": {
        "description": "The built-in vehicle profiles.",
        "properties": {
          "profiles": {
            "items": {
              "$ref": "#/components/schemas/ProfileInfo"
            },
            "type": "array"
          }
        },
        "required": [
          "profiles"
        ],
        "type": "object"
      },
      "Ready": {
        "description": "`GET /readyz` when ready.",
        "properties": {
          "data_version": {
            "description": "The data version being served.",
            "type": "string"
          },
          "stale": {
            "description": "Served from the local cache because the data store is unreachable.",
            "type": "boolean"
          },
          "status": {
            "description": "Always `ready`.",
            "type": "string"
          }
        },
        "required": [
          "status",
          "data_version",
          "stale"
        ],
        "type": "object"
      },
      "ResolvedPlace": {
        "description": "A place as a response echoes it. Documented as `ResolvedPlace`: the\nsearch endpoints' `PlaceOut` is a different shape, and two schemas of one\nname would silently replace each other in the OpenAPI document.",
        "properties": {
          "ds100": {
            "type": "string"
          },
          "kind": {
            "description": "`station`, `halt` (OSM), `op` (RINF operational point), `point` or `node`.",
            "type": "string"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "description": "The station's name, or the coordinates / node as given.",
            "type": "string"
          },
          "snapped": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SnappedOut",
                "description": "Where the route meets the track."
              },
              {
                "type": "null"
              }
            ]
          },
          "uic": {
            "type": "string"
          },
          "uopid": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "kind",
          "lon",
          "lat"
        ],
        "type": "object"
      },
      "ReverseResult": {
        "description": "What is at a point.",
        "properties": {
          "line_km": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/NearLineKm",
                "description": "The km on the nearest track's line if calibrated, else on the nearest calibrated line."
              },
              {
                "type": "null"
              }
            ]
          },
          "place": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/NearPlace",
                "description": "The nearest place within the radius."
              },
              {
                "type": "null"
              }
            ]
          },
          "track": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/NearTrack",
                "description": "The nearest track within the radius."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "type": "object"
      },
      "RinfPlatformEdge": {
        "description": "A RINF platform edge of a station's operational points.",
        "properties": {
          "height_cm": {
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "length_m": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "osm_platforms": {
            "description": "The OSM platforms linked to it.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "platform_id": {
            "type": "string"
          },
          "track": {
            "description": "The OP track's number.",
            "type": "string"
          },
          "uopid": {
            "type": "string"
          }
        },
        "required": [
          "uopid",
          "track",
          "platform_id",
          "osm_platforms"
        ],
        "type": "object"
      },
      "RouteOperationalPoint": {
        "description": "A station or operational point within 300 m of the route, where it passes\nclosest. Documented as `RouteOperationalPoint` (the places endpoints'\n`OperationalPointOut` is another shape).",
        "properties": {
          "ds100": {
            "type": "string"
          },
          "kind": {
            "description": "`station`, `halt` (OSM) or `op` (RINF only).",
            "type": "string"
          },
          "km": {
            "format": "double",
            "type": "number"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "uic": {
            "type": "string"
          },
          "uopid": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "kind",
          "km",
          "lon",
          "lat"
        ],
        "type": "object"
      },
      "RouteOut": {
        "description": "A route through the stops.",
        "properties": {
          "border_crossings": {
            "items": {
              "$ref": "#/components/schemas/BorderCrossingOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "capacity": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/CapacityOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "changes": {
            "items": {
              "$ref": "#/components/schemas/ChangeOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "charges": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChargesOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "countries": {
            "items": {
              "$ref": "#/components/schemas/CountryOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "distance_by_im": {
            "items": {
              "$ref": "#/components/schemas/ImDistanceOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "duration_min": {
            "description": "Running time at min(line speed, max speed), plus reversals.",
            "format": "double",
            "type": "number"
          },
          "estimate": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/EstimateOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "geometry": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LineGeometry"
              },
              {
                "type": "null"
              }
            ]
          },
          "infrastructure_managers": {
            "items": {
              "$ref": "#/components/schemas/ImOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "legs": {
            "items": {
              "$ref": "#/components/schemas/LegOut"
            },
            "type": "array"
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/LineOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "operational_points": {
            "items": {
              "$ref": "#/components/schemas/RouteOperationalPoint"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "polyline": {
            "type": [
              "string",
              "null"
            ]
          },
          "reversals": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "sections": {
            "items": {
              "$ref": "#/components/schemas/SectionOut"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "segments": {
            "items": {
              "$ref": "#/components/schemas/SegmentOut"
            },
            "type": [
              "array",
              "null"
            ]
          }
        },
        "required": [
          "distance_km",
          "duration_min",
          "reversals",
          "legs"
        ],
        "type": "object"
      },
      "RouteRequest": {
        "additionalProperties": false,
        "description": "A route: from, via …, to, for a vehicle.",
        "example": {
          "from": {
            "station": "AK"
          },
          "include": [
            "geometry",
            "sections",
            "estimate"
          ],
          "profile": "freight-electric-de",
          "to": {
            "station": "AH"
          },
          "vehicle": {
            "max_speed_kmh": 90
          },
          "via": [
            {
              "dwell_min": 5,
              "lat": 54.08,
              "lon": 10.13
            }
          ]
        },
        "properties": {
          "alternatives": {
            "description": "Alternative routes to add (0–3): noticeably different, at most 40 % longer in time.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "avoid": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AvoidInput",
                "description": "Lines and areas the route must not use."
              },
              {
                "type": "null"
              }
            ]
          },
          "charges": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ChargesInput",
                "description": "The train of the charges estimate."
              },
              {
                "type": "null"
              }
            ]
          },
          "from": {
            "$ref": "#/components/schemas/Location"
          },
          "include": {
            "description": "Parts of each route to include.",
            "items": {
              "$ref": "#/components/schemas/Part"
            },
            "type": "array"
          },
          "no_reversal": {
            "description": "The train never reverses.",
            "type": "boolean"
          },
          "profile": {
            "description": "A built-in vehicle profile (`GET /v1/route/profiles`); default:\nany track of 1,435 mm gauge, a passenger train's characteristics.",
            "type": [
              "string",
              "null"
            ]
          },
          "reversal_min": {
            "description": "Minutes a reversal costs (default 20); trains reverse only near stations.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "to": {
            "$ref": "#/components/schemas/Location"
          },
          "vehicle": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VehicleInput",
                "description": "Overrides of the profile's vehicle."
              },
              {
                "type": "null"
              }
            ]
          },
          "via": {
            "description": "Places to pass in order (at most 10).",
            "items": {
              "$ref": "#/components/schemas/Location"
            },
            "type": "array"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "type": "object"
      },
      "RouteResponse": {
        "description": "The answer of `POST /v1/route`.",
        "properties": {
          "no_route": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/NoRouteOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "profile": {
            "type": [
              "string",
              "null"
            ]
          },
          "routes": {
            "description": "The best route first, then alternatives; empty without a route.",
            "items": {
              "$ref": "#/components/schemas/RouteOut"
            },
            "type": "array"
          },
          "status": {
            "$ref": "#/components/schemas/RouteStatus"
          },
          "stops": {
            "description": "The places as resolved: from, via …, to.",
            "items": {
              "$ref": "#/components/schemas/ResolvedPlace"
            },
            "type": "array"
          },
          "vehicle": {
            "$ref": "#/components/schemas/Vehicle",
            "description": "The effective vehicle."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "required": [
          "status",
          "stops",
          "vehicle",
          "routes",
          "warnings"
        ],
        "type": "object"
      },
      "RouteStatus": {
        "description": "Whether a route was found.",
        "enum": [
          "ok",
          "no_route"
        ],
        "type": "string"
      },
      "RunSegmentOut": {
        "description": "The estimate over one section (same km as `sections`).",
        "properties": {
          "avg_speed_kmh": {
            "format": "double",
            "type": "number"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "speed_limit_kmh": {
            "description": "min(line speed, max speed); the lowest if it varies.",
            "format": "double",
            "type": "number"
          },
          "time_s": {
            "description": "Running time, halts not included.",
            "format": "double",
            "type": "number"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          },
          "top_speed_kmh": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "from_km",
          "to_km",
          "speed_limit_kmh",
          "top_speed_kmh",
          "avg_speed_kmh",
          "time_s"
        ],
        "type": "object"
      },
      "SectionOut": {
        "description": "A stretch of equal infrastructure. Values come from RINF where the track\nis matched to a RINF section, else from OSM (the `*_source` fields).",
        "properties": {
          "electrified": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "electrified_source": {
            "type": "string"
          },
          "energy": {
            "description": "RINF energy supply system.",
            "type": "string"
          },
          "etcs": {
            "type": "string"
          },
          "etcs_source": {
            "type": "string"
          },
          "frequency": {
            "type": "string"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "gauge": {
            "description": "OSM, mm.",
            "type": "string"
          },
          "gauging": {
            "type": "string"
          },
          "gauging_source": {
            "type": "string"
          },
          "length_m": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "type": "string"
          },
          "load": {
            "description": "RINF, e.g. `D4@100km/h`.",
            "type": "string"
          },
          "maxspeed_kmh": {
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "maxspeed_source": {
            "type": "string"
          },
          "rinf_section": {
            "type": "string"
          },
          "structure": {
            "description": "`tunnel` or `bridge` (OSM).",
            "type": "string"
          },
          "structure_name": {
            "type": "string"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          },
          "track_class": {
            "type": "string"
          },
          "track_class_source": {
            "type": "string"
          },
          "train_protection": {
            "description": "Class B systems: RINF legacy, else OSM PZB/LZB.",
            "type": "string"
          },
          "train_protection_source": {
            "type": "string"
          },
          "voltage": {
            "description": "OSM.",
            "type": "string"
          }
        },
        "required": [
          "from_km",
          "to_km",
          "length_m"
        ],
        "type": "object"
      },
      "SegmentOut": {
        "description": "A compressed edge of the route (track between junctions), or the part of\nit the route uses.",
        "properties": {
          "edge": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "from_km": {
            "format": "double",
            "type": "number"
          },
          "from_node": {
            "description": "OSM node where the route enters / leaves it (absent inside it).",
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "length_m": {
            "format": "double",
            "type": "number"
          },
          "reversal": {
            "description": "The train reverses before this edge.",
            "type": "boolean"
          },
          "speed_kmh": {
            "description": "Routing line speed (km/h), the lowest on it.",
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "to_km": {
            "format": "double",
            "type": "number"
          },
          "to_node": {
            "format": "int64",
            "type": [
              "integer",
              "null"
            ]
          },
          "ways": {
            "description": "OSM ways in travel order.",
            "items": {
              "format": "int64",
              "type": "integer"
            },
            "type": "array"
          }
        },
        "required": [
          "edge",
          "from_km",
          "to_km",
          "length_m",
          "ways",
          "speed_kmh"
        ],
        "type": "object"
      },
      "ShipmentStop": {
        "additionalProperties": false,
        "description": "One end of a shipment.",
        "properties": {
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "service_s": {
            "format": "int64",
            "type": "integer"
          },
          "time_windows": {
            "items": {
              "items": {
                "format": "int64",
                "type": "integer"
              },
              "type": "array"
            },
            "type": "array"
          }
        },
        "required": [
          "location"
        ],
        "type": "object"
      },
      "SnappedOut": {
        "description": "Where a place meets the track.",
        "properties": {
          "distance_m": {
            "description": "Distance from the place (m).",
            "format": "double",
            "type": "number"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          }
        },
        "required": [
          "lon",
          "lat",
          "distance_m"
        ],
        "type": "object"
      },
      "SolverStats": {
        "description": "How the search went.",
        "properties": {
          "construction_cost": {
            "format": "int64",
            "type": "integer"
          },
          "cost": {
            "format": "int64",
            "type": "integer"
          },
          "iterations": {
            "description": "Ruin-and-recreate rounds.",
            "minimum": 0,
            "type": "integer"
          },
          "moves": {
            "description": "Improving moves applied.",
            "minimum": 0,
            "type": "integer"
          },
          "ms": {
            "format": "int64",
            "minimum": 0,
            "type": "integer"
          },
          "timed_out": {
            "description": "The time limit stopped the search.",
            "type": "boolean"
          }
        },
        "required": [
          "construction_cost",
          "cost",
          "iterations",
          "moves",
          "timed_out",
          "ms"
        ],
        "type": "object"
      },
      "StationPlatform": {
        "description": "A platform of a station.",
        "properties": {
          "height_cm": {
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "height_source": {
            "description": "`RINF` or `OSM tag`.",
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "description": "The OSM platform object.",
            "type": "string"
          },
          "length_m": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "length_source": {
            "description": "`RINF`, `OSM tag` or `OSM geometry`.",
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "ref": {
            "type": [
              "string",
              "null"
            ]
          },
          "rinf_platform_ids": {
            "description": "The RINF platform edges linked to it.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "tracks": {
            "description": "Track numbers it serves.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "tracks_source": {
            "description": "`OSM platform` (its own refs) or `OSM track` (the tracks alongside).",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "tracks",
          "rinf_platform_ids"
        ],
        "type": "object"
      },
      "StepType": {
        "description": "What a step is.",
        "enum": [
          "start",
          "job",
          "pickup",
          "delivery",
          "end"
        ],
        "type": "string"
      },
      "SubscriptionFilter": {
        "description": "What a subscription selects; stored as JSON (`change_subscriptions.filter`).",
        "properties": {
          "bbox": {
            "description": "minLon, minLat, maxLon, maxLat.",
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "lines": {
            "description": "Line refs (e.g. `1043`); a change on one of them matches.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "route": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SubscriptionRoute",
                "description": "A route corridor."
              },
              {
                "type": "null"
              }
            ]
          },
          "types": {
            "description": "Object types (`track` includes `tunnel` and `bridge`).",
            "items": {
              "type": "string"
            },
            "type": "array"
          }
        },
        "type": "object"
      },
      "SubscriptionList": {
        "description": "`GET /v1/changes/subscriptions`.",
        "properties": {
          "subscriptions": {
            "items": {
              "$ref": "#/components/schemas/SubscriptionView"
            },
            "type": "array"
          }
        },
        "required": [
          "subscriptions"
        ],
        "type": "object"
      },
      "SubscriptionRequest": {
        "additionalProperties": false,
        "description": "The body of `POST /v1/changes/subscriptions`.",
        "example": {
          "description": "Marschbahn",
          "lines": [
            "1210"
          ],
          "types": [
            "track",
            "signal"
          ],
          "url": "https://example.com/hooks/railroute"
        },
        "properties": {
          "bbox": {
            "description": "minLon, minLat, maxLon, maxLat: changes in this box.",
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "description": {
            "description": "Free text, at most 200 characters.",
            "type": "string"
          },
          "lines": {
            "description": "Line refs: changes on these lines (at most 100).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "route": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SubscriptionRouteInput",
                "description": "A route corridor: changes on the route's track ways or within\n`buffer_m` of its line. The route is computed now, on the data\nversion served, and not recomputed for later versions."
              },
              {
                "type": "null"
              }
            ]
          },
          "types": {
            "description": "Object types (`track` includes `tunnel` and `bridge`).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "url": {
            "description": "Where events are POSTed (https).",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "type": "object"
      },
      "SubscriptionRoute": {
        "description": "A route corridor: the route as requested and what was computed from it\n(on the data version named). A change matches if it is on one of the\nroute's track ways or its point is within `buffer_m` of its line.",
        "properties": {
          "buffer_m": {
            "format": "double",
            "type": "number"
          },
          "data_version": {
            "type": "string"
          },
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "geometry": {
            "$ref": "#/components/schemas/LineGeometry"
          },
          "lines": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "ok": {
            "description": "false: no route fits the vehicle; the corridor follows the route ignoring its constraints.",
            "type": "boolean"
          },
          "request": {
            "description": "The route as given (from, to, via, vehicle, …)."
          }
        },
        "required": [
          "buffer_m",
          "geometry"
        ],
        "type": "object"
      },
      "SubscriptionRouteInput": {
        "additionalProperties": false,
        "description": "A subscription's route: as in `POST /v1/route` (places, vehicle, what to\navoid), and the corridor's width.",
        "example": {
          "buffer_m": 300,
          "from": {
            "station": "AMAS"
          },
          "profile": "freight-electric-de",
          "to": {
            "station": "AK"
          }
        },
        "properties": {
          "avoid": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AvoidInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "buffer_m": {
            "description": "Corridor half-width (m, 10–5,000; default 500).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "from": {
            "$ref": "#/components/schemas/Location"
          },
          "no_reversal": {
            "type": "boolean"
          },
          "profile": {
            "type": [
              "string",
              "null"
            ]
          },
          "reversal_min": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "to": {
            "$ref": "#/components/schemas/Location"
          },
          "vehicle": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VehicleInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "via": {
            "description": "Places to pass in order (at most 10).",
            "items": {
              "$ref": "#/components/schemas/Location"
            },
            "type": "array"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "type": "object"
      },
      "SubscriptionView": {
        "description": "A subscription.",
        "properties": {
          "created_at": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "filter": {
            "$ref": "#/components/schemas/SubscriptionFilter"
          },
          "id": {
            "description": "`sub_…`.",
            "type": "string"
          },
          "last_delivery": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/DeliveryView"
              },
              {
                "type": "null"
              }
            ]
          },
          "secret": {
            "description": "The signing secret (`whsec_…`): only in the answer of the create.",
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "description",
          "filter",
          "created_at"
        ],
        "type": "object"
      },
      "Suggestion": {
        "description": "An autocomplete suggestion: what a search box shows and needs to act on it.",
        "properties": {
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "distance_m": {
            "description": "From `focus` (m), if given.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "ds100": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "description": "As in `/v1/places`.",
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "lat": {
            "format": "double",
            "type": "number"
          },
          "lon": {
            "format": "double",
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "uic": {
            "type": [
              "string",
              "null"
            ]
          },
          "uopid": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "lat",
          "lon"
        ],
        "type": "object"
      },
      "Suggestions": {
        "description": "A page of suggestions.",
        "properties": {
          "next_cursor": {
            "description": "The cursor of the next page; `null` on the last.",
            "type": [
              "string",
              "null"
            ]
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/Suggestion"
            },
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "type": "object"
      },
      "TestQueued": {
        "description": "`POST /v1/changes/subscriptions/{id}/test`.",
        "properties": {
          "delivery_id": {
            "type": "string"
          },
          "status": {
            "description": "`pending`: a worker sends it within seconds.",
            "type": "string"
          },
          "subscription_id": {
            "type": "string"
          }
        },
        "required": [
          "delivery_id",
          "status",
          "subscription_id"
        ],
        "type": "object"
      },
      "TileJson": {
        "description": "A TileJSON 3.0 document.",
        "example": {
          "attribution": "© OpenStreetMap contributors (ODbL), RINF © ERA / infrastructure managers",
          "bounds": [
            5.8,
            47.2,
            15.1,
            55.1
          ],
          "maxzoom": 14,
          "minzoom": 5,
          "tilejson": "3.0.0",
          "tiles": [
            "https://api.routing.gleisklar.de/v1/tiles/20261105-0200/{z}/{x}/{y}.mvt?key=rr_pk_…"
          ],
          "vector_layers": [
            {
              "id": "tracks"
            },
            {
              "id": "signals"
            }
          ],
          "version": "20261105-0200"
        },
        "properties": {
          "attribution": {
            "type": "string"
          },
          "bounds": {
            "description": "minLon, minLat, maxLon, maxLat.",
            "items": {
              "format": "double",
              "type": "number"
            },
            "type": "array"
          },
          "maxzoom": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "minzoom": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "tilejson": {
            "type": "string"
          },
          "tiles": {
            "description": "The tile URL template (with the publishable key the TileJSON was fetched with).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "vector_layers": {
            "items": {
              "$ref": "#/components/schemas/VectorLayer"
            },
            "type": "array"
          },
          "version": {
            "description": "The data (or basemap) version the tile URLs point at.",
            "type": "string"
          }
        },
        "required": [
          "tilejson",
          "version",
          "minzoom",
          "maxzoom",
          "bounds",
          "tiles",
          "attribution",
          "vector_layers"
        ],
        "type": "object"
      },
      "TrackSection": {
        "description": "A stretch of equal infrastructure. Each value comes from RINF where the\ntrack is matched to a RINF section, else from OSM; `*_source` says which.",
        "properties": {
          "electrified": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "electrified_source": {
            "type": [
              "string",
              "null"
            ]
          },
          "energy": {
            "description": "RINF energy supply system, where electrified.",
            "type": [
              "string",
              "null"
            ]
          },
          "etcs": {
            "type": [
              "string",
              "null"
            ]
          },
          "etcs_source": {
            "type": [
              "string",
              "null"
            ]
          },
          "frequency": {
            "type": [
              "string",
              "null"
            ]
          },
          "from_km": {
            "description": "Where it starts and ends: line km (linear referencing) or km along\nthe route / matched path.",
            "format": "double",
            "type": "number"
          },
          "gauge": {
            "description": "OSM gauge (mm).",
            "type": [
              "string",
              "null"
            ]
          },
          "gauging": {
            "type": [
              "string",
              "null"
            ]
          },
          "gauging_source": {
            "type": [
              "string",
              "null"
            ]
          },
          "length_m": {
            "format": "double",
            "type": "number"
          },
          "line": {
            "description": "OSM `railway:ref`.",
            "type": [
              "string",
              "null"
            ]
          },
          "load": {
            "description": "RINF line category with the speed it holds for (`D4@100km/h`).",
            "type": [
              "string",
              "null"
            ]
          },
          "max_speed_kmh": {
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "max_speed_source": {
            "type": [
              "string",
              "null"
            ]
          },
          "missing_geometry": {
            "description": "No track geometry here (a gap in the line's mapping, bridged straight).",
            "type": "boolean"
          },
          "rinf_section": {
            "description": "The RINF section of line (its id).",
            "type": [
              "string",
              "null"
            ]
          },
          "structure": {
            "description": "`tunnel` or `bridge`.",
            "type": [
              "string",
              "null"
            ]
          },
          "structure_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "to_km": {
            "format": "double",
            "type": "number"
          },
          "track_class": {
            "type": [
              "string",
              "null"
            ]
          },
          "track_class_source": {
            "type": [
              "string",
              "null"
            ]
          },
          "tracks": {
            "description": "Parallel tracks of the line (`/infra/lines` only).",
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "train_protection": {
            "description": "Class B systems (`PZB 90`, `LZB`).",
            "type": [
              "string",
              "null"
            ]
          },
          "train_protection_source": {
            "type": [
              "string",
              "null"
            ]
          },
          "voltage": {
            "description": "OSM, where electrified.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "from_km",
          "to_km",
          "length_m"
        ],
        "type": "object"
      },
      "TrainType": {
        "description": "The running characteristics' typical values.",
        "enum": [
          "freight",
          "passenger"
        ],
        "type": "string"
      },
      "UnassignedReason": {
        "description": "Why a unit is left out.",
        "enum": [
          "unreachable",
          "capacity",
          "time_window"
        ],
        "type": "string"
      },
      "UnconstrainedOut": {
        "description": "The route the vehicle's constraints rule out.",
        "properties": {
          "distance_km": {
            "format": "double",
            "type": "number"
          },
          "geometry": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/LineGeometry"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "distance_km"
        ],
        "type": "object"
      },
      "VectorLayer": {
        "description": "A source layer of the tiles.",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "Vehicle": {
        "description": "A vehicle: its infrastructure requirements and running characteristics\n(as a profile defines them and as a route answers with the effective\nvalues; 0 = the train type's typical value).",
        "properties": {
          "axle_load": {
            "type": "string"
          },
          "brake_decel_ms2": {
            "format": "double",
            "type": "number"
          },
          "davis_a_kn": {
            "format": "double",
            "type": "number"
          },
          "davis_b_kn_per_kmh": {
            "format": "double",
            "type": "number"
          },
          "davis_c_kn_per_kmh2": {
            "format": "double",
            "type": "number"
          },
          "electrification": {
            "description": "The systems it can draw power from; empty: it needs no electrification.",
            "items": {
              "$ref": "#/components/schemas/ElecSystemSpec"
            },
            "type": "array"
          },
          "gauge_mm": {
            "format": "int32",
            "minimum": 0,
            "type": "integer"
          },
          "gauging": {
            "type": "string"
          },
          "mass_t": {
            "format": "double",
            "type": "number"
          },
          "max_accel_ms2": {
            "format": "double",
            "type": "number"
          },
          "max_speed_kmh": {
            "description": "0: line speed.",
            "format": "double",
            "type": "number"
          },
          "max_tractive_effort_kn": {
            "format": "double",
            "type": "number"
          },
          "power_kw": {
            "format": "double",
            "type": "number"
          },
          "rotating_mass_factor": {
            "format": "double",
            "type": "number"
          },
          "train_length_m": {
            "format": "double",
            "type": "number"
          },
          "train_protection": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "train_type": {
            "$ref": "#/components/schemas/TrainType"
          }
        },
        "required": [
          "electrification",
          "gauge_mm",
          "max_speed_kmh",
          "train_protection",
          "train_length_m",
          "train_type",
          "mass_t",
          "power_kw",
          "max_tractive_effort_kn",
          "max_accel_ms2",
          "brake_decel_ms2",
          "rotating_mass_factor",
          "davis_a_kn",
          "davis_b_kn_per_kmh",
          "davis_c_kn_per_kmh2"
        ],
        "type": "object"
      },
      "VehicleInput": {
        "additionalProperties": false,
        "description": "Overrides of a profile's vehicle: fields that are present replace the\nprofile's (or the defaults': any track of 1,435 mm gauge, passenger train).",
        "properties": {
          "axle_load": {
            "description": "Minimum EN 15528 line category for the axle load (`D4`, `C2`, `CE`).",
            "type": [
              "string",
              "null"
            ]
          },
          "brake_decel_ms2": {
            "description": "Service braking (m/s²).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "davis_a_kn": {
            "description": "Running resistance A + B·v + C·v² (kN, v in km/h).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "davis_b_kn_per_kmh": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "davis_c_kn_per_kmh2": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "electrification": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Electrification"
              },
              {
                "type": "null"
              }
            ]
          },
          "gauge_mm": {
            "description": "Gauge in mm (300–2000).",
            "format": "int32",
            "minimum": 0,
            "type": [
              "integer",
              "null"
            ]
          },
          "gauging": {
            "description": "Gauging profile (`G1`, `G2`, `GA`, `GB`, `GC`, `DE3` …).",
            "type": [
              "string",
              "null"
            ]
          },
          "mass_t": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_accel_ms2": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_speed_kmh": {
            "description": "Running time and route cost at min(line speed, this) (km/h, 1–400; 0: line speed).",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "max_tractive_effort_kn": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "power_kw": {
            "description": "Rated power (kW); 85 % reaches the wheel.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "rotating_mass_factor": {
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "train_length_m": {
            "description": "For the estimate (m); not enforced in route choice.",
            "format": "double",
            "type": [
              "number",
              "null"
            ]
          },
          "train_protection": {
            "description": "Train protection systems on board (`pzb`, `lzb`, `etcs`, `zub` …): track\nwith protection data must have one of them. Empty: not checked.",
            "items": {
              "type": "string"
            },
            "type": [
              "array",
              "null"
            ]
          },
          "train_type": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/TrainType"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "publishable_key": {
        "description": "A publishable key (`rr_pk_…`) in `?key=`; accepted only from the browser origins registered for it.",
        "in": "query",
        "name": "key",
        "type": "apiKey"
      },
      "secret_key": {
        "description": "A secret key (`rr_sk_…`) in `Authorization: Bearer …`; server to server only.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "Rail routing on the European network. Errors are RFC 9457 problem details (`application/problem+json`).",
    "license": {
      "identifier": "LicenseRef-Proprietary",
      "name": "Proprietary"
    },
    "title": "railroute API",
    "version": "0.1.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/healthz": {
      "get": {
        "operationId": "health",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            },
            "description": "The server is running"
          }
        },
        "summary": "Liveness: the process answers.",
        "tags": [
          "operations"
        ]
      }
    },
    "/readyz": {
      "get": {
        "operationId": "ready",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ready"
                }
              }
            },
            "description": "A data version is loaded"
          },
          "503": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No data version is loaded yet"
          }
        },
        "summary": "Readiness: 200 once a data version is loaded (load balancers and the\nuptime monitor use it).",
        "tags": [
          "operations"
        ]
      }
    },
    "/styles/u/{file}": {
      "get": {
        "description": "The style saved in the dashboard, with its `railroute://` sources resolved\nto the current tile URLs (carrying the publishable key the style was\nfetched with). Needs a key of the style's account with the `tiles`\nscope; revalidate with `If-None-Match`.",
        "operationId": "getHostedStyle",
        "parameters": [
          {
            "description": "The style id with `.json`, e.g. `k3j9…q2.json`",
            "in": "path",
            "name": "file",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "The MapLibre style",
            "headers": {
              "etag": {
                "description": "Changes with the style, the data version, the basemap and the key",
                "schema": {
                  "type": "string"
                }
              },
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "Not modified (`If-None-Match`)"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such style for this key's account"
          },
          "422": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The stored style fails validation; save it again in the dashboard"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A hosted map style",
        "tags": [
          "maps"
        ],
        "x-railroute": {
          "scope": "tiles",
          "usage": "styles"
        }
      }
    },
    "/v1/basemap.json": {
      "get": {
        "description": "The tile URL of the basemap version being served (versioned apart from\nthe rail data). 404 while none is published.",
        "operationId": "getBasemapTileJson",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TileJson"
                }
              }
            },
            "description": "TileJSON 3.0",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No basemap is available"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "TileJSON of the basemap",
        "tags": [
          "maps"
        ],
        "x-railroute": {
          "scope": "tiles",
          "usage": "basemapjson"
        }
      }
    },
    "/v1/basemap/fonts/{fontstack}/{range}": {
      "get": {
        "description": "A glyph range of the first font of `fontstack` (the comma-separated\n`text-font` list of a layer) that the server has: Noto Sans Regular,\nMedium, Italic. Public: no key, not counted.",
        "operationId": "getBasemapGlyphs",
        "parameters": [
          {
            "description": "Comma-separated fonts",
            "example": "Noto Sans Regular",
            "in": "path",
            "name": "fontstack",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A glyph range",
            "example": "0-255.pbf",
            "in": "path",
            "name": "range",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/x-protobuf": {
                "schema": {
                  "$ref": "#/components/schemas/Binary"
                }
              }
            },
            "description": "The glyphs (protobuf)"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unknown font or range"
          }
        },
        "summary": "Basemap glyphs",
        "tags": [
          "maps"
        ]
      }
    },
    "/v1/basemap/sprites/{file}": {
      "get": {
        "description": "The sprite sheets of the basemap styles: `light`, `dark`, `white`,\n`grayscale`, `black`, as `.json` or `.png`, `@2x` for high DPI. Public.",
        "operationId": "getBasemapSprite",
        "parameters": [
          {
            "description": "Sprite file",
            "example": "light@2x.png",
            "in": "path",
            "name": "file",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/octet-stream": {
                "schema": {
                  "$ref": "#/components/schemas/Binary"
                }
              }
            },
            "description": "The sprite index or image"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unknown sprite"
          }
        },
        "summary": "Basemap sprites",
        "tags": [
          "maps"
        ]
      }
    },
    "/v1/basemap/{version}/{z}/{x}/{y}": {
      "get": {
        "description": "Mapbox Vector Tile of the basemap version from `basemap.json`.",
        "operationId": "getBasemapTile",
        "parameters": [
          {
            "description": "The basemap version, from `basemap.json`",
            "in": "path",
            "name": "version",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Zoom",
            "in": "path",
            "name": "z",
            "required": true,
            "schema": {
              "format": "int32",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Column",
            "in": "path",
            "name": "x",
            "required": true,
            "schema": {
              "format": "int32",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Row, with `.mvt`",
            "example": "21134.mvt",
            "in": "path",
            "name": "y",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/vnd.mapbox-vector-tile": {
                "schema": {
                  "$ref": "#/components/schemas/Binary"
                }
              }
            },
            "description": "The tile",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "204": {
            "description": "An empty tile",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Another basemap version, or none"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A basemap tile",
        "tags": [
          "maps"
        ],
        "x-railroute": {
          "scope": "tiles",
          "usage": "basemap"
        }
      }
    },
    "/v1/changes": {
      "get": {
        "description": "What was added, removed or changed (OSM tags, RINF attributes, geometry)\nin a data version against the one before it, object by object, with the\nids of the infrastructure API. Without `version` and `since`: the version\nbeing served. Poll with `since=<the last version you saw>`, or subscribe\nto webhooks (`/v1/changes/subscriptions`).",
        "operationId": "getChanges",
        "parameters": [
          {
            "description": "One version's changes (default: the version being served).",
            "in": "query",
            "name": "version",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "All versions after this one (up to the version being served), oldest first.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "minLon,minLat,maxLon,maxLat: changes whose bbox intersects it.",
            "in": "query",
            "name": "bbox",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated line refs, e.g. `1043,1220`.",
            "in": "query",
            "name": "line",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated object types (`track` includes `tunnel` and `bridge`).",
            "in": "query",
            "name": "types",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated: `added`, `removed`, `changed`.",
            "in": "query",
            "name": "change",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "A subscription id of this account: its filter applies too.",
            "in": "query",
            "name": "subscription",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Changes per page (1–2000, default 500).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangesResponse"
                }
              }
            },
            "description": "Changes, oldest version first",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Unknown version, no change set, or `since` not in the history"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Infrastructure changes between data versions",
        "tags": [
          "changes"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "changes"
        }
      }
    },
    "/v1/changes/subscriptions": {
      "get": {
        "description": "The account's subscriptions, each with its last delivery.",
        "operationId": "listChangeSubscriptions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionList"
                }
              }
            },
            "description": "The subscriptions",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "List subscriptions",
        "tags": [
          "changes"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "changes/subscriptions"
        }
      },
      "post": {
        "description": "Creates a webhook subscription: every new data version with changes that\nmatch the filter (all filters given must match) is POSTed to `url`,\nsigned with the secret returned here (only here). Verify the\n`Railroute-Signature` header: `t=<unix s>,v1=<hex HMAC-SHA256 of \"<t>.<body>\">`.",
        "operationId": "createChangeSubscription",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscriptionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionView"
                }
              }
            },
            "description": "Created; the secret is shown once",
            "headers": {
              "location": {
                "description": "The subscription's URL",
                "schema": {
                  "type": "string"
                }
              },
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "The account has the maximum number of subscriptions"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Subscribe to changes",
        "tags": [
          "changes"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "changes/subscriptions"
        }
      }
    },
    "/v1/changes/subscriptions/{id}": {
      "delete": {
        "description": "Deletes the subscription and its pending deliveries.",
        "operationId": "deleteChangeSubscription",
        "parameters": [
          {
            "description": "`sub_…`",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such subscription for this account"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Delete a subscription",
        "tags": [
          "changes"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "changes/subscription"
        }
      },
      "get": {
        "description": "One subscription of the account, with its last delivery.",
        "operationId": "getChangeSubscription",
        "parameters": [
          {
            "description": "`sub_…`",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionView"
                }
              }
            },
            "description": "The subscription",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such subscription for this account"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A subscription",
        "tags": [
          "changes"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "changes/subscription"
        }
      }
    },
    "/v1/changes/subscriptions/{id}/test": {
      "post": {
        "description": "Queues a `test` event to the subscription's URL; a worker sends it within\nseconds. Its state shows as `last_delivery`.",
        "operationId": "testChangeSubscription",
        "parameters": [
          {
            "description": "`sub_…`",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestQueued"
                }
              }
            },
            "description": "Queued",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such subscription for this account"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Send a test event",
        "tags": [
          "changes"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "changes/subscription/test"
        }
      }
    },
    "/v1/dataset": {
      "get": {
        "description": "Describes the data version this request was answered from: its name,\nwhen it was built and the size of its network.",
        "operationId": "getDataset",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetInfo"
                }
              }
            },
            "description": "The data version",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "The data version being served",
        "tags": [
          "data"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "dataset"
        }
      }
    },
    "/v1/infra/along-route": {
      "post": {
        "description": "A route as `POST /v1/route` finds it (same places, vehicle, `avoid`),\ndescribed by its infrastructure: stretches of equal infrastructure with\nkm along the route (line, speed, electrification, gauge, line category\nand load, gauging, ETCS and class B protection, structures, RINF\nsection, parallel tracks, each value with its source), the lines in\ntravel order, and the infrastructure objects on its track nodes\n(signals, switches, level crossings, border points; `types` filters)\nwith their km. Without a route, `status` is `no_route` and `no_route`\nexplains it as in `POST /v1/route`. Counts as one request per leg.",
        "operationId": "infraAlongRoute",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AlongRouteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlongRouteResponse"
                }
              }
            },
            "description": "The route's infrastructure, or why there is no route",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "The infrastructure along a route",
        "tags": [
          "infrastructure"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "infra/along-route"
        }
      }
    },
    "/v1/infra/lines/{line}": {
      "get": {
        "description": "A line (by number) as km-based sections of equal infrastructure: speed,\nelectrification, track class and load, gauging, ETCS and class B\nprotection, structures, RINF section, and the number of parallel tracks;\nwith geometry and km jumps. The whole line (each calibrated piece), or\n`from_km`–`to_km` (in that direction).",
        "operationId": "getInfraLine",
        "parameters": [
          {
            "description": "Line number",
            "example": "1220",
            "in": "path",
            "name": "line",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start of the km range (with `to_km`; neither = the whole line).",
            "in": "query",
            "name": "from_km",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "in": "query",
            "name": "to_km",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineInfra"
                }
              }
            },
            "description": "The line's infrastructure",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such calibrated line, or km not on it (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A line's infrastructure",
        "tags": [
          "infrastructure"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "infra/lines"
        }
      }
    },
    "/v1/infra/objects": {
      "get": {
        "description": "Every object touching the box, in ID order, as GeoJSON Features:\ntrack, tunnels and bridges (with their effective infrastructure, RINF\nover OSM), stations (with platforms), RINF operational points, platforms,\nsignals, switches, level crossings, yards, freight terminals, depots and\nborder points. Paginated (`limit` default 500, at most 2000).",
        "operationId": "listInfraObjects",
        "parameters": [
          {
            "description": "`minLon,minLat,maxLon,maxLat`, at most 0.25 deg².",
            "example": "9.98,53.54,10.02,53.56",
            "in": "query",
            "name": "bbox",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated object types (default all); `track` includes tunnels and bridges.",
            "in": "query",
            "name": "types",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Results per page (default and maximum depend on the endpoint).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page; omit it for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeaturePage"
                }
              }
            },
            "description": "The objects",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Infrastructure objects in a box",
        "tags": [
          "infrastructure"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "infra/objects"
        }
      }
    },
    "/v1/infra/objects/{id}": {
      "get": {
        "description": "An object by ID (`way:<osm id>`, `node:<osm id>`, `rinf-op:<UOPID>`; `/`\nmay be written as `:` or escaped) with all its attributes, OSM and RINF\napart. A RINF operational point that is part of an OSM station is found\nunder the station (the 404 says which).",
        "operationId": "getInfraObject",
        "parameters": [
          {
            "description": "The object's ID",
            "example": "rinf-op:DE000AH",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Feature"
                }
              }
            },
            "description": "The object",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such object (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "One infrastructure object",
        "tags": [
          "infrastructure"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "infra/object"
        }
      }
    },
    "/v1/infra/search": {
      "get": {
        "description": "Non-station objects by name or reference: sidings, yards, freight\nterminals, depots and workshops, border points, level crossings, tunnels\nand bridges (stations, halts and operational points: `/v1/places`).\nParts of one object (a tunnel mapped as several ways) are one result.\nWithout `q`, every object in `bbox`. Paginated (`limit` default 10, at most 50).",
        "operationId": "searchInfra",
        "parameters": [
          {
            "description": "A name or reference (any spelling, typos tolerated); without `q`, `bbox` is required.",
            "example": "maschen",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated categories (default all): `siding`, `yard`,\n`freight_terminal`, `depot`, `border_point`, `level_crossing`, `tunnel`, `bridge`.",
            "in": "query",
            "name": "types",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "`minLon,minLat,maxLon,maxLat`: only objects inside (at most 0.25 deg² without `q`).",
            "in": "query",
            "name": "bbox",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Results per page (default and maximum depend on the endpoint).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page; omit it for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InfraMatches"
                }
              }
            },
            "description": "Objects, best first",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Search infrastructure",
        "tags": [
          "infrastructure"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "infra/search"
        }
      }
    },
    "/v1/isochrone": {
      "post": {
        "description": "The track a vehicle reaches within a time and/or distance, in bands:\nlines per band (the last stretch cut at the limit), the stations and\noperational points reached (time and distance of the route there) and,\nwith `polygons`, the area around the track. Billed one request per band.",
        "operationId": "isochrone",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IsochroneRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IsochroneResult"
                }
              }
            },
            "description": "The isochrone",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "The network reached from a place",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "isochrone"
        }
      }
    },
    "/v1/linref/lines": {
      "get": {
        "description": "The lines with linear referencing in this data version, by line number.\nPaginated (`limit` default 100, at most 1000).",
        "operationId": "listLinRefLines",
        "parameters": [
          {
            "description": "Results per page (default and maximum depend on the endpoint).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page; omit it for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineSummaries"
                }
              }
            },
            "description": "The lines",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Calibrated lines",
        "tags": [
          "linear referencing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "linref/lines"
        }
      }
    },
    "/v1/linref/locate": {
      "get": {
        "description": "Coordinates → the lines within the radius, nearest first, with the\npoint's km, side offset and distance. Paginated (`limit` default 5, at most 20).",
        "operationId": "locateOnLines",
        "parameters": [
          {
            "example": 54.315,
            "in": "query",
            "name": "lat",
            "required": true,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "example": 10.131,
            "in": "query",
            "name": "lon",
            "required": true,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "Search radius (m), 1 to 2000; default 100.",
            "in": "query",
            "name": "radius_m",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "Only this line.",
            "in": "query",
            "name": "line",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Results per page (default and maximum depend on the endpoint).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page; omit it for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineKms"
                }
              }
            },
            "description": "Lines near the point",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such calibrated line (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Locate a point on the lines",
        "tags": [
          "linear referencing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "linref/locate"
        }
      }
    },
    "/v1/linref/position": {
      "get": {
        "description": "Line + km (+ side offset) → coordinates. 404 if the line has no such km\n(the detail lists its km ranges).",
        "operationId": "positionOnLine",
        "parameters": [
          {
            "description": "Line number.",
            "example": "1220",
            "in": "query",
            "name": "line",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 12.3,
            "in": "query",
            "name": "km",
            "required": true,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "Right (+) or left (−) of the line in the direction of increasing km (m), ±500.",
            "in": "query",
            "name": "offset_m",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinePosition"
                }
              }
            },
            "description": "The point(s)",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such line or km (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "The point at a km of a line",
        "tags": [
          "linear referencing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "linref/position"
        }
      }
    },
    "/v1/linref/segment": {
      "get": {
        "description": "Line + km range → geometry and the infrastructure along it. Both km must\nlie on the same continuous piece of the line.",
        "operationId": "lineSegment",
        "parameters": [
          {
            "description": "Line number.",
            "example": "1220",
            "in": "query",
            "name": "line",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "example": 10.0,
            "in": "query",
            "name": "from_km",
            "required": true,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "example": 12.5,
            "in": "query",
            "name": "to_km",
            "required": true,
            "schema": {
              "format": "double",
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineSegment"
                }
              }
            },
            "description": "The stretch",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such line, or km not on it (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "The stretch of a line between two km",
        "tags": [
          "linear referencing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "linref/segment"
        }
      }
    },
    "/v1/match": {
      "post": {
        "description": "The body is a trace: GPX (track or route points, `<time>`), GeoJSON (a\nLineString/MultiLineString with `properties.coordTimes` or `times`, or\nPoint features with `properties.time`) or CSV (a header naming `lat`,\n`lon` and optionally `time`; `,` `;` or tab). Times are ISO 8601 or\nunix seconds; at most 10,000 points. A hidden Markov model (GPS error vs\nroute distance on the track network with its turn rules) picks the path;\nper point the track (and whether parallel tracks can be told apart), the\nline and line km; per section the lines and infrastructure along it.\nBilled per point (0.01 requests each).",
        "operationId": "matchTrace",
        "parameters": [
          {
            "description": "GPS accuracy, σ of the error (m), 1 to 100; default 15.",
            "in": "query",
            "name": "gps_accuracy_m",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "How far from a point to look for track (m), 5 to 500; default max(25, 4σ).",
            "in": "query",
            "name": "search_radius_m",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "Fastest plausible speed (km/h), 10 to 500; default 300.",
            "in": "query",
            "name": "max_speed_kmh",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "`gpx`, `geojson` or `csv`; default from `Content-Type`, else the body.",
            "in": "query",
            "name": "format",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/geo+json": {
              "schema": {
                "type": "object"
              }
            },
            "application/gpx+xml": {
              "schema": {
                "type": "string"
              }
            },
            "text/csv": {
              "schema": {
                "type": "string"
              }
            }
          },
          "description": "The trace",
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchResponse"
                }
              }
            },
            "description": "The matched path",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Trace too large or too costly to match (`payload-too-large`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Match a GPS trace to the track",
        "tags": [
          "map matching"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "match"
        }
      }
    },
    "/v1/matrix": {
      "post": {
        "description": "From every origin to every destination, for one vehicle. Up to 250,000\nelements (origins × destinations) the matrix is the answer (200); larger\nones, or with `\"async\": true`, become a job (202, `Location`: poll it at\n`GET /v1/matrix/jobs/{id}`). The same request again returns the same job\n(200) while it exists. Billed per element; a job when it is accepted.",
        "operationId": "matrix",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatrixRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatrixResult"
                }
              }
            },
            "description": "The matrix, or the job of the same request",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatrixJob"
                }
              }
            },
            "description": "Accepted as a job; poll `Location`",
            "headers": {
              "location": {
                "description": "Where to poll the job",
                "schema": {
                  "type": "string"
                }
              },
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "More elements than the plan allows (`too-large`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Travel times and distances between many places",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "matrix"
        }
      }
    },
    "/v1/matrix/jobs/{id}": {
      "get": {
        "description": "Its status and progress; once done, the matrix. Jobs are kept for an\nhour after they finish and answer only keys of the account that\nsubmitted them (others: 404).",
        "operationId": "getMatrixJob",
        "parameters": [
          {
            "description": "The job id (`mx_…`)",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatrixJob"
                }
              }
            },
            "description": "The job",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such job (`job-not-found`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A matrix job",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "matrix"
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "operationId": "openapi",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "The OpenAPI document"
          }
        },
        "summary": "This document (OpenAPI 3.1).",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/optimize": {
      "post": {
        "description": "Which vehicle serves which stops in which order: jobs (single stops)\nand shipments (pickup, then delivery, on one vehicle), with capacities,\ntime windows and each vehicle's routing constraints. Up to 100 stops\n(and a time limit up to 10 s) the answer comes at once (200); larger\nproblems, or `\"async\": true`, become a job (202, `Location`: poll\n`GET /v1/optimize/jobs/{id}`); the same request again returns that job\n(200). Billed per matrix element (distinct locations² × distinct\nvehicle profiles).",
        "operationId": "optimize",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OptimizeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OptimizeResult"
                }
              }
            },
            "description": "The solution, or the job of the same request",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OptimizationJob"
                }
              }
            },
            "description": "Accepted as a job; poll `Location`",
            "headers": {
              "location": {
                "description": "Where to poll the job",
                "schema": {
                  "type": "string"
                }
              },
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "More vehicles, stops or matrix elements than the plan allows (`too-large`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Optimize stops over vehicles",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "optimize"
        }
      }
    },
    "/v1/optimize/jobs/{id}": {
      "get": {
        "description": "Its status and progress; once done, the solution. Kept for an hour after\nit finishes, for keys of the account that submitted it (others: 404).",
        "operationId": "getOptimizationJob",
        "parameters": [
          {
            "description": "The job id (`op_…`)",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OptimizationJob"
                }
              }
            },
            "description": "The job",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such job (`job-not-found`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A route optimization job",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "optimize"
        }
      }
    },
    "/v1/places": {
      "get": {
        "description": "Stations, halts and operational points by name or code, ranked: the\nmatch class first (see `match.class`), then stations before halts before\noperational points, then the closer name, then more lines nearby.\nNames match in any spelling (umlauts as `ü`, `ue` or `u`; `ß` as `ss`;\n`Hbf`, `Bf`, `Rbf`, `St.` … as abbreviations), typos only when nothing\nbetter is found. Typed diacritics are meant: \"Fürth\" doesn't find \"Furth\".\nPaginated (`limit` default 10, at most 50).",
        "operationId": "searchPlaces",
        "parameters": [
          {
            "description": "A name (any spelling: \"Lübeck Hbf\", \"luebeck hauptbahnhof\", \"lubeck\", typos\ntolerated), a DS100 code (`AH`), a RINF UOPID (`DE000AH`) or a UIC code.",
            "example": "kiel hbf",
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated kinds: `station`, `halt`, `operational_point` (default all).",
            "in": "query",
            "name": "kinds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO 3166-1 alpha-2; places of unknown country are left out.",
            "in": "query",
            "name": "country",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only places inside `minLon,minLat,maxLon,maxLat`.",
            "in": "query",
            "name": "bbox",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Results per page (default and maximum depend on the endpoint).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page; omit it for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceMatches"
                }
              }
            },
            "description": "Places, best first",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Search places",
        "tags": [
          "places"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "geocode"
        }
      }
    },
    "/v1/places/autocomplete": {
      "get": {
        "description": "For a search box, one call per keystroke: prefixes only (no typos, no\nsubstrings), answered from a prefix index. \"kiel h\" → Kiel Hauptbahnhof,\n\"AK\" → the place with DS100 code AK. Ranking: match quality, then kind,\nlines nearby and the name's length, plus a bias towards `focus` or into\n`bbox`. Billed at 0.2 requests per call. Paginated (`limit` default 8, at most 20).",
        "operationId": "autocompletePlaces",
        "parameters": [
          {
            "description": "What has been typed so far (every word a prefix of a word of the name,\nor a code prefix).",
            "example": "kiel h",
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated kinds: `station`, `halt`, `operational_point` (default all).",
            "in": "query",
            "name": "kinds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "ISO 3166-1 alpha-2; places of unknown country are left out.",
            "in": "query",
            "name": "country",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "`lat,lon`: closer places rank higher (e.g. the map centre).",
            "in": "query",
            "name": "focus",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Distance from `focus` at which its bonus halves (km, default 50).",
            "in": "query",
            "name": "focus_scale_km",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "`minLon,minLat,maxLon,maxLat`: places inside rank higher (a bias, not a filter).",
            "in": "query",
            "name": "bbox",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Results per page (default and maximum depend on the endpoint).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page; omit it for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Suggestions"
                }
              }
            },
            "description": "Suggestions, best first",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Autocomplete place names",
        "tags": [
          "places"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "autocomplete"
        }
      }
    },
    "/v1/places/lookup": {
      "get": {
        "description": "Exact codes only (no names, no fuzziness): DS100/RL100, RINF\noperational point IDs, UIC codes — the codes present in the data.\nStations before halts before operational points. 404 if no place has the\ncode. Paginated (`limit` default 10, at most 50).",
        "operationId": "lookupPlaces",
        "parameters": [
          {
            "description": "A DS100/RL100 code (`AH`, `MH  W` = `MH W`), a RINF UOPID (`DE000AH`)\nor a UIC code (`8002549`); case and repeated spaces don't matter.",
            "example": "AH",
            "in": "query",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Results per page (default and maximum depend on the endpoint).",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "format": "int32",
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`next_cursor` of the previous page; omit it for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CodeMatches"
                }
              }
            },
            "description": "The places with the code",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No place has the code (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Look places up by code",
        "tags": [
          "places"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "lookup"
        }
      }
    },
    "/v1/places/reverse": {
      "get": {
        "description": "Coordinates → the nearest place, the nearest track and its line km.\n404 if there is neither place nor track within the radius.",
        "operationId": "reverseGeocode",
        "parameters": [
          {
            "example": 54.3146,
            "in": "query",
            "name": "lat",
            "required": true,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "example": 10.1319,
            "in": "query",
            "name": "lon",
            "required": true,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "Search radius (m), 1 to 5000; default 1000.",
            "in": "query",
            "name": "radius_m",
            "required": false,
            "schema": {
              "format": "double",
              "type": "number"
            }
          },
          {
            "description": "Comma-separated place kinds for `place` (default all).",
            "in": "query",
            "name": "kinds",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReverseResult"
                }
              }
            },
            "description": "What is at the point",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Nothing within the radius (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Reverse geocode a point",
        "tags": [
          "places"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "reverse"
        }
      }
    },
    "/v1/places/{id}": {
      "get": {
        "description": "A place by its `id` (`node:<osm id>`, `rinf-op:<UOPID>`; `/` may be\nwritten as `:` or escaped): codes, names, its OSM stations and RINF\noperational points, and its platforms (lengths, heights, tracks).",
        "operationId": "getPlace",
        "parameters": [
          {
            "description": "The place's `id`",
            "example": "rinf-op:DE000AH",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceDetail"
                }
              }
            },
            "description": "The place",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "No such place (`not-in-data`)"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "One place",
        "tags": [
          "places"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "lookup"
        }
      }
    },
    "/v1/route": {
      "post": {
        "description": "The best route from `from` through `via` to `to` for a vehicle, as one\ntrain path (it continues at via points the way it arrives; reversing only\nnear stations, at the reversal's cost). Places are stations by code\n(DS100, UOPID, UIC), coordinates (snapped onto track within 1.5 km,\nstarting or ending inside track between junctions) or OSM nodes. The\nvehicle is a built-in profile (`GET /v1/route/profiles`) with overrides;\n`avoid` excludes lines and areas. The response has distance, running\ntime and legs; geometry, segments and the report parts (sections, lines,\noperational points, countries and borders, infrastructure managers,\nsystem changes, running time estimate, track access charges, capacity)\ncome with `include`. Without a route the status is `no_route` and\n`no_route` explains which stretches rule it out. Counts as one request per leg.",
        "operationId": "route",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RouteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteResponse"
                }
              }
            },
            "description": "The route, or why there is none",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A route",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "route"
        }
      }
    },
    "/v1/route/batch": {
      "post": {
        "description": "Up to 25 routes (100 on the invoice plan) for one vehicle, each answered\nas `POST /v1/route` answers it, computed in parallel; the options apply\nto every route. A route that is invalid (unknown station, no track near\na place) has status `error` with the problem `POST /v1/route` would\nreturn; the others are `ok` or `no_route`. Counts as one request per leg\nof the routes that aren't errors (at least one).",
        "operationId": "routeBatch",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            },
            "description": "Each route's outcome, in request order",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "Many routes",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "route"
        }
      }
    },
    "/v1/route/profiles": {
      "get": {
        "description": "The vehicles `profile` can name, with their requirements and running\ncharacteristics; a route request overrides what differs with `vehicle`.",
        "operationId": "routeProfiles",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfilesResponse"
                }
              }
            },
            "description": "The profiles",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "The built-in vehicle profiles",
        "tags": [
          "routing"
        ],
        "x-railroute": {
          "scope": "route",
          "usage": "route"
        }
      }
    },
    "/v1/tiles.json": {
      "get": {
        "description": "The tile URL of the data version being served, its zoom range, bounds and\nlayers (`tracks`, `signals`, `switches`, `level_crossings`, `platforms`,\n`sites`). A publishable key in `?key=` is carried into the tile URL.",
        "operationId": "getTileJson",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TileJson"
                }
              }
            },
            "description": "TileJSON 3.0",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "This data version has no tiles"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "TileJSON of the rail network",
        "tags": [
          "maps"
        ],
        "x-railroute": {
          "scope": "tiles",
          "usage": "tilejson"
        }
      }
    },
    "/v1/tiles/{version}/{z}/{x}/{y}": {
      "get": {
        "description": "Mapbox Vector Tile (gzip-compressed: `Content-Encoding: gzip`). 204 for an\nempty tile. The version must be the one being served (from `tiles.json`).",
        "operationId": "getTile",
        "parameters": [
          {
            "description": "The data version, from `tiles.json`",
            "in": "path",
            "name": "version",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Zoom",
            "in": "path",
            "name": "z",
            "required": true,
            "schema": {
              "format": "int32",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Column",
            "in": "path",
            "name": "x",
            "required": true,
            "schema": {
              "format": "int32",
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "Row, with `.mvt`",
            "example": "21134.mvt",
            "in": "path",
            "name": "y",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/vnd.mapbox-vector-tile": {
                "schema": {
                  "$ref": "#/components/schemas/Binary"
                }
              }
            },
            "description": "The tile",
            "headers": {
              "content-encoding": {
                "description": "`gzip` (tiles are stored compressed)",
                "schema": {
                  "type": "string"
                }
              },
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "204": {
            "description": "An empty tile",
            "headers": {
              "ratelimit-limit": {
                "description": "Requests per minute this key allows.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "ratelimit-remaining": {
                "description": "Requests left in this key's bucket.",
                "schema": {
                  "minimum": 0,
                  "type": "integer"
                }
              },
              "x-data-version": {
                "description": "The data version that answered.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "description": "Another data version, or no tiles"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        },
        "security": [
          {
            "secret_key": []
          },
          {
            "publishable_key": []
          }
        ],
        "summary": "A vector tile of the rail network",
        "tags": [
          "maps"
        ],
        "x-railroute": {
          "scope": "tiles",
          "usage": "tiles"
        }
      }
    }
  },
  "servers": [
    {
      "description": "Production",
      "url": "https://api.routing.gleisklar.de"
    }
  ],
  "tags": [
    {
      "description": "The data version being served",
      "name": "data"
    },
    {
      "description": "Stations, halts and operational points: search, autocomplete, codes, reverse geocoding, platforms",
      "name": "places"
    },
    {
      "description": "Infrastructure objects (OSM and RINF), infrastructure search, a line's properties",
      "name": "infrastructure"
    },
    {
      "description": "Line numbers and km (Streckenkilometer): locate, position, segment",
      "name": "linear referencing"
    },
    {
      "description": "GPS traces matched to the track",
      "name": "map matching"
    },
    {
      "description": "Vector tiles of the rail network, the basemap, and hosted map styles",
      "name": "maps"
    },
    {
      "description": "What changed between data versions: the change feed and webhook subscriptions",
      "name": "changes"
    },
    {
      "description": "Routes for a vehicle: via points, profiles, avoided lines and areas, alternatives, batches; the route report",
      "name": "routing"
    },
    {
      "description": "Health, readiness and this document; no API key needed",
      "name": "operations"
    }
  ]
}
