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.

In the picture above, entities are drawn with purple color. Boxes with blue color are properties of the entities, but drawn out to explain the concepts. Lines in the picture represent UML-styled relations. Lines with filled diamond represent relation with ownership rule: the entity which has a diamond shape attached to it, owns the entity or property at other end of the line. Lines with empty diamond represent relation reference rule: the entity which has an empty diamond shape attached to it, is referred by entity or property at other end of the line. For example ROUTE owns POINTS ON ROUTE, and JOURNEY references a STOP POINT. Numbers at the end of lines are multiplicity rules, which tell how many entities or properties are included in the relation. If number is not present at the end of a line, it is assumed that number one would exist at the end of that line. For example: Route and PointOnRoute share a relation. In this relation, a PointOnRoute relates to one Route, whereas a Route relates to two or more PointOnRoutes.

Routes and Points on Route

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). ROUTE consists of sequence of POINTS ON ROUTE, each having a location. The first POINT ON ROUTE is the starting point of the ROUTE and the last POINT ON ROUTE is the termination 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, 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" : {
        "journeys" : [
            {
                "href" : "http://example.com/journeys/api/journeys/111",
                "route" : "http://example.com/journeys/api/routes/123",
                "validFrom" : "2013-01-01",
                "validTo" : "2013-05-31",
                "departureTime" : "08:00:00+0300",
                "dayTypes" : ["Monday","Tuesday","Wednesday","Thursday","Friday"],
                "dayTypeExceptions" : [
                    {
                        "date" : "2014-05-05",
                        "runs" : "no"
                    }
                ],
                "calls" : [
                    {
                        "arrival" : "08:00:00+0300",
                        "departure" : "08:00:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/222"
                        }
                    },
                    {
                        "arrival" : "08:10:00+0300",
                        "departure" : "08:10:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/223"
                        }
                    },
                    {
                        "arrival" : "08:20:00+0300",
                        "departure" : "08:20:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/224"
                        }
                    }
                ]
            }
        ]
...

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 stopPoint 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. An expanded entity has still the href property, but is accompanied by other properties too. 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" : {
        "startIndex" : 0,
        "pageSize" : 10,
        "moreData" : false

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

The response has headers and data elements. Data element contains the actual response data, and its content varies depending on the request made by the client. Headers contain metadata-like information about the response. 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" : {
        "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"
            }
        ]
    }
}

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). For example query:

Routes

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" : {
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "routes" : [
            {
                "href" : "http://example.com/journeys/api/routes/123",
                "line" : "http://example.com/journeys/api/lines/123",
                "pointsOnRoute": [
                    {
                        "location": "61.48016,23.83057"
                    },                    
                    {
                        "location": "60.48016,23.83057"
                    },
                    {
                        "location": "59.48016,23.83057"
                    }                    
                ]
            }
        ]
    }
}

The ROUTE entity refers to LINE via the "line" property. The ROUTE entity also owns multiple POINT ON ROUTEs, which each have location property. The location property tells the latitude and longitude of the POINT ON ROUTE. Location has format: latitude,longitude.

A client can search ROUTES 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). For example query

Journeys

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" : {
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "journeys" : [
            {
                "href" : "http://example.com/journeys/api/journeys/111",
                "route" : "http://example.com/journeys/api/routes/123",
                "departureTime" : "08:00:00+0300",
                "dayTypes" : ["Monday","Tuesday","Wednesday","Thursday","Friday"],
                "dayTypeExceptions" : [
                    {
                        "date" : "2014-05-05",
                        "runs" : "no"
                    }
                ],
                "calls" : [
                    {
                        "arrival" : "08:00:00+0300",
                        "departure" : "08:00:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/222"
                            "location" : "61.44960,23.87165",
                            "name" : "Hermia",
                            "shortName" : "3633"   
                        }
                    },
                    {
                        "arrival" : "08:10:00+0300",
                        "departure" : "08:10:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/223"
                            "location" : "61.43054,23.81566",
                            "name" : "Vuoreksen koulu",
                            "shortName" : "3635"
                        }
                    },
                    {
                        "arrival" : "08:20:00+0300",
                        "departure" : "08:20:00+0300",
                        "stopPoint" : {
                            "href" : "http://example.com/journeys/api/stop-points/224"
                            "location" : "61.44273,23.86268",
                            "name" : "Näyttämönkatu",
                            "shortName" : "3637"
                        }
                    }
                ]
            }
        ]
    }
}

JOURNEY element contains property called "call". A call is NeTEx element which binds together journeys arrival and departure times with STOP POINT information. For example the JOURNEY in the response has three calls: first call tells that the JOURNEY start time and that it starts from STOP POINT with id 222.

A client can search JOURNEYS 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). For example query:

Stop Points

A client can access specific STOP POINTS details by issuing request at http://example.com/journeys/api/stop-points/222

This request would produce following response:

{
    "headers" : {
        "startIndex" : 0,
        "pageSize" : 1,
        "moreData" : false
    },
    "data" : {
        "stopPoints" : [
            {
                "href" : "http://example.com/journeys/api/stop-points/222",
                "location" : "61.44960,23.87165",
                "name" : "Hermia",
                "shortName" : "3633"            
            }
        ]
    }
}

A client can search STOP POINTS 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). For example query: