PROJECT 825
National Rail Enquiries
Online Journey Planner (OJP)
OJP Web Services
What Can I do With My Ticket JSON Web Service
P82501008 Issue 1 / 11 January 2017
Originator’s signature & date / Approver’s signature and date
Thales / National Rail Enquiries
Thales, Ashurst Drive, Bird Hall Lane, Cheadle Heath, Stockport, Cheshire SK3 0XB, UK
Tel: +44 (0)161 491 4001•Fax: +44 (0)161 741 3704••
© 2017 Thales Transport & Security Ltd - This document is the copyright of Thales Transport & Security Ltd and is issued in confidence. It must not be used other than for the purposes of the contract to which it relates and is not to be reproduced in whole or in part without the prior written permission of Thales Transport & Security Ltd.

DISTRIBUTION

1 / Project Master File

ISSUE RECORD

Issue / Date / Purpose
1 Draft A / 09/09/2016 / 1 Draft A
1 Draft B / 28/09/2016 / 1 Draft B Minor type reformatting
1 Draft C / 10/10/2016 / Andrew Tolley Comments
1 / 11/01/2017 / Raised to Issue status following RDG approval
P82501008 Issue 1 / 1

CONTENTS

1.Introduction

2.Getting Started

2.1Standards Compliance

2.2Development Platforms

2.3Json Schema

3.Authentication

4.Security

5.Available Operations

6.Minification

7.API

7.1Selection of Operation

7.2Internationalisation and Character Sets

7.3JSON Compliance

7.4Characteristics of API Calls

7.5Committed Atomically

8.Error Handling

8.1Errors common to all Operations

8.2Validation Handling

9.JSON Data Structures

9.1Request Json Objects

9.1.1Search Location

9.1.2Fare Matching Criteria

9.1.3WCT Ticket Request JSON Object

9.1.4Extended WCT Ticket Request JSON Object

9.2Response Json Objects

9.2.1WCT Ticket Response

9.2.2WCT Route Mapping Response

9.2.3WCT Other Journeys Response

9.2.4WCTLinkVO

9.2.5JsonPlusBikeData

9.2.6Alternative Terminals

9.2.7JsonLocationDTO

9.2.8RailCard

9.2.9Terms and Conditions

9.2.10Ticket Type Description

9.2.11Journey Information

9.2.12EnhancedCRS Codes

9.2.13WCT Railcard Response

10.Usage and Examples

10.1Search

10.1.1Standard Single Journey

10.1.2Extended Request.

10.2Route Mapping

10.2.1Single Journey Request

10.2.2Return Journey Request

10.3Other Journeys

10.3.1Single Journey Request

10.4RailCards

10.4.1Rail Card Example

P82501008 Issue 1 / 1
OJP Web Services
What Can I do With My Ticket JSON Web Service

1.Introduction

This user guide describes how to write client calls to the JSONWeb Services for the OJP What Can I do with my Ticket.

2.Getting Started

2.1Standards Compliance

The API is implemented to comply with the following specifications:

Standard Name / Version / Website
JSR 339 Java Api for RESTful Web Services / 2.0 /

2.2Development Platforms

No specific development environment is required for developing software to use the RESTful web services. There are several application capable of testing RESTful web services (Chrome REST Plugin / SoapUI).

2.3Json Schema

A json schema is available for all operations. This can be found by adding /schema/{request or response} to the supplied url’s. For further information regarding json schemas see here.

For example
<url>/search/schema/request will return the json schema for the request.

<url>/search/schema/response will return the json schema for the response.

It should be noted that the translation process for dates is extracting all of the available methods for the date object. Dates should be submitted as per the examples, not this format.

3.Authentication

There are two types of authentication possible for accessing these web services:

  • IP White Listing
  • Username/password

The choice of which to use will depend on what application the web services are required for. In the case of an application running in a server environment and calling the web services from a specific place then IP White Listing can be used. A typical setup here would be another web site that wants to include information from OJP.

Where the web services will be called from many different IP addresses then the recommended setup is username/password. A typical setup here would be a smartphone application.

If you are given a username/password this must be sent as part of the HTTP transaction. The exact method of adding this is dependent upon the client side framework that you are using. Further information can be found here

4.Security

All submissions must be performed using https. Transmissions by http will be rejected.

5.Available Operations

The following table lists the available operations for the RESTful Web Service. All operations require the post of html response data with the exception of railcards, which is a restful url.

This will be detailed further in the documentation.

