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)