@mattywhite/skyscanner-api
v1.0.0
Published
A Node.js library for querying the reverse-engineered SkyScanner Android app API for flights, airports, locations, and car rentals, with built-in retries and error handling
Maintainers
Readme
SkyScanner API Client (Node.js)
A Node.js library for querying the reverse-engineered SkyScanner Android app API for flights, airports, locations, and car rentals, with built-in retries and error handling.
Note: This is a Node.js port of the original Python library. Original credit goes to @irrisolto.
Table of Contents
Installation
npm install skyscanner-apiOr if you're installing from source:
npm installQuick Start
const { SkyScanner, CabinClass, SpecialTypes } = require('skyscanner-api');
async function main() {
// Initialize the client
const scanner = new SkyScanner({
locale: "en-US",
currency: "USD",
market: "US"
});
// Search for airports
const airports = await scanner.searchAirports("London");
const origin = airports[0];
const destinationAirports = await scanner.searchAirports("New York");
const destination = destinationAirports[0];
// Search for flights
const departDate = new Date('2025-08-15');
const returnDate = new Date('2025-08-22');
const response = await scanner.getFlightPrices({
origin: origin,
destination: destination,
departDate: departDate,
returnDate: returnDate,
cabinClass: CabinClass.ECONOMY,
adults: 2
});
console.log(response.json);
}
main().catch(console.error);Class Reference
SkyScanner
The main client class for interacting with Skyscanner APIs.
Constructor
const scanner = new SkyScanner({
locale: "en-US", // Locale code for results
currency: "USD", // Currency code for pricing
market: "US", // Market region code
retryDelay: 2, // Seconds to wait between polling retries
maxRetries: 15, // Maximum number of polling retries
proxy: "", // Proxy URL for HTTP requests
pxAuthorization: null, // Optional pre-generated PX authorization token
verify: true // Whether to verify SSL certificates
});Parameters:
locale(string): Locale code for results (e.g., "en-US", "fr-FR")currency(string): Currency code for pricing (e.g., "USD", "EUR", "GBP")market(string): Market region code (e.g., "US", "UK", "DE")retryDelay(number): Seconds to wait between polling retriesmaxRetries(number): Maximum number of polling retries before giving upproxy(string): Proxy URL configuration for HTTP requestspxAuthorization(string | null): Optional pre-generated PX authorization tokenverify(boolean): Whether to verify SSL certificates
Methods
getFlightPrices()
Search for flight prices between two locations.
await scanner.getFlightPrices({
origin, // Airport object
destination, // Airport | SpecialTypes
departDate, // Date | SpecialTypes | null
returnDate, // Date | SpecialTypes | null
cabinClass, // CabinClass (default: ECONOMY)
adults, // number (default: 1)
childAges // number[] (default: [])
});Parameters:
origin(Airport): Origin airport objectdestination(Airport | SpecialTypes): Destination airport or special search type (e.g., SpecialTypes.EVERYWHERE)departDate(Date | SpecialTypes | null): Departure date or SpecialTypes.ANYTIMEreturnDate(Date | SpecialTypes | null): Return date (optional for one-way trips)cabinClass(string): Cabin class preference (from CabinClass enum)adults(number): Number of adult passengers (1-8)childAges(number[]): Ages of child passengers (0-17 years, max 8 children)
Returns: SkyscannerResponse object containing flight options and pricing data
Throws:
Error: Invalid dates, passenger counts, or search parametersBannedWithCaptcha: When blocked by Skyscanner's anti-bot measuresAttemptsExhaustedIncompleteResponse: When max retries exceeded
searchAirports()
Auto-suggest airports based on a search query.
await scanner.searchAirports(query, departDate, returnDate);Parameters:
query(string): Search text (airport name, city, or IATA code)departDate(Date | null): Optional departure date for contextreturnDate(Date | null): Optional return date for context
Returns: Array of Airport objects matching the query
searchLocations()
Auto-suggest locations for car rentals and other services.
await scanner.searchLocations(query);Parameters:
query(string): Location search text
Returns: Array of Location objects
getAirportByCode()
Retrieve a specific airport by its IATA code.
await scanner.getAirportByCode(airportCode);Parameters:
airportCode(string): Three-letter IATA airport code (e.g., "JFK", "LHR")
Returns: Airport object for the specified code
Throws:
GenericError: If airport code not found
getItineraryDetails()
Get detailed information for a specific flight itinerary.
await scanner.getItineraryDetails(itineraryId, response);Parameters:
itineraryId(string): Unique itinerary identifier from search resultsresponse(SkyscannerResponse): Original search response containing session data
Returns: Object with detailed itinerary information including flight legs and preferences
getCarRental()
Search for car rental options between locations and times.
await scanner.getCarRental({
origin, // Location | Coordinates | Airport
departTime, // Date
returnTime, // Date
destination, // Location | Coordinates | Airport | null
isDriverOver25 // boolean (default: true)
});Parameters:
origin(Location | Coordinates | Airport): Pickup locationdepartTime(Date): Pickup date and timereturnTime(Date): Drop-off date and timedestination(Location | Coordinates | Airport | null): Drop-off location (defaults to origin)isDriverOver25(boolean): Driver age flag affecting pricing
Returns: Object containing car rental options and pricing
getCarRentalFromUrl()
Parse a Skyscanner car rental URL and fetch rental options.
await scanner.getCarRentalFromUrl(url);Parameters:
url(string): Skyscanner car hire URL
Returns: Car rental search results
Example URL format:
https://www.skyscanner.net/g/carhire-quotes/GB/en-GB/GBP/30/27544008/27544008/2025-07-01T10:00/2025-08-01T10:00/Types and Enums
Airport
const airport = new Airport(
"London Heathrow", // title
"27544008", // entityId
"LHR" // skyId (IATA code)
);Location
const location = new Location(
"London", // entityName
"27544008", // entityId
"51.5074,-0.1278" // coordinates (lat,lng)
);CabinClass
CabinClass.ECONOMYCabinClass.PREMIUM_ECONOMYCabinClass.BUSINESSCabinClass.FIRST
SpecialTypes
SpecialTypes.ANYTIME- Flexible date searchSpecialTypes.EVERYWHERE- Open destination search
Error Handling
The library defines several custom exceptions:
BannedWithCaptcha
Raised when Skyscanner blocks requests with CAPTCHA challenges.
try {
const response = await scanner.getFlightPrices({...});
} catch (error) {
if (error instanceof BannedWithCaptcha) {
console.log(`Blocked by anti-bot measures: ${error.captchaUrl}`);
// Consider using proxies or reducing request frequency
}
}AttemptsExhaustedIncompleteResponse
Raised when polling retries are exhausted without getting complete results.
try {
const response = await scanner.getFlightPrices({...});
} catch (error) {
if (error instanceof AttemptsExhaustedIncompleteResponse) {
console.log("Search timed out - try again later");
}
}GenericError
General API errors with status codes and response details.
Examples
Basic Flight Search
const { SkyScanner } = require('skyscanner-api');
async function searchFlights() {
const scanner = new SkyScanner();
// Find airports
const londonAirports = await scanner.searchAirports("London");
const heathrow = londonAirports[0];
const nycAirports = await scanner.searchAirports("New York");
const jfk = nycAirports[0];
// Search flights
const response = await scanner.getFlightPrices({
origin: heathrow,
destination: jfk,
departDate: new Date('2025-09-01'),
returnDate: new Date('2025-09-08'),
adults: 1
});
console.log(response.json);
}
searchFlights().catch(console.error);Flexible Search (Anywhere, Anytime)
const { SkyScanner, SpecialTypes } = require('skyscanner-api');
async function flexibleSearch() {
const scanner = new SkyScanner();
const londonAirports = await scanner.searchAirports("London");
const heathrow = londonAirports[0];
// Search from London to anywhere
const response = await scanner.getFlightPrices({
origin: heathrow,
destination: SpecialTypes.EVERYWHERE,
departDate: SpecialTypes.ANYTIME
});
console.log(response.json);
}
flexibleSearch().catch(console.error);Car Rental Search
const { SkyScanner } = require('skyscanner-api');
async function searchCarRentals() {
const scanner = new SkyScanner();
// Search locations
const locations = await scanner.searchLocations("London");
const pickupLocation = locations[0];
// Set dates
const pickupDate = new Date('2025-07-01');
pickupDate.setHours(10, 0);
const returnDate = new Date('2025-07-08');
returnDate.setHours(10, 0);
// Search car rentals
const rentals = await scanner.getCarRental({
origin: pickupLocation,
departTime: pickupDate,
returnTime: returnDate,
isDriverOver25: true
});
console.log(rentals);
}
searchCarRentals().catch(console.error);Rate Limiting and Best Practices
- Use Proxies: Consider proxy rotation for high-volume usage
- Cache Results: Store airport/location searches to reduce API calls
- Validate Inputs: Check dates and passenger counts before API calls
- Reuse PX Authorization: X-Px-Authorization header isn't single use. Once you've made one you can use it for multiple requests, but once you get captcha you need to switch IP and authorization
Dependencies
axios: HTTP client for making API requestshttps-proxy-agent: Proxy support for HTTPS requests
License
MIT
Credits
Original Python library by @irrisolto on Discord. Node.js port created for broader accessibility.
Disclaimer
This library uses reverse-engineered Skyscanner Android app endpoints. Use at your own risk. The library is not affiliated with, endorsed by, or sponsored by Skyscanner.