Operation / Usage
search / Takes specified ticket parameter, and returns a collection of matched tickets.
routemap / Takes specified ticket parameters and returns route map information
otherjourneys / Takes specified ticket parameters and returns other journey information
railcards / Produces a list of railcards.

6.Minification

It is recommended that the json payload is minified prior to sending, as this will reduce the size of the overall payload.

7.API

7.1Selection of Operation

RESTful web services are called by specifying a specific url.

7.2Internationalisation and Character Sets

The API supports the full Unicode(UTf-8) character set.

7.3JSON Compliance

The API is based on JSON, which requires all documents to be well formed. There are several characters that will require escaping. These are detailed below with escaping example:

\b Backspace (ascii code 08)

\f Form feed (ascii code 0C)

\n New line

\r Carriage return

\t Tab

\v Vertical tab

\' Apostrophe or single quote

\" Double quote

\\ Backslash character

For more information about JSON characters and character sets see

7.4Characteristics of API Calls

All API calls are:

  • Service Requests and Responses. Your client application prepares and submits a service request to the Web Service via the API, the Web Service processes the request and returns a response, and the client application handles the response.
  • Synchronous. Once the API call is invoked, your client application waits until it receives a response from the service. Asynchronous calls are not supported.

7.5Committed Atomically

Every operation that writes data is committed atomically and automatically. Therefore an operation always succeeds entirely or fails – it never partially succeeds.

8.Error Handling

A generic error handling framework has been created which manages all errors that can be thrown. The formatting of this is detailed below:

{

"status":"ERROR"

"payload":

{

"type":[String] Type of Error

"message":[String] Detailed Message describing error.

"code":[String] Message string which is written into the

server logs to enable fault diagnosis

e.g.

stg1-OjpApp202.nrepreprod.local#2015-12-14-11-47-12-789"

}

}

8.1Errors common to all Operations

There is only one error which is common to all operations, which is thrown as and when the JSON parser is unable to read the supplied input. An example of this is given below.

{

"status":"ERROR"

"payload":{

"type":"org.springframework.http.converter.HttpMessageNotReadableException"

"message":"Could not read JSON: Unexpected character ('}' (code 125)): was expecting double-quote to start field name at [Source: org.apache.catalina.connector.CoyoteInputStream@4d121573; line: 225, column: 2]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('}' (code 125)): was expecting double-quote to start field name at [Source: org.apache.catalina.connector.CoyoteInputStream@4d121573; line: 225, column: 2]"

"code":"stg1-OjpApp202.nrepreprod.local#2015-12-14-11-47-12-789"

}

-

}

The exact nature of the message response will differ depending on the supplied input.

8.2Validation Handling

A generic validation framework has been implemented to ensure that standardised validation messages are thrown.

This conforms to the JSR-303 framework. Details of which can be found in here.

The format of a JSON response where a validation response has been thrown is detailed as follows:
{

"status" : "VALIDATION",

"payload" : {

"fieldErrors" : [ {

"field" : "fieldName",

"message" : " validation message"

} ]

}

}

The formatting of the message will be detailed as follows :

ValidationType.FieldName

For example

Size.jsonWctRequest,fareMatchingCriteria.fareDestination

In this example the fareDestination size is incorrect. As can be seen in this example the structure supports nested structures. The fareDestination is located within the fareMatchingCriteria.

9.JSON Data Structures

Detailed below are the main data structures, and the data type that is expected to be supplied along with its length. Unless specified the objects will be defaulted to null if not supplied.

It should be noted that any Integer objects supplied with decimal places will be automatically truncated by default.

i.e. 5.33 will become 5

9.1Request Json Objects

9.1.1Search Location

{

"crsCode" : [STRING(3) ],

"nlcCode" : [STRING(4) ]

}

One of CRS or NLC code must be supplied. If both the codes are supplied then preference is given to the CRS code.

9.1.2Fare Matching Criteria

{

"fareSetter"** : [STRING(3)],

"fareOrigin"* :[STRING(4)],

"fareDestination"* : [STRING(4)],

"RouteCode"* : [String(5)],

"ticketTypeCode"* : [String(3)],

"railcardCode"** : [String(3)]

}

* - Mandatory for RouteMapping and Other Journeys, otherwise validated if supplied.

** - Validated if supplied.

9.1.3WCT Ticket Request JSON Object

