Skyscanner Flight Price Calendar Scraper
Pricing
from $1.20 / 1,000 price date collecteds
Skyscanner Flight Price Calendar Scraper
A full year of daily flight prices for any route. Find the cheapest date and the cheapest month, see how prices move across the calendar, and compare the same route across 52 country storefronts where fares genuinely differ. No account or login needed.
Pick a route. Get a full year of departure dates, each with the lowest price Skyscanner publishes for flying that day — the cheapest date, the cheapest date in every month, and where every other date sits against them. Then do the thing nobody else does: collect the same route from several country storefronts at once and see how differently it is priced. Built for travel agencies, affiliate publishers, revenue analysts and anyone who needs to answer "when is this route cheapest?" with data instead of a guess.
What you can do with it
- Find the cheapest date to fly on any route, up to about a year ahead, in one run.
- Chart a route's seasonality — cheapest and typical price per month, weekday versus weekend, the shape of the whole year.
- Compare markets — collect the same route as travellers in the US, the UK, India or Japan see it. These are genuinely different sets of fares, not one price converted, and the cheapest date can land in a different month.
- Feed a fare-alert or "best time to book" product with dated prices you can re-collect on a schedule and compare over time.
- Price a tour, a package or an ad campaign around the dates a route is actually cheap.
- Build route dashboards for a whole portfolio — a main route plus 20 more, across up to 8 markets, in a single run.
What you get
One result per departure date, per route, per market. A real result, abridged:
{"route": "LOND-NYCA","origin": "LOND","originName": "London","originQuery": "London","originType": "city","destination": "NYCA","destinationName": "New York","destinationQuery": "New York","destinationType": "city","date": "2026-11-29","weekdayName": "Sunday","isWeekend": true,"month": "2026-11","daysFromCollection": 105,"price": 212.59,"hasPrice": true,"currency": "GBP","currencyRequested": "GBP","currencyMatchesRequest": true,"priceBand": "low","market": "UK","marketName": "United Kingdom","isCheapestDate": true,"isCheapestInMonth": true,"priceRank": 1,"cheapestPriceInMonth": 212.59,"medianPriceInMonth": 257.59,"percentAboveCheapest": 0,"percentVsMedian": -24.52,"cheapestPriceInRange": 212.59,"cheapestDateInRange": "2026-11-29","isEstimated": true,"source": "skyscanner","collectedAt": "2026-08-16T16:23:15.876Z"}
That same route and that same departure date, collected across markets on the same day, came back at 212.59 GBP in the United Kingdom, 287.68 USD in the United States and 45,834 JPY in Japan — and the United States market's own cheapest date was not that date at all, but 2027-01-24 at 242.54 USD. Every result is labelled with the market it came from and the currency that actually came back.
Input reference
| Field | Type | Default | What it does |
|---|---|---|---|
origin | string | London | Where the trip starts. An airport code (LHR), a city code (LON, NYC) or a place name (London). Codes are used exactly as you type them. |
destination | string | New York | Where the trip ends, in the same forms. |
additionalRoutes | array | empty | More routes for the same run, one per line, as LHR-JFK or London > New York. Up to 20. |
placeMatching | select | city | How a place name is matched: the whole city and all its airports, or a single airport. |
market | select | US | The country storefront to price the route in. This chooses which fares you see, not just the currency. 52 markets available. |
currency | select | match the market | The currency to show prices in. Left alone, each market is priced the way travellers there see it. Every result is labelled with the currency that actually came back. |
locale | select | match the market | The language the market is browsed in. Recorded on every result; it does not change prices. |
compareMarkets | array | empty | Extra storefronts for the same route, one per line: UK, or UK:USD to fix the currency, or UK:USD:en-GB to fix the language too. Up to 7. |
startDate | date | empty | Keep only dates on or after this day. |
endDate | date | empty | Keep only dates on or before this day. |
maxDaysPerMarket | integer | 400 | Ceiling on how many dates are kept per route and market, counting from the earliest. The source publishes about 360, so the default keeps all of them. Maximum 400. |
onlyCheapestPerMonth | boolean | false | Compact seasonality view: about a dozen results per route and market instead of a full year. |
includeUnpricedDays | boolean | false | Keep dates with no published price, shown as empty. Blank dates are delivered as results and are billed like priced ones — see Pricing. Prices are never estimated or copied from another date. |
includeSeasonality | boolean | true | Adds the monthly cheapest and typical price, the cheapest-to-priciest ranking and the comparison columns. |
Output fields
| Field | Type | Description |
|---|---|---|
route | string | The route this result belongs to, as ORIGIN-DESTINATION. |
origin, destination | string | The places used, as the source identifies them. |
originName, destinationName | string | Readable names. |
originType, destinationType | string | city or airport. |
originQuery, destinationQuery | string | Exactly what you typed, so you can trace every result back to your input. |
date | string | Departure date, YYYY-MM-DD. |
weekdayName, isWeekend | string, boolean | Day of the week, and whether it is a weekend. |
month | string | YYYY-MM, ready to group by. |
daysFromCollection | integer | How far ahead of collection this date is. |
price | number | Lowest published price for departing on this date. Empty when the source published none. |
hasPrice | boolean | Whether a price was published for this date. |
currency | string | The currency the price actually came back in. |
currencyRequested, currencyMatchesRequest | string, boolean | What you asked for, and whether it matched. |
priceBand | string | The source's own low / medium / high grouping for this date. |
market, marketName, language | string | Which storefront the price came from. |
isCheapestDate | boolean | The cheapest date in the range you collected, for this route and market. |
isCheapestInMonth | boolean | The cheapest date within its own month. Ties go to the earlier date. |
priceRank | integer | 1 is the cheapest date in the range. |
cheapestPriceInMonth, medianPriceInMonth, pricedDatesInMonth | number, number, integer | Month-level context for this date. |
percentAboveCheapest | number | How much more than the cheapest date this date costs, as a percentage. |
percentVsMedian | number | How this date compares with the typical price for the range. |
cheapestPriceInRange, cheapestDateInRange, medianPriceInRange, pricedDatesInRange | number, string, number, integer | The same context at range level, repeated on every result so a single row stands alone. |
isEstimated | boolean | Always true: the source publishes these as indicative lowest prices, not as a quote. |
source | string | skyscanner. |
collectedAt | string | When the run collected this route. |
A run summary is also saved with the run: how many calendars were collected, how many routes had nothing published, and how many could not be read.
Pricing
You pay per result, plus a small amount for each extra market you compare.
| What you pay for | Price |
|---|---|
| Each departure date delivered — with its price, or blank if you keep dates with no published price | $0.0012 (that is $1.20 per 1,000) |
| Each extra market compared, beyond the first, for a route | $0.020 |
Worked example. One route, one market, the whole published year is about 360 dates: $0.43. Add two comparison markets and you get about 1,080 dated prices across three storefronts: 1,080 × $0.0012 = $1.30, plus 2 × $0.020 for the extra markets = $1.34 for the run.
One setting can multiply that. Include dates with no published price delivers every date in the range, blanks included, and a blank date is a result like any other and costs the same $0.0012. On a thin route that published 42 dates spread over 205 days, leaving it off gives you 42 results for $0.05; switching it on gives you 205 results for $0.25 — the same 42 prices, five times the bill. It is worth it when you need an unbroken day-by-day series; leave it off if you only want the dates that are actually sold.
The extra-market charge applies to any comparison storefront that answered — including one that answers that it sells nothing on your route, since that answer is the comparison you asked for. A storefront that could not be read is never charged.
Want it cheaper? Turn on only the cheapest date in each month and one route in one market costs about $0.02 — roughly a dozen results instead of 360 — or narrow the date range to the months you care about.
Limits & what this actor cannot do
- It gives you one lowest price per departure date, not a list of flights. There are no airlines, flight numbers, departure times, stop counts or fare rules in these results — the source does not publish them on this view.
- The number is the lowest price published for departing on that date. The source does not label it by trip length or fare type on this view, so treat it as an indicative floor for that day rather than a specific ticket.
- Prices are a snapshot at the moment of collection. Airline pricing changes continuously, and a price seen now may be gone hours later.
- This actor does not book, hold or reserve anything, and it cannot guarantee that a price is still available. The source itself describes these as estimated lowest prices.
- Markets are separate sets of fares, not one price converted. Never convert between markets to compare them: the same route can have a genuinely different cheapest date in two markets on the same day. Every result carries its own market and currency for exactly this reason.
- About a year ahead, rolling. The source publishes roughly 360 departure dates starting from the day you run it. Dates beyond that do not exist yet.
- Thin routes are sparse. On a quiet route the source publishes prices for some dates and nothing for others. Missing dates are left out, or shown empty if you ask for them — never filled in with a neighbouring date's price.
- A route with nothing published is reported as having nothing, and a route the source would not serve is reported as a failed read. The two are counted separately in the run summary, and a run where nothing could be read ends as a failed run rather than an empty success.
- An answer that cannot be used is a failed read too. You are never told a route publishes no dates on the strength of an answer this actor could not read. Where only some dates come back in a form it cannot use, those dates are left out, counted in the run summary and never guessed at.
- Routes are seasonal. A real route with no departures in the window you asked for is a legitimate empty result, not an error.
- How long a run takes depends on its size and on how quickly the source answers. No fixed speed is promised.
- The source's terms govern automated access. You are responsible for using the data lawfully and in line with those terms.
FAQ
Do I need a Skyscanner account? No. No account, no sign-up, nothing to connect.
Does it need my login or password? No. You supply a route and a market and nothing else.
Can I schedule it? Yes. Schedule it daily or weekly and compare the results over time — that is how a price-drop or best-time-to-book product gets built. Very frequent runs are not worth it: these prices move over days, not minutes.
Are these prices bookable? Treat them as indicative. They are the lowest prices the source publishes for each date, and airline pricing moves constantly. This actor reports what is published; it does not hold or book a seat.
Why do two markets disagree about the cheapest date? Because they are genuinely different sets of fares. A storefront in one country can be sold inventory another one is not. That disagreement is a real signal, and it is the reason the comparison feature exists.
Can I get airlines, flight times or stops? Not from this actor — the source does not publish them alongside these dated prices. Use it to find the right dates, then search those dates for the flight detail.
What happens if a route does not exist? You get a clear failed read naming the route, never a silent empty result that looks like "no flights".