openapi: "3.0.0" info: version: 2.0.0 title: Trip Ninja API Documentation description: |

Introduction

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.

Trip Ninja API URLs

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:
- IP addresses have been provided to be whitelisted for our servers.
- API username and password have been provided by Trip Ninja.

Workflow

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. ![Workflow diagram](https://s3.amazonaws.com/tn-api-docs/ota_flowchart.png)

Authentication

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:
        import base64
        auth = base64.b64encode("USERNAME:PASSWORD")
        headers = {
            'authorization': "Basic "+ auth,
        }
        response = requests.post(url, headers=headers, data=json.dumps(payload))
        
# Error Codes
IE01Need minimum 2 destinations
IE02Duplicate city in list
IE09Can't run any queries for flight dates in the past
IE10Incorrect city_type, expected one of ['C', 'A']
IE19Incorrect region, expected one of 'emea', 'apac', 'americas'
IE21Wrong currency
IE22Not a valid cabin option. expected one of 'E' , 'PE', 'SE', 'BC','FC', 'PFC'
IE23Not a valid alliance. Expected one of *A, *S, *O
IE24Travellers Type does not meet expected criteria. Should be a list having between 0 and 10 values
IE27Num_results should be an integer between 50 and 1000
IE29Invalid Traveller type
IE30Incorrect value for single_pnr, must be boolean
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.
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.
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.
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 availability on the flight. example: $ tier: type: string description: Brand tier example: "0002" BrandFareInfo: type: array description: Contains fare info for the brand items: type: object properties: origin: description: Origin of the segment type: string example: "YHZ" destination: description: Destination of the segment type: string example: "YVR" fare_basis: description: Fare Basis Code for the segment. type: string example: "QUSDSI0E" booking_code: description: Booking code for the segment type: string example: "12S3TI3P" cabin_class: description: Cabin class of the segment type: string example: "E" brand: $ref: "#/components/schemas/FareInfoBrandDetails" DatasourceBrandDetails: type: array description: List of branded fares for the current segment items: type: object properties: base_price: description: Base price of the segment (tax excluded) type: float example: 0 taxes: description: Tax price of the segment type: float example: 119.1 fees: description: Fees for the segment *Travelport customers only* type: float example: 0 price: description: Price of the segment (fare and tax included). type: float example: 197.1 change_penalty: $ref: "#/components/schemas/ChangePenaltyWithExtraInfo" cancel_penalty: $ref: "#/components/schemas/CancelPenaltyWithExtraInfo" baggage_info: description: Contains baggage information. type: object properties: pieces: description: Number of baggages included type: int example: 1 units: description: Unit of the baggage type: string example: "pc" fare_info: $ref: "#/components/schemas/BrandFareInfo" BasicGenerateDatasourceRequest: type: object description: blah required: - pricing_solution_id - total_price - segment_source - legs properties: pricing_solution_id: type: string description: A unqiue identifier that represents the itinerary details. example: "40495f0f293b54ffe64c833d987cd80ecdb5aca5" total_price: type: float description: Total price of the segment (fare and tax included). example: 197.1 segment_source: type: string description: GDS or LCC provider source for segment. example: travelport segments: type: array description: A list of segments for this itinerary items: type: array description: A list of required legs information for this segment items: $ref: '#/components/schemas/MinimalDatasourceLegDetails' refundable: type: boolean description: Explains whether the booking will be refundable. example: True FullGenerateDatasourceRequest: allOf: - $ref: "#/components/schemas/BasicGenerateDatasourceRequest" - type: object properties: metadata: type: object 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." example: {} MetaDataDetails: type: array description: Contains a list of metadata for data mapping, 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 the metadata within each itinerary example: "c2f59ef0eeec039233d60e694fed09edc4dfa954"