{

"origin"*: [see search location],

"destination"*:[see search location],

"ticketPrice"* :[Number Size= 6, precision =2 ],

"fareMatchingCriteria"** : [see fare matching criteria],

"startDate"* : [STRING ISO DATE TIME FORMAT],

"returnDate"** : [STRING ISO DATE TIME FORMAT,

"fareClass"* :[one of STANDARD,FIRST_CLASS],

"passengerType"* : [one of ADULT, CHILD]

}

* - Mandatory.

** - Validated if supplied.

9.1.4Extended WCT Ticket Request JSON Object

{

"origin"*: [see search location],

"destination"*:[see search location],

"ticketPrice"* :[Number Size= 6, precision =2 ],

"fareMatchingCriteria"** : [see fare matching criteria],

"startDate"* : [STRING ISO DATE TIME FORMAT],

"returnDate"** : [STRING ISO DATE TIME FORMAT,

"fareClass"* :[one of STANDARD,FIRST_CLASS],

"passengerType"* : [one of ADULT, CHILD],

"outward" : [BOOLEAN default to True if not supplied],

}

* - Mandatory.

** - Mandatory if Other Journeys/Route Mapping, otherwise validated if supplied.

9.2Response Json Objects

9.2.1WCT Ticket Response

{

"typeOfPassenger": [one of ADULT , CHILD],

"price : Number,

"fareCategory": [one of RESTRICTED, RESTRICTED_TRAVELCARD,

FLEXIBLE,FLEXIBLE_TRAVELCARD, OPEN, OPEN_TRAVELCARD],

"wctLinks": [array of WCTLinkVO],

"discount": [INTEGER],

"originLocation": [JSONLocationDTO],

"destinationLocation":[JSONLocationDTO],

"startDate": [STRING ISO DATE TIME FORMAT],

"returnDate": [STRING ISO DATE TIME FORMAT],

"fareClass": [STANDARD,FIRST_CLASS],

"railcard": [see Railcard],

"termsAndConditions": [see terms and conditionns],

"ticketRestictions": [String],

"plusBus": [String],

"ticketWarningMessage": [String],

"myTicket": [String],

"compensation": [String],

"routeDescription": [String],

"routeCode": [String],

"ticketTypeCode":[String] ,

"fareSetter": [String],

"fareOrigin": [String],

"fareDestination": [String],

"routeName": [String],

"id": [String],

"url": [String]

}

9.2.2WCT Route Mapping Response

{

"id": [Integer],

"numberOfJourneys": [Integer],

"totalDistance": [Number],

"averageJourneyTime": [Integer],

"temporaryEasementApplies": [Boolean],

"easementTexts": [array of String],

"routeScore": [Integer],

"crsCodes": [array of Enhanced CRS codes]

}

9.2.3WCT Other Journeys Response

{

"selectedJourneyIndex": [Integer],

"journeyInformation":[array of journey information]

}

9.2.4WCTLinkVO

{

"name": [String],

"url": [String]

}

9.2.5JsonPlusBikeData

{

"cycleStorageAvailable": BOOLEAN,

"url": [String],

"cycleHireAvailable": BOOLEAN

}

9.2.6Alternative Terminals

{

"name": [String],
"type": [String],
"crs": [String],
"nlc": [String]

}

9.2.7JsonLocationDTO

{

"plusBike:[see JsonPlusBikeData],
"stationMadeEasyUrl": [String],
"onwardTravelOptions": [String],
"alternativeTerminals": [array of Alternative Terminals],
"name": [String],
"type": [STATION,STATION_GROUP,STATION_IN_LONDON,STATION_NOT_USABLE_BY_OJP,

STATION_DOCKLAND_LIGHT_RAILWAY,STATION_LONDON_UNDERGROUND,

STATION_DOCKLAND_LIGHT_RAILWAY_AND_LONDON_UNDERGROUND,

FARE_LOCATION, STATION_ALIAS],

"crs": [String],
"nlc": [String]

}

9.2.8RailCard

{

code : [String],

name : [String],

count : [Integer],

valid : [boolean]

}

9.2.9Terms and Conditions

{

“ticketTypeDescription” : [Ticket Type Description],

"trainOperators": [String]

}

9.2.10Ticket Type Description

{

"validity": [String],

"ticketTypeName": [String],

"description": [String],

"bookingDeadlines": [String],

"discounts": [String],

"changesToTravelPlans": [String],

"refunds": [String],

"conditions": [String],

"fareCategory": [String],

"breaksOfJourney": [String],

"availability": [String],

"sleepers": [String],

"easements": [String],

"retailing": [String],

"packages": [String],

"allTocs": [Boolean],

"tocAndConnections": [String]

}

9.2.11Journey Information

{

"arrivalStationName": [String],

"arrivalStationCrs": [String],

"departureTime": [STRING ISO DATE TIME FORMAT],

"durationMins": [Integer],

"statusMessage": [String],

"arrivalTime": [STRING ISO DATE TIME FORMAT],

"statusMessageHoverInformation": [String],

"departureStationCrs": [String],

"departureStationName":[String],

"durationHours": [Integer],

"changes": [Integer],

"realTime": [Boolean],

"scheduled": [Boolean],

"valid": [Boolean]

}

9.2.12EnhancedCRS Codes

{

"code": [String],

"longitude": [Number],

"latitude": [Number]}

9.2.13WCT Railcard Response

{

"railcardCode": [String],

"railcardName": [String],

"adultStatusCodeDescription: [String],

"childStatusCodeDescription": [String],

}

10.Usage and Examples

Detailed below are examples that can be submitted in order to get a json response.

10.1Search

Title
URL / <root url>/json/wctjsonservice/search
For example on live ojp this would be

Schema / <root url>/json/wctjsonservice/search/schema/request
<root url>/json/wctjsonservice/search/schema/response
For example on live ojp this would be


Method / POST
URL Parameters / n/a
Data Parameters
Refer to 9.1.3 WCT Ticket Request JSON Object / {
"origin"*: [see search location],
"destination"*:[see search location],
"ticketPrice"* :[Number Size= 6, precision =2 ],
"fareMatchingCriteria"** : [see fare matching criteria],
"startDate"* : [STRING ISO DATE TIME FORMAT],
"returnDate"** : [STRING ISO DATE TIME FORMAT,
"fareClass"* :[one of STANDARD,FIRST_CLASS],
"passengerType"* : [one of ADULT, CHILD]
}
Key
* = mandatory, and validated.
** = not mandatory, but if supplied will be validated.
Success Response / {
"status": "OK",
"payload": [array of WCT Ticket Response JSON Object*]
}
*=It should be noted that if multiple tickets are matched then an array of WCT ticket responses are returned. The information returned allows for both the WCT page to be generated and for the correct ticket to be easily identified if the route mapping / other journey web services are required to be called. The request will then be required to be updated to facilitate a single ticket response.

10.1.1Standard Single Journey

Request

{
"origin": {
"crsCode": "MAN",
"nlcCode": null
},
"destination": {
"crsCode": "EUS",
"nlcCode": null
},
"ticketPrice": 81.4,
"startDate": "2016-09-07T13:51:15.041Z",
"returnDate": null,
"fareClass": "STANDARD",
"passengerType": "ADULT"
}

Response

{

"status": "OK",

"payload": [ {

"typeOfPassenger": "ADULT",

"price": 81.4,

"fareCategory": "FLEXIBLE",

"wctLinks": [ {

"name": "this is a new link",

"url": "

}],

"discount": 0,

"originLocation": {

"plusBike": {

"cycleStorageAvailable": true,

"url": "

"cycleHireAvailable": true

},

"stationMadeEasyUrl": "

"onwardTravelOptions": "

"alternativeTerminals": [

{

"name": "London Euston",

"type": "STATION_IN_LONDON",

"nlc": "1444",

"crs": "EUS"

},

{

"name": "London Marylebone",

"type": "STATION_IN_LONDON",

"nlc": "1475",

"crs": "MYB"

},

{

"name": "London Paddington",

"type": "STATION_IN_LONDON",

"nlc": "3087",

"crs": "PAD"

},

{

"name": "London St Pancras International",

"type": "STATION_IN_LONDON",

"nlc": "1555",

"crs": "STP"

}

],

"name": "London Euston",

"type": "STATION_IN_LONDON",

"nlc": "1444",

"crs": "EUS"

},

"destinationLocation": {

"plusBike": {

"cycleStorageAvailable": true,

"url": "

"cycleHireAvailable": true

},

"stationMadeEasyUrl": "

"onwardTravelOptions": "

"alternativeTerminals": [],

"name": "Manchester Piccadilly",

"type": "STATION",

"nlc": "2968",

"crs": "MAN"

},

"startDate": "2016-10-25",

"fareClass": "STANDARD",

"termsAndConditions": {

"ticketTypeDescription": {

"validity": null,

"ticketTypeName": "Off-Peak Single",

"description": "<p>Off-Peak fares are cheaper tickets for\n travelling on trains that are less busy. You may need to travel at\n specific times of the day, days of the week and sometimes on specific\n routes or operators.<\/p>\n <p>The times when you may use your Off-Peak\n ticket will depend on the journey you are making and you will be advised\n when buying your ticket. The <a href=\" Rail Journey Planner<\/a> will automatically work out which tickets are valid for your journey.<\/p>",

"bookingDeadlines": "None.",

"discounts": "Child:<br/<div<\/div>\n <p>Children (aged 5 to 15 inclusive) are offered a 50% discount.<\/p>\n <p>Up to two children aged under 5 can travel free with each fare paying passenger.<\/p>\n <div<\/div<br/>Railcard:<br/<div<\/div>\n <p>16-25 Railcard, Family & Friends, Two Together, Disabled Persons\n Railcard, HM Forces Railcard, Senior Railcard, Network and GoldCard all\n offer 34% discount.<\/p>\n <p>Minimum fares / time restrictions may apply\n to tickets bought with a Railcard or other discount card. See terms and\n conditions of the appropriate Railcard or discount card for details.<\/p>\n <p>Railcard holders travelling on a discounted\n ticket must carry their Railcard when they travel. If a Railcard holder\n fails to produce their valid Railcard with their ticket, they will be\n required to pay a full priced ticket for their journey as if no Railcard\n and/or no ticket were held.<\/p>\n <div<\/div>",

"refunds": "<p>Your ticket is refundable. If you decide not to use your ticket to\n make all or part of your intended journey then you can get a refund by\n returning your unused ticket to the ticket office or place of purchase\n (for tickets bought via websites, telesales or travel agents) within 28\n days of the ticket expiry date.<\/p>\n <p>You may be required to pay an administration\n fee (up to a maximum of £10 per ticket). The refund amount will normally\n take into account any use you have made of the ticket and in some\n circumstances no refund will be paid.<\/p>",

"changesToTravelPlans": "<p>If you wish to change your time of travel you\n can pay the difference between the cost of the ticket held and the cost\n of the ticket that is most appropriate for the journey you need to\n make. In many cases, if you are still travelling at a time when your\n ticket is not restricted, no additional fare is payable.<\/p>\n <p>If you wish to change the date of travel, or\n the origin or destination of your ticket, it may be necessary to buy a\n new ticket and apply for a refund on your existing ticket (see Refund\n Policy below).<\/p>",

"conditions": "<p>Off-Peak tickets may require you to travel at specific times of\nday, days of the week or on a specific route. Website journey planners\ncan tell you when your ticket can be used - simply enter your outward\nand return journey times to see the trains you can travel on. If you\nboard a train at a time when your Off-Peak ticket is not valid,\nyou will be charged the difference between the fare you have paid and\nthe cheapest valid fare for the service concerned. In some\ncircumstances you may have to pay a penalty fare. <\/p>\n<p>If the route shown on the ticket has a + or †\nsymbol then the ticket includes the cost of travelling between certain\nLondon Stations (e.g. between Liverpool Street and Paddington) by either\nLondon Underground, Docklands Light Railway (DLR) or Thameslink\nservices as appropriate to the route of the journey being made. Tickets\nwill only be accepted by London Underground and DLR up to the last day\nof validity of the ticket and until 04:29 the following day. Other than\nto change trains, a break of journey at intermediate London Underground\nor DLR stations is not permitted.<\/p>\n<p>All tickets and travel are subject to the <a href=\"/Conditions%20of%20Travel%202016.pdf\">National Rail Conditions of Travel<\/a>. <\/p>",

"fareCategory": "FLEXIBLE",

"breaksOfJourney": "Outward:<br/<p>\n A break of journey is permitted unless otherwise indicated by a restriction shown against the ticket's Restriction Code.&nbsp;<\/p>\n <p>Overnight break of journey - if the journey cannot be completed in this\n time, the ticket may be used to continue the journey on the following\n day. Unless otherwise indicated in the relevant restriction code, time\n restrictions <span class=\"change\">apply<\/span<span class=\"change\"> as<\/span<span class=\"change\"&nbsp;<\/span>from the <span class=\"change\">initial<\/span> origin station on <span class=\"change\">both<\/span> days. <span class=\"change\">The appropriate <\/span<span class=\"change\">restrictions <\/span<span class=\"change\">for the actual day on which travel is <\/span<span class=\"change\">being undertaken apply (<\/span<span class=\"change\">for example, it may be that if day 1 is on Sunday, no restrictions apply, but on day 2, the Monday-Friday <\/span<span class=\"change\">restrictions apply<\/span<span class=\"change\">).<\/span> All travel must be completed by 04:29 in the morning&nbsp;after this second day.<\/p<br/>Return:<br/>Not applicable.<br />",