openapi: "3.0.0"
info:
version: 2.0.0
title: Trip Ninja API Documentation
description: |
<h2>Introduction</h2>
Trip Ninja uses a REST API with requests and responses in JSON format. For development and testing, the pre-production servers
are to be used. Once ready for live use, access to the production servers will be provided. <br />
<h2>Trip Ninja API URLs</h2>
Pre-Production: https://preprodapi.tripninja.io
For security, Trip Ninja’s servers are only accessible from whitelisted IPs. Please contact your account manager to whitelist IPs you
will be using.
Before you start ensure that:<br />
- IP addresses have been provided to be whitelisted for our servers.<br />
- API username and password have been provided by Trip Ninja.<br />
<h2>Workflow</h2>
The following diagram shows the typical data flow of API calls to Trip Ninja for a typical OTA integration using our new core non-emulation architecture.

<h2>Authentication</h2>
Trip Ninja uses Basic Authentication standards. Simply encode your username and password string using base64 and pass it in the
authorization headers. See the python example below on how this is done. In the example, the payload and API endpoint url are not
shown.
Python Example:
<pre>
import base64
auth = base64.b64encode("USERNAME:PASSWORD")
headers = {
'authorization': "Basic "+ auth,
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
</pre>
# Error Codes
<table>
<tr><td>IE01</td><td>Need minimum 2 destinations</td></tr>
<tr><td>IE02</td><td>Duplicate city in list</td></tr>
<tr><td>IE09</td><td>Can't run any queries for flight dates in the past</td></tr>
<tr><td>IE10</td><td>Incorrect city_type, expected one of ['C', 'A']</td></tr>
<tr><td>IE19</td><td>Incorrect region, expected one of 'emea', 'apac', 'americas'</td></tr>
<tr><td>IE21</td><td>Wrong currency</td></tr>
<tr><td>IE22</td><td>Not a valid cabin option. expected one of 'E' , 'PE', 'SE', 'BC','FC', 'PFC'</td></tr>
<tr><td>IE23</td><td>Not a valid alliance. Expected one of *A, *S, *O</td></tr>
<tr><td>IE24</td><td>Travellers Type does not meet expected criteria. Should be a list having between 0 and 10 values</td></tr>
<tr><td>IE27</td><td>Num_results should be an integer between 50 and 1000</td></tr>
<tr><td>IE29</td><td>Invalid Traveller type</td></tr>
<tr><td>IE30</td><td>Incorrect value for single_pnr, must be boolean</td></tr>
<table>
x-logo:
url: 'https://s3.amazonaws.com/tn-api-docs/trip_ninja_logo.png'
altText: Trip Ninja logo
href: 'https://www.tripninja.io/'
servers:
- url: https://preprodapi.tripninja.io
description: Pre-Production server for development and testing
paths:
/get-searches/:
post:
summary: "Get Searches"
description: |
This endpoint carries out FareStructure and if applicable Virtual Interlining logic to determine the optimal searches predicted to provide the best flight search results. The response contains a list of searches to be done by the OTA, which are then passed in the next
endpoint (generate-solutions) to get the results.
operationId: GetSearchesRequest
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GetSearchesRequest'
responses:
200:
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/GetSearchesResponse'
400:
description: Invalid Input
content:
application/json:
schema:
type: object
properties:
status:
type: sting
description: Error code and 0 for success response
example: IE23
message:
type: string
description: Contains the error message
example: Not a valid search
401:
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
status:
type: sting
description: Error code and 0 for success response
example: IE44
message:
type: string
description: Contains the error message
example: "User is not authorized"
500:
description: Server Error
/generate-solutions/:
post:
summary: "Generate Solutions"
description: "
There are two ways to approach this endpoint. For each search the OTA performed, we have provided a optional metadata field per pricing solution.
This allows the customer to pass in any metadata (branded fares, tax info, ect) regarding that specific pricing solution.
When we have finished generating the itineraries for the search, we will pass these values in a list inside the corresponding itinerary.<br/>
This will allow the response from the generate-solutions endpoint to be totally FE ready, in whatever format the OTA decides.
The downside of this approach is this will inflate the request/response size considerably.<br/>
An alternative is to simply ignore the metadata field. Using this minimal approach the OTA simply sends all the required fields listed in our docs.
This will result in a much smaller request/response, however it will be up to the OTA to process the data on their end and add any additional metadata to the itineraries returned.
"
operationId: GenerateSolutionsRequest
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/FullGenerateSolutionsRequest'
responses:
200:
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/GenerateSolutionsResponse'
400:
description: Invalid Input
content:
application/json:
schema:
type: object
properties:
status:
type: string
description: Error code and 0 for success response
example: "IE38"
message:
type: string
description: Contains the error message
example: "Trip ID not found"
401:
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
status:
type: sting
description: Error code and 0 for success response
example: IE44
message:
type: string
description: Contains the error message
example: "User is not authorized"
500:
description: Server Error
components:
schemas:
GetSearchesRequest:
title: Request
type: object
required:
- flights
- travellers
- currency
- country_code
properties:
flights:
description: "Array of flight legs input."
required: true
type: array
items:
type: object
required:
- id
- from_city
- start_type
- to_city
- end_type
- departure_date
properties:
id:
type: integer
description: "Flight leg ID, must be unique and in order from 1 to n."
example: 1
from_city:
type: string
description: "Start city/airport IATA code of leg."
example: "YHZ"
start_type:
type: string
description: "Upper-case letter “C” for city or “A” for airport. Doing a city search may return multiple airports nearby."
example: C
to_city:
type: string
description: "End city/airport IATA code of leg."
example: "LON"
end_type:
type: string
description: "Upper-case letter “C” for city or “A” for airport. Doing a city search may return multiple airports nearby."
example: C
departure_date:
type: string
description: "Departure date for this leg, format: YYYY-MM-DD. Any trailing characters after do not affect the API’s functionality."
example: "2023-06-20"
cabin_class:
type: string
description: "A unique cabin class can be set for each segment of the trip, otherwise it can be set at the root level."
example: BC
enum: [ "E", "PE", "BC", "FC", "PFC" ]
required: false
travellers:
description: "Array of passenger types, values include ‘ADT’, ’MIL’, ’CHD’ and ‘INF’"
required: true
type: array
example: [ 'ADT','ADT','CHD' ]
currency:
description: Currency to be used for provider query requests in three digit code and any price computation.
example: USD
required: true
type: string
source:
description: "Segment to be used for markup models - typically by source (ex: onsite, skyscanner, kayak, mobile, etc). Ensure this is known by your Trip Ninja account manager so the markup models for that source can be created."
example: skyscanner
type: string
required: true
country_code:
description: "Country code where search came from (For example: CA, US). This works with the source field to determine the markup model to use."
example: CA
type: string
required: true
cabin_class:
default: E
description: "Parameter toggles the permitted cabin class for your query. Alternatively, it can be set for each segment."
example: E
required: false
enum: [ "E", "PE", "BC", "FC", "PFC" ]
type: string
time_value:
default: 0
description: |
This parameter helps set the value of a passenger’s time, in
terms of the currency selected. It is used to trade off flight
prices versus flight durations. The parameter is in units of
[currency]/hour. Flight durations are calculated as the difference
in minutes from the arrival time of the last flight in a leg to
the departure time of the first flight in the leg.
True Cost of Flight = [Flight Price] * [time_value/60] * [Flight Duration]
The itinerary which provides the lowest True Cost of Flight is
what is returned in the response. If you provide a time_value
of 0 or do not provide the parameter, it will sort by price.
required: false
type: integer
num_results:
description: Parameter sets the number of segments in the response. If single_pnr = true, this parameter refers to the number of constructed itineraries in the response. All single_pnr itineraries are passed through if that parameter is set to true.
default: 50
type: integer
minimum: 50
maximum: 5000
single_pnr:
description: Return single-pnr structures in addition to the results returned. If set to true, all single_pnr itineraries will be passed through, regardless of the num_results parameter.
default: false
type: boolean
virtual_interlining:
description: Add virtual interlining to the search so that the results are a mix of standard search results and virtual interlining results.
default: false
type: boolean
GetSearchesResponse:
type: object
properties:
trip_id:
description: The trip id of the search. This will be used in all future requests relating to this search.
type: string
example: "fb3d8eff432a329dc21fad8449c686fa93e5ce24"
datasource_requests:
description: The list of datasource requests to be carried out by the OTA.
type: array
items:
$ref: '#/components/schemas/DatasourceRequest'
DatasourceRequest:
properties:
datasource_request_id:
description: The id of the datasource request.
type: string
example: "4f499298b303c55a1ee522118afce28abe2f68e4"
num_results:
description: The number of results requested.
type: integer
example: 50
datasource_segment:
description: The list of datasource segments.
type: array
items:
$ref: '#/components/schemas/DatasourceSegment'
DatasourceSegment:
type: object
properties:
id:
description: The id of the datasource segment. While most will be in sequence and an integer [1...n], some may include a 1.1 or 1.2 when these are part of a virtual interlining segment to be searched.
type: float or integer
example: 1
from_iata:
description: The IATA code of the origin airport or city.
type: string
example: "YHZ"
from_type:
description: The type of the origin, "C" for City or "A" for Airport.
type: string
enum: [ "C", "A" ]
example: "C"
to_iata:
description: The IATA code of the destination airport or city.
type: string
example: "YVR"
to_type:
description: The type of the destination, "C" for City or "A" for Airport.
type: string
enum: [ "C", "A" ]
example: "C"
departure_date:
description: The departure date of the segment, format = YYYY-MM-DD.
type: string
example: "2023-06-30"
cabin_class:
description: The cabin class of the segment.
type: string
enum: [ "E", "PE", "BC", "FC", "PFC" ]
example: "E"
FullGenerateSolutionsRequest:
type: object
title: Generate Solutions Request
properties:
trip_id:
description: The trip id of the search. This will be used in all future requests relating to this search.
type: string
example: "fb3d8eff432a329dc21fad8449c686fa93e5ce24"
datasource_responses:
description: The list of datasource responses to be used to generate solutions.
type: object
allOf:
- $ref: '#/components/schemas/FullDatasourceResponse'
MinimalDatasourceResponse:
type: object
properties:
4f499298b303c55a1ee522118afce28abe2f68e4:
description: The ID of the datasource request. The ID varies between requests.
type: array
items:
$ref: "#/components/schemas/BasicGenerateDatasourceRequest"
FullDatasourceResponse:
type: object
properties:
4f499298b303c55a1ee522118afce28abe2f68e4:
description: "The datasource_request_id of a datasource request returned from the first get-searches
call after the OTA has performed the flight searches requested. The value of this id will be the
formatted results from that search."
type: array
items:
$ref: "#/components/schemas/FullGenerateDatasourceRequest"
MinimalDatasourceLegDetails:
description: A list of required info for each leg of this segment.
type: object
required:
- departure_time
- arrival_time
- flight_number
- operating_carrier
- transportation_type
- fare_type
- cabin_class
properties:
departure_time:
type: string
description: Departure time.
example: "2023-03-15T08:00:00"
arrival_time:
type: string
description: Arrival time.
example: "2023-03-15T10:29:00"
flight_number:
type: string
description: Flight number.
example: "391"
operating_carrier:
type: string
description: Operating carrier.
example: "WS"
transportation_type:
type: string
description: "Transportation vehicle used for this segment."
example: "flight"
fare_type:
type: string
description: Fare Type of the segment
example: "Published"
cabin_class:
type: string
description: "The cabin class of the leg."
example: BC
enum: [ "E", "PE", "BC", "FC", "PFC" ]
DatasourceLegDetails:
description: Information for each leg of this segment.
type: object
properties:
OriginName:
type: string
description: Full name of the origin airport.
example: "Halifax, NS, Canada (YHZ)"
Origin:
type: string
description: Origin airport code.
example: "YHZ"
DestinationName:
type: string
description: Full name of the destination airport.
example: "Vancouver, BC, Canada (YVR)"
Destination:
type: string
description: Destination airport code.
example: "YVR"
DepartureTime:
type: string
description: Departure time.
example: "2023-03-15T08:00:00"
ArrivalTime:
type: string
description: Arrival time.
example: "2023-03-15T10:29:00"
FlightNumber:
type: string
description: Flight number.
example: "391"
Carrier:
type: string
description: Carrier code.
example: "WS"
CarrierFullName:
type: string
description: Carrier full name.
example: "Westjet"
FlightTime:
type: integer
description: Flight time in minutes.
example: 329
AircraftType:
type: string
description: Aircraft type.
example: "73H"
Key:
type: string
description: Leg key.
example: "DDN3UXYAuDKAaiphxoAAAA=="
BookingCode:
type: string
description: Booking code.
example: "L"
cabin_class:
type: string #TODO: standardize this into ["E", "PE", "BC", "FC", "PFC"] as in other cabin_class sections
description: Cabin class.
example: "Economy"
fare_info_ref:
type: string
description: Fare info reference.
example: "DDN3UXYAuDKAkiphxoAAAA=="
fare_rule_key:
type: string
description: Fare rule key.
example: "gws-eJxNj8EOAiEMRD+GzL1ASdwbuKsxWcJBzRo8+P+f4VA17pQ2baa8QM45SIgS5JD3cni5xw1zWYCGwOzbFT6JCDynBhltnbez1uMKg0SfzPqHR7dFrtph6Yw29K398qTxIT"
DatasourcePriceBreakdownDetails:
type: object
description: Displays the pricing for each passenger type
properties:
passenger_type_code:
type: string
description: Passenger type code.
example: "ADT"
base_price:
type: number
total_price:
type: number
taxes:
type: number
tax_breakdown:
type: array
items:
$ref: '#/components/schemas/DatasourceTaxBreakdownDetails'
DatasourceTaxBreakdownDetails:
type: object
description: Breakdown of taxes amount into their categories
properties:
category:
type: string
description: Tax category.
example: "FR"
amount:
type: number
description: Tax amount.
GenerateSolutionsResponse:
title: Generate Solutions Response
type: object
properties:
trip_id:
type: string
description: A unique key used for identification and when booking a trip.
example: "fb3d8eff432a329dc21fad8449c686fa93e5ce24"
itineraries:
$ref: '#/components/schemas/DatasourceItineraryInfo'
metadata_details:
$ref: '#/components/schemas/MetaDataDetails'
DatasourceItineraryInfo:
type: array
description: Array of itineraries sorted by weight.
items:
properties:
weight:
type: float
description: Weight of the segment (time-value considered).
example: 239
total_price:
type: float
description: Price of the itinerary (fare and tax included).
example: 197.1
transportation_time:
type: integer
description: Total transportation time for the itinerary
example: 425
structure:
type: Array of ints and/or Array of tuple/or Array of tuple and int
description: |
"Array representing the structure of the trip in terms of one-ways and open-jaw segments.
For example: [(0, 1), (3, 4), 2] means there would be three bookings. One openjaw with key “01”,
one with key “34” and a one-way with key ‘2”."
See Price Confirm Report segment_ids field for more detail.
example: "[(0, 1), 2]"
metadata:
type: array
description: "Contains extra information about the segment that was sent by the OTA.
This field is completely optional and we will not alter the data within this object.
Whatever passed within this object will be returned as-is back to the OTA.<br/>
This array contains all the metadata that correlates with the related itineraries.
This will not be populated if no metadata is passed in the generate solutions request."
items:
type: object
properties:
metadata_id:
type: string
description: A unique identifier that matches objects within metadata_details
example: "c2f59ef0eeec039233d60e694fed09edc4dfa954"
DatasourceItinerarySegmentInfo:
type: object
properties:
segment_id:
type: string
description: String if one-way, Array of 2 Strings if open-jaw. Used for booking.
example: "344d73be0d61f820aa9a6ace300742fed0672f2e"
price:
type: float
description: Price of the segment (fare and tax included)
example: 72.3
PercentageWithExtraInfo:
type: object
description: Information about penalty percentage and amount
properties:
amount:
type: float
description: Penalty amount
example: 78
percentage:
type: float
description: Penalty percentage
example: 0
ChangePenaltyWithExtraInfo:
type: object
description: Information about changing.
properties:
amount:
type: float
description: Change penalty amount
example: 78
percentage:
$ref: "#/components/schemas/PercentageWithExtraInfo"
applies_at:
type: string
description: When will the change penality apply at
example: "Anytime"
CancelPenaltyWithExtraInfo:
type: object
description: Information about cancelling.
properties:
amount:
type: float
description: Cancel penalty amount
example: 78
percentage:
$ref: "#/components/schemas/PercentageWithExtraInfo"
applies_at:
type: string
description: When will the cancel penality apply at
example: "Anytime"
FareInfoBrandDetails:
type: object
description: Contains brand information for the fare
properties:
name:
type: string
description: Name of the brand
example: "STANDARD"
brand_description:
type: string
description: Description of the brand
example: "Standard: Carry on baggage only"
tag_line:
type: string
description: Tag line of the brand
example: "Low Fares for Carefee Travel"
brand_services:
type: object
description: Contains information of what the brand offers
properties:
carry_on_hand_baggage:
type: boolean or string
description: Are carry on bags permittied on this ticket. True/False or "$"
example: true
checked_baggage:
type: boolean or string
description: Are checked bags permittied on this ticket. True/False or "$"
example: true
rebooking:
type: string
description: Rebooking available on this ticket.
example: $
refund:
type: boolean
description: Refundability of the ticket.
example: true
seat_assignment:
type: string
description: Seat assignment availability on this ticket.
example: $
meals_and_beverages:
type: boolean
description: Are meals and beverages provided as part of this ticket.
example: true
wifi:
type: string
description: Wifi avail
# --- truncated at 32 KB (37 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/webjet/refs/heads/main/openapi/webjet-tripninja-v2-core-openapi.yml