{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/digitraffic-fi/json-schema/digitraffic-fi-train-schema.json",
  "title": "Train",
  "x-generated": "2026-11-11",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/digitraffic-fi-rail-api-openapi.yml#/components/schemas/Train",
  "required": [
    "departureDate",
    "trainNumber"
  ],
  "type": "object",
  "properties": {
    "trainNumber": {
      "type": "integer",
      "description": "Identifies the train inside a single departure date",
      "format": "int64"
    },
    "departureDate": {
      "type": "string",
      "description": "Date of the train's first departure",
      "format": "date"
    },
    "operatorUICCode": {
      "type": "integer",
      "description": "Official UIC code of the operator",
      "format": "int32"
    },
    "operatorShortCode": {
      "type": "string",
      "description": "Short code of the operator"
    },
    "trainType": {
      "type": "string"
    },
    "trainCategory": {
      "type": "string"
    },
    "commuterLineID": {
      "type": "string"
    },
    "runningCurrently": {
      "type": "boolean",
      "description": "Is the train running currently or does it have actual times"
    },
    "cancelled": {
      "type": "boolean",
      "description": "Is the train wholly cancelled"
    },
    "deleted": {
      "type": "boolean",
      "description": "Is the train deleted which means cancelled 10 days before its departure date"
    },
    "version": {
      "type": "integer",
      "description": "When was train last modified",
      "format": "int64"
    },
    "timetableType": {
      "type": "string",
      "description": "Is the train ADHOC or REGULAR. REGULAR trains are run for example every monday, ADHOC trains are one-time trains",
      "enum": [
        "REGULAR",
        "ADHOC"
      ]
    },
    "timetableAcceptanceDate": {
      "type": "string",
      "description": "When was this train accepted to run on Finnish railways by the FTA",
      "format": "date-time"
    },
    "timeTableRows": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/TimeTableRow"
      }
    }
  },
  "$defs": {
    "Cause": {
      "title": "Cause",
      "required": [
        "categoryCode",
        "categoryName",
        "validFrom"
      ],
      "type": "object",
      "properties": {
        "passengerTerm": {
          "$ref": "#/$defs/PassengerTerm"
        },
        "categoryCode": {
          "type": "string",
          "description": "Official code"
        },
        "categoryName": {
          "type": "string",
          "description": "Official name"
        },
        "validFrom": {
          "type": "string",
          "description": "Start date when this category code is used",
          "format": "date"
        },
        "validTo": {
          "type": "string",
          "description": "End date when this code is used. Empty means category is used until further notice",
          "format": "date"
        },
        "id": {
          "type": "integer",
          "format": "int32"
        },
        "detailedCategoryCode": {
          "type": "string"
        },
        "detailedCategoryName": {
          "type": "string"
        },
        "thirdCategoryCode": {
          "type": "string"
        },
        "thirdCategoryName": {
          "type": "string"
        },
        "description": {
          "type": "string",
          "description": "Detailed description"
        },
        "categoryCodeId": {
          "type": "integer",
          "format": "int32"
        },
        "detailedCategoryCodeId": {
          "type": "integer",
          "format": "int32"
        },
        "thirdCategoryCodeId": {
          "type": "integer",
          "format": "int32"
        }
      },
      "description": "Details why a train is not on schedule. Train-responses only have ids and codes populated."
    },
    "PassengerTerm": {
      "title": "PassengerTerm",
      "type": "object",
      "properties": {
        "fi": {
          "type": "string",
          "description": "Finnish passenger friendly term for the code"
        },
        "en": {
          "type": "string",
          "description": "English passenger friendly term for the code"
        },
        "sv": {
          "type": "string",
          "description": "Swedish passenger friendly term for the code"
        }
      }
    },
    "TimeTableRow": {
      "title": "TimeTableRow",
      "required": [
        "scheduledTime",
        "type"
      ],
      "type": "object",
      "properties": {
        "stationShortCode": {
          "type": "string"
        },
        "stationUICCode": {
          "type": "integer",
          "format": "int32"
        },
        "countryCode": {
          "type": "string"
        },
        "type": {
          "type": "string",
          "enum": [
            "ARRIVAL",
            "DEPARTURE"
          ]
        },
        "trainStopping": {
          "type": "boolean",
          "description": "Does the train actual stop on the station"
        },
        "commercialStop": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "Is the stop 'commercial' ie. loading/unloading of passengers or cargo"
        },
        "cancelled": {
          "type": "boolean",
          "description": "Is the schedule part cancelled"
        },
        "scheduledTime": {
          "type": "string",
          "description": "Scheduled time for departure/arrival of the train",
          "format": "date-time"
        },
        "estimateSource": {
          "type": "string",
          "description": "Source for the estimate",
          "enum": [
            "LIIKE_USER",
            "MIKU_USER",
            "LIIKE_AUTOMATIC",
            "UNKNOWN",
            "COMBOCALC"
          ]
        },
        "unknownDelay": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "Set if the train is delayed, but it is impossible to estimate for how long"
        },
        "unknownTrack": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "Set if the track is not known"
        },
        "actualTime": {
          "type": [
            "string",
            "null"
          ],
          "description": "Actual time when train departured or arrived on the station",
          "format": "date-time"
        },
        "differenceInMinutes": {
          "type": "integer",
          "description": "Difference between schedule and actual time in minutes",
          "format": "int64"
        },
        "causes": {
          "uniqueItems": true,
          "type": "array",
          "items": {
            "$ref": "#/$defs/Cause"
          }
        },
        "stopSector": {
          "type": [
            "string",
            "null"
          ]
        },
        "commercialTrack": {
          "type": "string",
          "description": "Track where the train stops"
        },
        "liveEstimateTime": {
          "type": "string",
          "description": "Estimated time for departure/arrival of the train",
          "format": "date-time"
        },
        "trainReady": {
          "$ref": "#/$defs/TrainReady"
        }
      },
      "description": "A part of train's schedule"
    },
    "TrainReady": {
      "title": "TrainReady",
      "type": "object",
      "properties": {
        "source": {
          "type": "string",
          "description": "How was the permission given",
          "enum": [
            "PHONE",
            "LIIKE",
            "UNKNOWN",
            "KUPLA"
          ]
        },
        "accepted": {
          "type": "boolean",
          "description": "Was the permission given"
        },
        "timestamp": {
          "type": "string",
          "description": "When was the permission given",
          "format": "date-time"
        }
      },
      "description": "Operator has to ask permission (=TrainReady) to leave certain stations"
    }
  }
}