npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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

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-api

Or if you're installing from source:

npm install

Quick 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 retries
  • maxRetries (number): Maximum number of polling retries before giving up
  • proxy (string): Proxy URL configuration for HTTP requests
  • pxAuthorization (string | null): Optional pre-generated PX authorization token
  • verify (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 object
  • destination (Airport | SpecialTypes): Destination airport or special search type (e.g., SpecialTypes.EVERYWHERE)
  • departDate (Date | SpecialTypes | null): Departure date or SpecialTypes.ANYTIME
  • returnDate (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 parameters
  • BannedWithCaptcha: When blocked by Skyscanner's anti-bot measures
  • AttemptsExhaustedIncompleteResponse: 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 context
  • returnDate (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 results
  • response (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 location
  • departTime (Date): Pickup date and time
  • returnTime (Date): Drop-off date and time
  • destination (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.ECONOMY
  • CabinClass.PREMIUM_ECONOMY
  • CabinClass.BUSINESS
  • CabinClass.FIRST

SpecialTypes

  • SpecialTypes.ANYTIME - Flexible date search
  • SpecialTypes.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

  1. Use Proxies: Consider proxy rotation for high-volume usage
  2. Cache Results: Store airport/location searches to reduce API calls
  3. Validate Inputs: Check dates and passenger counts before API calls
  4. 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 requests
  • https-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.