Skip to main content

NSKCC Availability Search API 0.1.73

Last updated: 17-Apr-2026
Recent changes: Merge branch 'feature/NSK-72563-fix-prod-catalog-publish' into 'main' NSK-72563: Fix prod catalog publish — api-product-prod now triggerable on... Closes NSK-72563 See merge request api-program/apigee/flight/newskies-apis/flight-availability-search-api!30

Code Examples

This page provides practical code examples for integrating with the Flight Availability Search API in various programming languages.

Table of Contents


cURL

Basic One-Way Search

curl -X GET "https://test.api.tui/flight/newskies/availability/v2/search?outboundStartDate=2024-06-01&outboundEndDate=2024-06-30&departureStationCodes=BRU&arrivalStationCodes=ALC&tripType=0&PassengerCount=2" \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Accept: application/json"

Round-Trip Search with Multiple Airports

curl -X GET "https://test.api.tui/flight/newskies/availability/v2/search?outboundStartDate=2024-07-01&outboundEndDate=2024-07-15&inboundStartDate=2024-07-15&inboundEndDate=2024-07-31&departureStationCodes=LHR,MAN,BHX&arrivalStationCodes=PMI,IBZ&carrierCodes=TB&tripType=1&PassengerCount=4&GroupBy=0&LimitGroups=10&LimitFlights=5" \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Accept: application/json"

JavaScript/Node.js

Using Fetch API (Browser/Node.js 18+)

