This is a workspace for Journeys API which allows developers and clients to access public transport lines, routes, stops and schedules. All material on this page are draft material and subject to significant change.

Concept

Journeys API allows developers and clients to access following information via REST API

  • Routes on which public transport services operate
  • Lines, or in other words grouping of routes. For example Line 2, which runs from Rauhaniemi to Pyyninkintori in Tampere
  • Journeys made by public transport vehicles on certain line and route at certain day and time
  • Stops where public transport vehicles stop during their journeys

The API allows accessing these concepts as hierarchy of objects (see later) as well as performing searches.

API Entities

The API is built on top of NeTEx entity model (http://user47094.vs.easily.co.uk/netex/), from which the entities in this API are derived. Following picture outlines the entities and their relationships.

Route, Route Link and Route Point

ROUTE entity describes a path through (a road or a rail) network, which is used by a public transport service (such as bus or a tram). A ROUTE is made up of a sequence of ROUTE LINKS which split the route into "pieces". Each ROUTE LINK starts and stops on ROUTE POINTS which typically map to a certain place in city infrastructure (a road junction, stopping place or a point of interest). All ROUTE LINKS laid out into a sequence form up the ROUTE (the start ROUTE POINT of the first ROUTE LINK is the start of the ROUTE and the end ROUTE POINT of the last ROUTE LINK is the ending point of the ROUTE). Following picture is taken from Tampere "reittikartta" and outlines a ROUTE through Tampere.

Line

LINE entity is a grouping of ROUTES that is generally known to the public with a common name, such as "Line 2". ROUTES on the same LINE usually follow similar ROUTEs.

Journey, Call, DayType, DayTypeException and StopPoint

JOURNEY describes public transport vehicle's run on a given ROUTE through the city. Typically the run occurs at the same time on multiple days during a week. For example a certain JOURNEY on given ROUTE could start 10:00 AM on Mondays, Tuesdays, Wednesdays, Thursdays and Fridays. DAY TYPE, attached to a JOURNEY, classifies the conditions on which kind of days the JOURNEY occurs. Conditions can be week day names, but other kind of conditions can apply too (such as "busy day" or "all weekdays"). DAY TYPE EXCEPTION provides mechanism to temporarily deviate from conditions imposed by a DAY TYPE. For example if a JOURNEY would occur on all weekdays, public holidays could be modeled as DAY TYPE EXCEPTIONS. In other words we could say "This JOURNEY runs on every week day except 21.5.2014, because this day is Labor Day".

On a given time on a given DAY TYPE or a given ROUTE, the JOURNEY stops on certain STOP POINTS from where passengers can board or alight the vehicle. A CALL groups together the STOP POINT where the vehicle stops, and the time when the vehicle stops on that STOP POINT. Since the vehicle stops multiple times during a JOURNEY, a CALL also contains the order of the stop.

Queries and Responses

REST styled API

Journeys API follows RESTful design pattern. This means that all entities returned by the API have an unique URL via which the entity can be accessed at all times. The returned entities refer to each other via these URLs, and each entity URL is always included in the entity itself as "href" property. Following is a fragment from JOURNEY entity response:

...
    "data" : {
        "href" : "http://example.com/journeys/api/journeys/111",
        "departureTime" : "08:00:00+0300",
        "dayTypes" : [
            {
                "href" : "http://example.com/journeys/api/day-types/weekdays"
            }
        ],
        "dayTypeExceptions" : [
            {
                "href" : "http://example.com/journeys/api/day-type-exceptions/111",
                "date" : "2014-05-05",
                "runs" : "no"
            }
        ],
        "calls" : [
            {
                "href" : "http://example.com/journeys/api/calls/1123",
                "arrival" : "08:00:00+0300",
                "departure" : "08:00:00+0300",
                "stopPoint" : {
                    "href" : "http://example.com/journeys/api/stop-points/222"
                }
            }
...

The JOURNEY itself has a href property (http://example.com/journeys/api/journeys/111) which points to the JOURNEY entity itself. A client can use this URL access this entity at any time. The dayType entity has also an href property which tells the client how to access the DAY TYPE data. Whenever a client encounters a href property in the response, the client should make a HTTP GET request to that url in order to access the entity data. The client the can "attach" the returned data to the original response. Depending on the request, the Journeys API might "expand" a entity in a response. For example, a DAY TYPE EXCEPTION element in the response above contains both href property as well as "date" and "runs" properties. This means that the client does not need to make a request to the href URL in order to access the entity data. Instead, the Journeys API has already included the full data of the entity into the request.

There are no rules when the Journeys API will expand an element (even though typically first level children of an element are typically expanded). Therefore, the client must follow these rules at all times.

  • If any entity (including nested child entities) contains href property, and no other properties, the client needs to make a HTTP GET request to the URL the href property specifies
  • If any entity (including nested child entities) contains href property, and other properties, the client should not make a HTTP GET request, since Journeys API has already expanded the entity (and all its child entities) in the response. The expanded entity can however contain child entities which have only href property present; in this case, the client is expected to make HTTP GET request for that child entity.

API-Wide URL parameters

Time

All Journeys API calls relate to certain time (in present, future or past). Journeys API elements are versioned over time, in other words changes in the entities are recorded with time stamps. By issuing requestTime parameter, the client can define the time from which the client wish to see the entities. For example: lets assume that a first version of time tables, lines and journeys is made 1.1.2013 (for winter schedules) and 1.6.2013 new version (for summer schedules is added). Each version would have different entities (lines, journeys etc...) since winter schedules would differ from summer schedules. Now, by issuing

http://example.com/journeys/lines/?requestTime=2013-01-10

request the Journeys API would return entities from the winter schedule. Respectively, a request to url

http://example.com/journeys/lines/?requestTime=2013-06-10 

would return entities from the summer schedule.

The requestTime parameter can be omitted, in this case requestTime is considered to be the time when the client made the request.

Response structure

Journeys API response is structured as follows:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 10,
        "moreData" : false

    },
    "data" : {
       ...
    }
}

The response has headers and data elements. Headers contain metadata-like information about the response. For example dataValidityPeriod tells the time span during which response data is valid. This would reflect the winter and summer example introduced previously. Data element contains the actual response data, and its content varies depending on the request made by the client. StartIndex tells the index of the first returned element, pageSize tells how many items were returned and moreData tells if the client should make another request to fetch the additional data. This approach is called "paging". The client can specify startIndex parameter to the request URL to specify the starting index of an entity list, for example:

http://example.com/journeys/api/lines?startIndex=10

If omitted, the Journeys API assumes startIndex to be zero.

Entity Queries

Lines

A client can access specific LINE'S details by issuing request at http://example.com/journeys/api/lines/123

This request would produce following response:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "lines":[
            {
                "href" : "http://example.com/journeys/api/lines/123",
                "name" : "13",
                "description" : "Hermia - Lukonmäki - Keskustori - Tesoma - Lamminpää - Ylöjärvi",
                "routes":[
                    {
                        "href" : "http://example.com/journeys/api/routes/123",
                        "pattern" : {
                            "href" : "http://example.com/journeys/api/route-patterns/111"
                        },
                        "journeys" : [
                            {
                                "href" : "http://example.com/journeys/api/journeys/111"
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

A client can search LINES by issuing following requests:

These queries return response like above, with entities matching the criteria. All query parameters are exclusive (if you specify multiple conditions, the conditions are ANDed together).

Routes

A client can access paged list of ROUTES by making HTTP GET request to url http://example.com/journeys/api/routes

This request would produce following response:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 10,
        "moreData" : false
    },
    "data" : {
        "routes" : [
            {
                "href" : "http://example.com/journeys/api/routes/123",
                "pattern" : {
                    "href" : "http://example.com/journeys/api/route-patterns/111"
                },
                "journeys" : [
                    {
                        "href" : "http://example.com/journeys/api/journeys/111",
                    }
                ]
            }
            ...
        ]
    }
}

A client can access specific ROUTE'S details by issuing request at http://example.com/journeys/api/routes/123

This request would produce following response:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "routes" : [
            {
                "href" : "http://example.com/journeys/api/routes/123",
                "pattern" : {
                    "href" : "http://example.com/journeys/api/route-patterns/111"
                },
                "journeys" : [
                    {
                        "href" : "http://example.com/journeys/api/journeys/111",
                        "departureTime" : "08:00:00+0300",
                        "dayTypes" : [
                            {
                                "href" : "http://example.com/journeys/api/day-types/weekdays"
                            }
                        ],
                        "dayTypeExceptions" : [
                            {
                                "href" : "http://example.com/journeys/api/day-type-exceptions/111"
                            }
                        ],
                        "calls" : [
                            {
                                "href" : "http://example.com/journeys/api/calls/1123",
                            },
                            {
                                "href" : "http://example.com/journeys/api/calls/1124",
                            },
                            {
                                "href" : "http://example.com/journeys/api/calls/1125",
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

Route Patterns

List of route patterns is not available, clients are expected to navigate to a certain route pattern via lines or routes.

A client can access specific ROUTE PATTERN'S details by issuing request at http://example.com/journeys/api/route-patterns/111

This request would produce following response:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "route-patterns" : [
            {
                "href" : "http://example.com/journeys/api/route-patterns/111",
                "pointsOnRoute": [
                    {
                        "href" : "http://example.com/journeys/api/points-on-routes/111",
                        "latitude" : "61.48016",
                        "longitude" : "23.83057"
                    },
                    {
                        "href" : "http://example.com/journeys/api/points-on-routes/112",
                        "latitude" : "60.48016",
                        "longitude" : "23.83057"
                    },
                    {
                        "href" : "http://example.com/journeys/api/points-on-routes/112",
                        "latitude" : "59.48016",
                        "longitude" : "23.83057"
                    }
                ]
            }
        ]
    }
}

Journeys

List of route JOURNEYS not available, clients are expected to navigate to a certain JOURNEY via LINES or ROUTES.

A client can access specific JOURNEY'S details by issuing request at http://example.com/journeys/api/journeys/111

This request would produce following response:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "journeys" : [
            {
                "href" : "http://example.com/journeys/api/journeys/111",
                "departureTime" : "08:00:00+0300",
                "dayTypes" : [
                    {
                        "href" : "http://example.com/journeys/api/day-types/weekdays"
                    }
                ],
                "dayTypeExceptions" : [
                    {
                        "href" : "http://example.com/journeys/api/day-type-exceptions/111",
                        "date" : "2014-05-05",
                        "runs" : "no"
                    }
                ],
                "calls" : [
                    {
                        "href" : "http://example.com/journeys/api/calls/1123",
                        "arrival" : "08:00:00+0300",
                        "departure" : "08:00:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/222"
                        }
                    },
                    {
                        "href" : "http://example.com/journeys/api/calls/1124",
                        "arrival" : "08:10:00+0300",
                        "departure" : "08:10:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/223"
                        }
                    },
                    {
                        "href" : "http://example.com/journeys/api/calls/1125",
                        "arrival" : "08:20:00+0300",
                        "departure" : "08:20:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/224"
                        }
                    }
                ]
            }
        ]
    }
}

DayTypes

A client can access paged list of DAY TYPES by making HTTP GET request to url http://example.com/journeys/api/day-types

This request would produce following response:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 10,
        "moreData" : false
    },
    "data" : {
        "dayTypes" : [
            {
                "href" : "http://example.com/journeys/api/day-types/weekdays",
                "properties" : [
                    {
                        "daysOfWeek" : "Monday,Tuesday,Wednesday,Thursday,Friday"
                    }
                ]
            }
            ...
        ]
    }
}

A client can access specific DAY TYPE'S details by for example issuing request at http://example.com/journeys/api/day-types/weekdays

This request would produce following response:

{
    "headers" : {
        "dataValidityPeriod" : {
            "validFrom" : "2013-01-01",
            "validTo" : "2013-05-31"
        },
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "dayTypes" : [
            {
                "href" : "http://example.com/journeys/api/day-types/weekdays",
                "properties" : [
                    {
                        "daysOfWeek" : "Monday,Tuesday,Wednesday,Thursday,Friday"
                    }
                ]
            }
        ]
    }
}

Search Queries

TBW

A client can search LINES by issuing following requests: