# Skyscanner Flight Price Calendar (`xtracto/skyscanner-scraper`) Actor

Get the cheapest daily flight prices between any two airports for the next 12 months in one structured dataset. Built for fare tracking, route discovery, price-alert apps, and travel content sites.

- **URL**: https://apify.com/xtracto/skyscanner-scraper.md
- **Developed by:** [Farhan Febrian Nauval](https://apify.com/xtracto) (community)
- **Categories:** Travel, Other
- **Stats:** 120 total users, 8 monthly users, 59.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Skyscanner Scraper

Skyscanner pricing data in two flavours — pick the granularity that fits your use case:

- **Daily price calendar** — one record per day for ~360 days on a chosen route.
- **Anywhere inspiration** — every destination Skyscanner indexes from one origin in a chosen travel month, with the cheapest fare to each.

Designed for fare-tracking dashboards, price-alert apps, route-pricing studies, travel content publishers, and anyone who wants Skyscanner pricing at scale.

***

### What you can do with it

- **Find the cheapest day to fly** — sort the daily-calendar dataset by price and you have your answer.
- **Discover where to go on a budget** — anywhere mode answers "where can I fly from LHR for under £100 in July?" in a single run.
- **Build a fare alert** — schedule the actor daily, diff against yesterday, notify on drops.
- **Power a travel content site** — embed price charts and "trending destinations" tiles.
- **Train pricing models** — daily-price snapshots over time are gold for forecasting.
- **Lead generation for travel agencies** — surface routes where customers can save the most.

***

### Why use this actor

- **One actor, two modes** — switch with a single input field; same dataset shape per mode.
- **Stable structured JSON** — fixed schema, ready for spreadsheets, BI tools, or LLM pipelines.
- **No Skyscanner account required** — public data only.
- **Automatic retries** — up to 5 fresh exit IPs on rate-limit responses.
- **Cheapest-first ordering** in anywhere mode out of the box.
- **City context included** — every record optionally carries place metadata (name, country, coordinates).

***

### How it works

Pick a mode and the actor delivers the matching dataset:

1. You give the actor an origin airport, optionally a destination, market, and currency.
2. The actor talks to Skyscanner's pricing service.
3. Each price is turned into one structured record with the deep link to that exact search.
4. Records stream into the run's dataset and are immediately available as JSON, CSV, Excel, or XML.

Pagination, retries, and IP rotation are handled automatically.

***

### Input

```json
{
  "mode": "pricecalendar",
  "origin": "LHR",
  "destination": "JFK",
  "market": "UK",
  "locale": "en-GB",
  "currency": "GBP",
  "include_place_info": true,
  "max_results": 200,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

For anywhere mode:

```json
{
  "mode": "anywhere_inspiration",
  "origin": "LHR",
  "year": 2026,
  "month": 7,
  "market": "UK",
  "currency": "GBP",
  "adults": 1,
  "cabin_class": "ECONOMY",
  "max_results": 50,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| `mode` | string | yes | `pricecalendar` (default) or `anywhere_inspiration` |
| `origin` | string | yes | 3-letter IATA code for the departure airport |
| `destination` | string | for `pricecalendar` | 3-letter IATA code. Required for `pricecalendar`; ignored for `anywhere_inspiration` |
| `year` | integer | for `anywhere_inspiration` | Travel year (default: next month from today) |
| `month` | integer | for `anywhere_inspiration` | Travel month 1–12 (default: next month from today) |
| `market` | string | no | Two-letter Skyscanner market code (default `UK`) |
| `locale` | string | no | Language tag for the response (default `en-GB`) |
| `currency` | string | no | ISO 4217 currency for prices (default `GBP`) |
| `adults` | integer | no | Passenger count for anywhere mode (default 1) |
| `cabin_class` | string | no | `ECONOMY`, `PREMIUM_ECONOMY`, `BUSINESS`, `FIRST` for anywhere mode |
| `include_place_info` | boolean | no | When true (default) attaches city/country/coordinates to each record |
| `max_results` | integer | no | Hard cap on records pushed |
| `proxy` | object | no | Apify proxy configuration; residential recommended |

***

### Sample output — `pricecalendar` (daily)

Real data from an LHR → JFK run:

```json
{
  "mode": "pricecalendar",
  "route_origin": "LHR",
  "route_destination": "JFK",
  "market": "UK",
  "currency": "GBP",
  "date": "2026-05-14",
  "price": 341.89,
  "price_tier": "medium",
  "price_tier_label": "££",
  "deeplink": "https://www.skyscanner.net/transport/flights/lhr/jfk/260514/?adults=1&cabinclass=economy&currency=GBP&market=UK",
  "origin_place": {
    "iata": "LOND",
    "name": "London",
    "city": "London",
    "country": "United Kingdom",
    "location": "51.5041174139,-0.0943465343"
  },
  "destination_place": {
    "iata": "NYCA",
    "name": "New York",
    "city": "New York",
    "country": "United States",
    "location": "40.6940959901,-73.9282670243"
  }
}
```

### Sample output — `anywhere_inspiration`

Real data from a "cheapest flights from LHR in July 2026" run, sorted cheapest-first:

```json
{
  "mode": "anywhere_inspiration",
  "origin": "LHR",
  "destination_id": "27544891",
  "destination_iata": "CHIA",
  "destination_name": "Chicago, IL",
  "destination_city": "Chicago",
  "destination_region": "IL",
  "destination_continent": "North America",
  "year": 2026,
  "month": 7,
  "month_iso": "2026-07",
  "market": "UK",
  "currency": "GBP",
  "lowest_price": 32.0,
  "price_display": "£32",
  "direct": true,
  "image_url": "https://content.skyscnr.com/fb510ffb5376ed43182ec12f35594366/GettyImages-179123717.jpg",
  "deeplink": "https://www.skyscanner.net/transport/flights/lhr/chia/2607/?adults=1&cabinclass=economy&currency=GBP&market=UK",
  "origin_place": {
    "iata": "LOND",
    "name": "London",
    "city": "London",
    "country": "United Kingdom",
    "location": "51.5041174139,-0.0943465343"
  }
}
```

A single anywhere run returns up to ~100 destinations sorted cheapest-first.

***

### Output schemas

#### `pricecalendar`

| Field | Type | Description |
|---|---|---|
| `mode` | string | `pricecalendar` |
| `route_origin` / `route_destination` | string | IATA codes from your input |
| `date` | string | Travel date `YYYY-MM-DD` |
| `price` | number | Cheapest known one-way price for that date |
| `price_tier` | string | `low` / `medium` / `high` |
| `price_tier_label` | string | Skyscanner's visual label (`£` / `££` / `£££`) |
| `deeplink` | string | Direct Skyscanner search URL |
| `origin_place` / `destination_place` | object | City / country / coordinates when `include_place_info` |

#### `anywhere_inspiration`

| Field | Type | Description |
|---|---|---|
| `mode` | string | `anywhere_inspiration` |
| `origin` | string | Origin IATA from your input |
| `destination_id` | string | Skyscanner's internal numeric ID for the destination city |
| `destination_iata` | string | Destination IATA / sky code |
| `destination_name` | string | Full destination name (e.g. "Chicago, IL") |
| `destination_city` | string | City portion |
| `destination_region` | string | Region / state / country portion when present |
| `destination_continent` | string | Continent name |
| `year` / `month` / `month_iso` | int / int / string | Travel period |
| `lowest_price` | number | Cheapest fare to that destination in the chosen month |
| `price_display` | string | Same price with currency symbol prefix |
| `direct` | boolean | Whether the cheapest fare is direct or has connections |
| `image_url` | string | Editorial photo of the destination |
| `deeplink` | string | Direct Skyscanner search URL |
| `origin_place` | object | Origin metadata when `include_place_info` |

***

### Tips

- **Cheapest week in a year:** `pricecalendar` mode, sort by `price`, take the top 7.
- **Budget travel discovery:** `anywhere_inspiration` with your home airport — filter the dataset by `lowest_price <= 200`.
- **Compare markets:** the same route can be substantially cheaper in one market than another (try `market: "ID"` for Indonesia, `market: "DE"` for Germany).
- **Schedule daily runs:** capture snapshots over time to build a custom historical price database.
- **Combine with a flight-booking actor:** the `deeplink` on each record opens that exact search on Skyscanner — perfect for handoff to a search/booking page.

# Actor input Schema

## `mode` (type: `string`):

pricecalendar = daily cheapest prices for one route across ~360 days. anywhere\_inspiration = every destination Skyscanner indexes from one origin in a chosen month.

## `origin` (type: `string`):

3-letter IATA airport code for the departure city.

## `destination` (type: `string`):

Destination IATA code. REQUIRED when mode is "pricecalendar" — that mode fails without it. Leave empty for "anywhere\_inspiration", which searches every destination from the origin.

## `year` (type: `integer`):

Year of the travel month for anywhere\_inspiration. Ignored in pricecalendar mode.

## `month` (type: `integer`):

Travel month (1-12) for anywhere\_inspiration. Ignored in pricecalendar mode.

## `market` (type: `string`):

Two-letter Skyscanner market code that determines pricing rules and supplier availability (e.g. UK, US, ID, SG, AU, DE).

## `locale` (type: `string`):

Language/locale tag for the response, e.g. en-GB, en-US, id-ID.

## `currency` (type: `string`):

ISO 4217 currency code for prices (GBP, USD, EUR, IDR, ...).

## `adults` (type: `integer`):

Number of adult passengers (1-9). Used by anywhere\_inspiration.

## `cabin_class` (type: `string`):

Cabin class for anywhere\_inspiration: ECONOMY, PREMIUM\_ECONOMY, BUSINESS, FIRST.

## `include_place_info` (type: `boolean`):

If enabled, runs an autosuggest lookup for the origin (and destination, where applicable) and attaches city/country/coordinates to each output record.

## `max_results` (type: `integer`):

Hard cap on records pushed. pricecalendar returns up to 365; anywhere\_inspiration can return hundreds.

## `proxy` (type: `object`):

Apify proxy configuration. Residential is recommended for the best success rate; the actor automatically retries up to 5 times across different exit IPs if any attempt is rate-limited.

## Actor input object example

```json
{
  "mode": "pricecalendar",
  "origin": "LHR",
  "destination": "JFK",
  "year": 2026,
  "month": 7,
  "market": "UK",
  "locale": "en-GB",
  "currency": "GBP",
  "adults": 1,
  "cabin_class": "ECONOMY",
  "include_place_info": true,
  "max_results": 50,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "pricecalendar",
    "origin": "LHR",
    "destination": "JFK",
    "year": 2026,
    "month": 7,
    "market": "UK",
    "locale": "en-GB",
    "currency": "GBP",
    "adults": 1,
    "cabin_class": "ECONOMY",
    "include_place_info": true,
    "max_results": 50,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("xtracto/skyscanner-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "pricecalendar",
    "origin": "LHR",
    "destination": "JFK",
    "year": 2026,
    "month": 7,
    "market": "UK",
    "locale": "en-GB",
    "currency": "GBP",
    "adults": 1,
    "cabin_class": "ECONOMY",
    "include_place_info": True,
    "max_results": 50,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("xtracto/skyscanner-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "pricecalendar",
  "origin": "LHR",
  "destination": "JFK",
  "year": 2026,
  "month": 7,
  "market": "UK",
  "locale": "en-GB",
  "currency": "GBP",
  "adults": 1,
  "cabin_class": "ECONOMY",
  "include_place_info": true,
  "max_results": 50,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call xtracto/skyscanner-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xtracto/skyscanner-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/X2F5HGgqctq7ZvIHz/builds/KswhIzouLlzUkhPPU/openapi.json