async function searchFlights(accessToken) {
  const baseUrl = 'https://test.api.tui/flight/newskies/availability/v2';

  const params = new URLSearchParams({
    outboundStartDate: '2024-06-01',
    outboundEndDate: '2024-06-30',
    departureStationCodes: 'BRU',
    arrivalStationCodes: 'ALC',
    tripType: '0',
    PassengerCount: '2',
    GroupBy: '0',
    LimitGroups: '10',
    LimitFlights: '5'
  });

  try {
    const response = await fetch(`${baseUrl}/search?${params}`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${accessToken}`,
        'Accept': 'application/json'
      }
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log('Flight groups:', data.groups);

    return data;
  } catch (error) {
    console.error('Error searching flights:', error);
    throw error;
  }
}

// Usage
const accessToken = 'your_access_token_here';
searchFlights(accessToken)
  .then(results => {
    results.groups.forEach(group => {
      console.log(`Group: ${group.name}`);
      console.log(`Flights: ${group.flights.length}`);
    });
  });

Using Axios (Node.js)

const axios = require('axios');

const searchFlights = async (accessToken, searchParams) => {
  const baseUrl = 'https://test.api.tui/flight/newskies/availability/v2';

  try {
    const response = await axios.get(`${baseUrl}/search`, {
      params: searchParams,
      headers: {
        'Authorization': `Bearer ${accessToken}`
      }
    });

    return response.data;
  } catch (error) {
    if (error.response) {
      console.error('API Error:', error.response.status, error.response.data);
    } else {
      console.error('Request Error:', error.message);
    }
    throw error;
  }
};

// Usage
const accessToken = 'your_access_token_here';
const searchParams = {
  outboundStartDate: '2024-06-01',
  outboundEndDate: '2024-06-30',
  departureStationCodes: 'BRU,LHR',
  arrivalStationCodes: 'ALC,PMI',
  tripType: 0,
  PassengerCount: 2,
  GroupBy: 0
};

searchFlights(accessToken, searchParams)
  .then(data => console.log('Results:', data))
  .catch(error => console.error('Failed:', error));

TypeScript Interface

interface SearchRequest {
  outboundStartDate: string;
  outboundEndDate: string;
  inboundStartDate?: string;
  inboundEndDate?: string;
  departureStationCodes?: string;
  arrivalStationCodes?: string;
  departureCountries?: string;
  arrivalCountries?: string;
  carrierCodes?: string;
  tripType: 0 | 1;
  PassengerCount?: number;
  GroupBy?: 0 | 1;
  LimitGroups?: number;
  LimitFlights?: number;
}

interface Fare {
  fareBasisCode: string;
  currencyCode: string;
  priceGrossAdt: number;
  priceGrossChd: number;
  priceNetAdt: number;
  taxes: number;
  fees: number;
}

interface Flight {
  departureDateTime: string;
  arrivalDateTime: string;
  carrierCode: string;
  flightNumber: string;
  departureStationCode: string;
  arrivalStationCode: string;
  availability: number;
  flightDuration: number;
  fares: Fare[];
}

interface FlightGroup {
  name: string;
  flights: Flight[];
}

interface SearchResponse {
  groups: FlightGroup[];
}

async function searchFlights(accessToken: string, params: SearchRequest): Promise<SearchResponse> {
  const baseUrl = 'https://test.api.tui/flight/newskies/availability/v2';
  const queryString = new URLSearchParams(params as any).toString();

  const response = await fetch(`${baseUrl}/search?${queryString}`, {
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Accept': 'application/json'
    }
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  return await response.json();
}

Python

Using Requests Library

import requests
from typing import Dict, List, Optional

class FlightSearchClient:
    def __init__(self, access_token: str, base_url: str = "https://test.api.tui/flight/newskies/availability/v2"):
        self.access_token = access_token
        self.base_url = base_url
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {access_token}',
            'Accept': 'application/json'
        })

    def search_flights(self, 
                      outbound_start: str,
                      outbound_end: str,
                      departure_stations: List[str],
                      arrival_stations: List[str],
                      trip_type: int = 0,
                      passenger_count: int = 1,
                      inbound_start: Optional[str] = None,
                      inbound_end: Optional[str] = None,
                      carrier_codes: Optional[List[str]] = None,
                      group_by: int = 0,
                      limit_groups: Optional[int] = None,
                      limit_flights: Optional[int] = None) -> Dict:
        """
        Search for flight availability

        Args:
            outbound_start: Outbound start date (YYYY-MM-DD)
            outbound_end: Outbound end date (YYYY-MM-DD)
            departure_stations: List of departure airport codes
            arrival_stations: List of arrival airport codes
            trip_type: 0 for one-way, 1 for round-trip
            passenger_count: Number of passengers
            inbound_start: Return start date (required for round-trip)
            inbound_end: Return end date (required for round-trip)
            carrier_codes: Optional list of carrier codes
            group_by: 0 for origin-destination, 1 for date
            limit_groups: Maximum number of groups
            limit_flights: Maximum flights per group

        Returns:
            Dict containing search results
        """
        params = {
            'outboundStartDate': outbound_start,
            'outboundEndDate': outbound_end,
            'departureStationCodes': ','.join(departure_stations),
            'arrivalStationCodes': ','.join(arrival_stations),
            'tripType': trip_type,
            'PassengerCount': passenger_count,
            'GroupBy': group_by
        }

        if inbound_start:
            params['inboundStartDate'] = inbound_start
        if inbound_end:
            params['inboundEndDate'] = inbound_end
        if carrier_codes:
            params['carrierCodes'] = ','.join(carrier_codes)
        if limit_groups:
            params['LimitGroups'] = limit_groups
        if limit_flights:
            params['LimitFlights'] = limit_flights

        try:
            response = self.session.get(f"{self.base_url}/search", params=params)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.HTTPError as e:
            print(f"HTTP Error: {e.response.status_code}")
            print(f"Response: {e.response.text}")
            raise
        except requests.exceptions.RequestException as e:
            print(f"Request Error: {e}")
            raise

# Usage Example
if __name__ == "__main__":
    access_token = "your_access_token_here"
    client = FlightSearchClient(access_token=access_token)

    # One-way search
    results = client.search_flights(
        outbound_start="2024-06-01",
        outbound_end="2024-06-30",
        departure_stations=["BRU", "LHR"],
        arrival_stations=["ALC", "PMI"],
        trip_type=0,
        passenger_count=2,
        carrier_codes=["TB"],
        limit_groups=10,
        limit_flights=5
    )

    # Process results
    for group in results.get('groups', []):
        print(f"\nGroup: {group['name']}")
        print(f"Number of flights: {len(group['flights'])}")

        for flight in group['flights']:
            print(f"  Flight {flight['carrierCode']}{flight['flightNumber']}")
            print(f"  {flight['departureStationCode']} -> {flight['arrivalStationCode']}")
            print(f"  Departure: {flight['departureDateTime']}")
            print(f"  Available seats: {flight['availability']}")

            if flight.get('fares'):
                cheapest_fare = min(flight['fares'], key=lambda f: f['priceGrossAdt'])
                print(f"  From: {cheapest_fare['priceGrossAdt']} {cheapest_fare['currencyCode']}")

C#/.NET

Using HttpClient

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

public class FlightSearchClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;

    public FlightSearchClient(string accessToken, string baseUrl = "https://test.api.tui/flight/newskies/availability/v2")
    {
        _baseUrl = baseUrl;
        _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}");
        _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    }

    public async Task<SearchResponse> SearchFlightsAsync(SearchRequest request)
    {
        var queryParams = new List<string>
        {
            $"outboundStartDate={request.OutboundStartDate:yyyy-MM-dd}",
            $"outboundEndDate={request.OutboundEndDate:yyyy-MM-dd}",
            $"tripType={request.TripType}",
            $"PassengerCount={request.PassengerCount}"
        };

        if (request.DepartureStationCodes?.Any() == true)
            queryParams.Add($"departureStationCodes={string.Join(",", request.DepartureStationCodes)}");

        if (request.ArrivalStationCodes?.Any() == true)
            queryParams.Add($"arrivalStationCodes={string.Join(",", request.ArrivalStationCodes)}");

        if (request.CarrierCodes?.Any() == true)
            queryParams.Add($"carrierCodes={string.Join(",", request.CarrierCodes)}");

        if (request.InboundStartDate.HasValue)
            queryParams.Add($"inboundStartDate={request.InboundStartDate.Value:yyyy-MM-dd}");

        if (request.InboundEndDate.HasValue)
            queryParams.Add($"inboundEndDate={request.InboundEndDate.Value:yyyy-MM-dd}");

        if (request.GroupBy.HasValue)
            queryParams.Add($"GroupBy={request.GroupBy.Value}");

        if (request.LimitGroups.HasValue)
            queryParams.Add($"LimitGroups={request.LimitGroups.Value}");

        if (request.LimitFlights.HasValue)
            queryParams.Add($"LimitFlights={request.LimitFlights.Value}");

        var queryString = string.Join("&", queryParams);
        var url = $"{_baseUrl}/search?{queryString}";

        try
        {
            var response = await _httpClient.GetAsync(url);
            response.EnsureSuccessStatusCode();

            return await response.Content.ReadFromJsonAsync<SearchResponse>();
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"HTTP Error: {ex.Message}");
            throw;
        }
    }
}

// Models
public class SearchRequest
{
    public DateTime OutboundStartDate { get; set; }
    public DateTime OutboundEndDate { get; set; }
    public DateTime? InboundStartDate { get; set; }
    public DateTime? InboundEndDate { get; set; }
    public List<string> DepartureStationCodes { get; set; }
    public List<string> ArrivalStationCodes { get; set; }
    public List<string> CarrierCodes { get; set; }
    public int TripType { get; set; } = 0;
    public int PassengerCount { get; set; } = 1;
    public int? GroupBy { get; set; }
    public int? LimitGroups { get; set; }
    public int? LimitFlights { get; set; }
}

public class SearchResponse
{
    public List<FlightGroup> Groups { get; set; }
}

public class FlightGroup
{
    public string Name { get; set; }
    public List<Flight> Flights { get; set; }
}

public class Flight
{
    public DateTime DepartureDateTime { get; set; }
    public DateTime ArrivalDateTime { get; set; }
    public string CarrierCode { get; set; }
    public string FlightNumber { get; set; }
    public string DepartureStationCode { get; set; }
    public string ArrivalStationCode { get; set; }
    public int Availability { get; set; }
    public int FlightDuration { get; set; }
    public List<Fare> Fares { get; set; }
}

public class Fare
{
    public string FareBasisCode { get; set; }
    public string CurrencyCode { get; set; }
    public decimal PriceGrossAdt { get; set; }
    public decimal PriceNetAdt { get; set; }
    public decimal Taxes { get; set; }
    public decimal Fees { get; set; }
}

// Usage
class Program
{
    static async Task Main(string[] args)
    {
        var accessToken = "your_access_token_here";
        var client = new FlightSearchClient(accessToken);

        var searchRequest = new SearchRequest
        {
            OutboundStartDate = new DateTime(2024, 6, 1),
            OutboundEndDate = new DateTime(2024, 6, 30),
            DepartureStationCodes = new List<string> { "BRU", "LHR" },
            ArrivalStationCodes = new List<string> { "ALC", "PMI" },
            CarrierCodes = new List<string> { "TB" },
            TripType = 0,
            PassengerCount = 2,
            GroupBy = 0,
            LimitGroups = 10,
            LimitFlights = 5
        };

        try
        {
            var results = await client.SearchFlightsAsync(searchRequest);

            foreach (var group in results.Groups)
            {
                Console.WriteLine($"\nGroup: {group.Name}");
                Console.WriteLine($"Flights: {group.Flights.Count}");

                foreach (var flight in group.Flights)
                {
                    Console.WriteLine($"  {flight.CarrierCode}{flight.FlightNumber}: " +
                                    $"{flight.DepartureStationCode} -> {flight.ArrivalStationCode}");
                    Console.WriteLine($"  Departure: {flight.DepartureDateTime}");
                    Console.WriteLine($"  Available: {flight.Availability} seats");

                    if (flight.Fares?.Any() == true)
                    {
                        var cheapest = flight.Fares.MinBy(f => f.PriceGrossAdt);
                        Console.WriteLine($"  From: {cheapest.PriceGrossAdt} {cheapest.CurrencyCode}");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

Java

Using Java 11+ HttpClient

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.LocalDate;
import java.util.List;

public class FlightSearchClient {
    private final HttpClient httpClient;
    private final ObjectMapper objectMapper;
    private final String baseUrl;
    private final String accessToken;

    public FlightSearchClient(String accessToken, String baseUrl) {
        this.accessToken = accessToken;
        this.baseUrl = baseUrl;
        this.httpClient = HttpClient.newHttpClient();
        this.objectMapper = new ObjectMapper();
        this.objectMapper.registerModule(new JavaTimeModule());
    }

    public SearchResponse searchFlights(SearchRequest request) throws Exception {
        String queryString = buildQueryString(request);
        String url = baseUrl + "/search?" + queryString;

        HttpRequest httpRequest = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Authorization", "Bearer " + accessToken)
                .header("Accept", "application/json")
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(
                httpRequest,
                HttpResponse.BodyHandlers.ofString()
        );

        if (response.statusCode() != 200) {
            throw new RuntimeException("API Error: " + response.statusCode() + " - " + response.body());
        }

        return objectMapper.readValue(response.body(), SearchResponse.class);
    }

    private String buildQueryString(SearchRequest request) {
        StringBuilder sb = new StringBuilder();

        sb.append("outboundStartDate=").append(request.getOutboundStartDate());
        sb.append("&outboundEndDate=").append(request.getOutboundEndDate());
        sb.append("&tripType=").append(request.getTripType());
        sb.append("&PassengerCount=").append(request.getPassengerCount());

        if (request.getDepartureStationCodes() != null && !request.getDepartureStationCodes().isEmpty()) {
            sb.append("&departureStationCodes=")
              .append(String.join(",", request.getDepartureStationCodes()));
        }

        if (request.getArrivalStationCodes() != null && !request.getArrivalStationCodes().isEmpty()) {
            sb.append("&arrivalStationCodes=")
              .append(String.join(",", request.getArrivalStationCodes()));
        }

        if (request.getCarrierCodes() != null && !request.getCarrierCodes().isEmpty()) {
            sb.append("&carrierCodes=")
              .append(String.join(",", request.getCarrierCodes()));
        }

        if (request.getInboundStartDate() != null) {
            sb.append("&inboundStartDate=").append(request.getInboundStartDate());
        }

        if (request.getInboundEndDate() != null) {
            sb.append("&inboundEndDate=").append(request.getInboundEndDate());
        }

        if (request.getGroupBy() != null) {
            sb.append("&GroupBy=").append(request.getGroupBy());
        }

        if (request.getLimitGroups() != null) {
            sb.append("&LimitGroups=").append(request.getLimitGroups());
        }

        if (request.getLimitFlights() != null) {
            sb.append("&LimitFlights=").append(request.getLimitFlights());
        }

        return sb.toString();
    }

    // Usage Example
    public static void main(String[] args) {
        try {
            String accessToken = "your_access_token_here";
            FlightSearchClient client = new FlightSearchClient(
                accessToken,
                "https://test.api.tui/flight/newskies/availability/v2"
            );

            SearchRequest request = new SearchRequest();
            request.setOutboundStartDate(LocalDate.of(2024, 6, 1));
            request.setOutboundEndDate(LocalDate.of(2024, 6, 30));
            request.setDepartureStationCodes(List.of("BRU", "LHR"));
            request.setArrivalStationCodes(List.of("ALC", "PMI"));
            request.setCarrierCodes(List.of("TB"));
            request.setTripType(0);
            request.setPassengerCount(2);
            request.setGroupBy(0);
            request.setLimitGroups(10);
            request.setLimitFlights(5);

            SearchResponse response = client.searchFlights(request);

            response.getGroups().forEach(group -> {
                System.out.println("\nGroup: " + group.getName());
                System.out.println("Flights: " + group.getFlights().size());

                group.getFlights().forEach(flight -> {
                    System.out.println("  " + flight.getCarrierCode() + flight.getFlightNumber() +
                                     ": " + flight.getDepartureStationCode() + " -> " +
                                     flight.getArrivalStationCode());
                    System.out.println("  Departure: " + flight.getDepartureDateTime());
                    System.out.println("  Available: " + flight.getAvailability() + " seats");

                    if (flight.getFares() != null && !flight.getFares().isEmpty()) {
                        Fare cheapest = flight.getFares().stream()
                                .min((f1, f2) -> Double.compare(f1.getPriceGrossAdt(), f2.getPriceGrossAdt()))
                                .orElse(null);
                        if (cheapest != null) {
                            System.out.println("  From: " + cheapest.getPriceGrossAdt() + " " +
                                             cheapest.getCurrencyCode());
                        }
                    }
                });
            });

        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

PHP

Using cURL

<?php

class FlightSearchClient {
    private $baseUrl;
    private $accessToken;

    public function __construct($accessToken, $baseUrl = 'https://test.api.tui/flight/newskies/availability/v2') {
        $this->accessToken = $accessToken;
        $this->baseUrl = $baseUrl;
    }

    public function searchFlights($params) {
        $queryString = http_build_query($params);
        $url = $this->baseUrl . '/search?' . $queryString;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $this->accessToken,
            'Accept: application/json'
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if (curl_errno($ch)) {
            $error = curl_error($ch);
            curl_close($ch);
            throw new Exception("cURL Error: " . $error);
        }

        curl_close($ch);

        if ($httpCode !== 200) {
            throw new Exception("API Error: HTTP " . $httpCode . " - " . $response);
        }

        return json_decode($response, true);
    }
}

// Usage Example
try {
    $accessToken = 'your_access_token_here';
    $client = new FlightSearchClient($accessToken);

    $searchParams = [
        'outboundStartDate' => '2024-06-01',
        'outboundEndDate' => '2024-06-30',
        'departureStationCodes' => 'BRU,LHR',
        'arrivalStationCodes' => 'ALC,PMI',
        'carrierCodes' => 'TB',
        'tripType' => 0,
        'PassengerCount' => 2,
        'GroupBy' => 0,
        'LimitGroups' => 10,
        'LimitFlights' => 5
    ];

    $results = $client->searchFlights($searchParams);

    foreach ($results['groups'] as $group) {
        echo "\nGroup: " . $group['name'] . "\n";
        echo "Flights: " . count($group['flights']) . "\n";

        foreach ($group['flights'] as $flight) {
            echo "  " . $flight['carrierCode'] . $flight['flightNumber'] . ": ";
            echo $flight['departureStationCode'] . " -> " . $flight['arrivalStationCode'] . "\n";
            echo "  Departure: " . $flight['departureDateTime'] . "\n";
            echo "  Available: " . $flight['availability'] . " seats\n";

            if (!empty($flight['fares'])) {
                $cheapest = array_reduce($flight['fares'], function($min, $fare) {
                    return $min === null || $fare['priceGrossAdt'] < $min['priceGrossAdt'] ? $fare : $min;
                });
                echo "  From: " . $cheapest['priceGrossAdt'] . " " . $cheapest['currencyCode'] . "\n";
            }
        }
    }

} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

?>

Error Handling Best Practices

Retry Logic Example (Python)


import time
from requests.exceptions import RequestException

def search_with_retry(client, max_retries=3, backoff_factor=2):
    """Search with exponential backoff retry logic"""
    for attempt in range(max_retries):
        try:
            return client.search_flights(
                outbound_start="2024-06-01",
                outbound_end="2024-06-30",
                departure_stations=["BRU"],
                arrival_stations=["ALC"],
                trip_type=0
            )
        except RequestException as e:
            if attempt == max_retries - 1:
                raise

            wait_time = backoff_factor ** attempt
            print(f"Attempt {attempt + 1} failed. Retrying in {wait_time}s...")
            time.sleep(wait_time)

About us

TUI is one of the world’s leading tourism groups. The broad portfolio gathered under the Group umbrella consists of strong tour operators, 1,600 travel agencies and leading online portals, five airlines with around 150 aircraft, over 400 hotels, 16 cruise liners and many incoming agencies in all major holiday destinations around the globe.

 

TUI Group logo

Contact

Login to your account