A train document contains trainNumber, operator, extraTrain, routeNumber, continuesAs, a static defaultRoute (scheduled timetable, using hour/minute time objects), and a live currentRoute (actual dates used for real-time tracking), plus currentFormation, position, and messages.
Creates a new train. defaultRoute is validated and converted into a UTC currentRoute automatically.
Body
{
"trainNumber": "301",
"operator": "PTR",
"extraTrain": false,
"routeNumber": "R81",
"continuesAs": null,
"defaultRoute": [
{
"name": "Skogviken",
"code": "SK",
"type": "stasjon",
"track": "1",
"arrival": { "hours": 8, "minutes": 0 },
"departure": { "hours": 8, "minutes": 2 },
"stopType": "passenger"
}
]
}
Returns 400 for missing fields or an invalid route, 409 if trainNumber already exists.
Returns all trains, or filters by query string (e.g. /trains?operator=PTR). Query parameters are matched against top-level train fields. Returns 200 with a JSON array of train documents (see the example below), or [] if no trains match.
Response (200 OK)
[
{
"_id": "665f1c2e9b1e8a0012a4b7c3",
"trainNumber": "301",
"operator": "PTR",
"extraTrain": false,
"routeNumber": "R81",
"continuesAs": null,
"defaultRoute": [
{
"name": "Skogviken",
"code": "SK",
"type": "stasjon",
"track": "1",
"arrival": { "hours": 8, "minutes": 0 },
"departure": { "hours": 8, "minutes": 2 },
"stopType": "passenger",
"passed": false,
"cancelledAtStation": false
}
],
"currentRoute": [
{
"name": "Skogviken",
"code": "SK",
"type": "stasjon",
"track": "1",
"arrival": "2026-10-08T06:00:00.000Z",
"departure": "2026-10-08T06:02:00.000Z",
"stopType": "passenger",
"passed": false,
"cancelledAtStation": false
}
],
"currentFormation": {},
"position": [],
"messages": [],
"__v": 0
}
]
Times in defaultRoute are local Norway time as hours/minutes objects. Times in currentRoute are UTC ISO 8601 strings. messages entries look like { "yellow": false, "message": { "NOR": "...", "ENG": "..." }, "from": "<ISO date>", "to": "<ISO date>" }.
Returns a single train document by its train number (same shape as one element of GET /trains), or 404 with { "error": "Train not found" } if it doesn't exist.
Example: GET /trains/301 → 200 with a single train object.
Returns the train's currentRoute with arrival/departure times formatted in Norway local time (dd.MM.yyyy HH:mm) instead of raw UTC dates. 404 if the train doesn't exist.
Response (200 OK)
[
{
"name": "Skogviken",
"code": "SK",
"type": "stasjon",
"track": "1",
"arrival": "08.10.2026 08:00",
"departure": "08.10.2026 08:02",
"stopType": "passenger",
"passed": false,
"cancelledAtStation": false
}
]
arrival and departure are null if the stop has no time set.
Partially updates a train. Any arrival/departure values in the body are converted to Date objects. Returns 409 if renaming to a trainNumber already in use, 404 if the train doesn't exist.
Replaces a train entirely (upserts). Body must be { "trainData": { ... } } containing all of: trainNumber, operator, extraTrain, defaultRoute, currentRoute, currentFormation, position.
Returns 409 if changing to a trainNumber that's already used by another train.
Deletes a train and its associated FIDO train claim. Returns 204 No Content on success, 404 if not found.