# Ryanair Flight Availability Scraper (`datascrapers/ryanair-scraper`) Actor

Delivers structured Ryanair flight availability, fare, and calendar records for origin/destination routes, queried by IATA codes and travel dates.

- **URL**: https://apify.com/datascrapers/ryanair-scraper.md
- **Developed by:** [Farhan Ali](https://apify.com/datascrapers) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 flights

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

**Ryanair Flight Availability Scraper** creates a structured dataset of Ryanair flight availability, priced fares, and calendar dates for origin/destination routes. Each dataset item can include the flight number, origin and destination airports, scheduled times, duration, fare amount and currency, remaining seat count, and a booking URL. Query the source using IATA codes and travel dates or a Ryanair flight-select URL, control the result limit with `maxItems`, and retrieve records through the Apify Dataset API or export them as JSON, CSV, Excel, or XML.

### Dataset at a glance

| Property | Value |
|---|---|
| Source | ryanair.com |
| Record unit | One flight or one available calendar date |
| Input methods | IATA codes and dates, or Ryanair start URLs |
| Main identifiers | `flightKey`, `flightNumber`, `bookingUrl` |
| Delivery | Apify Dataset and API |
| Export formats | JSON, CSV, Excel, XML |
| Update model | Fresh records per Actor run |
| Pricing | Pay per event, $2 per 1,000 flights |

### Coverage and available records

The Actor returns two record types, controlled by `scrapeMode`:

- **`flight`** — priced flight legs with departure/arrival times, duration, fare amount, currency, and remaining inventory.
- **`availableDate`** — calendar days on which a flight operates, without fare details.

Supported behavior includes:

- **Return and one-way trips** via `tripType` (`auto`, `return`, `oneway`).
- **All destinations from one origin** by leaving `destinationIata` empty.
- **Date ranges** via `dateOutEnd` / `dateInEnd` and `flexDays` (±0–6 days, matching the site calendar).
- **Multiple routes** through the `routes` array, and **start URLs** parsed from the query string.
- **Passenger mix** (adults, teens, children, infants) and optional `promoCode`, connecting flights, and Prime fares.

### Data dictionary

| Field | Type | Nullable | Description | Example |
|---|---:|---|---|---|
| `recordType` | string | No | `flight` or `availableDate` | `flight` |
| `flightKey` | string | No | Ryanair flight key | `FR~2527` |
| `flightNumber` | string | No | Marketing flight number | `FR 2527` |
| `origin` | string | No | Origin IATA code | `BER` |
| `originName` | string | No | Origin airport name | `Berlin` |
| `destination` | string | No | Destination IATA code | `MAD` |
| `destinationName` | string | No | Destination airport name | `Madrid` |
| `direction` | string | No | `outbound` or `inbound` | `outbound` |
| `departureDate` | string | No | Local departure date `YYYY-MM-DD` | `2026-11-28` |
| `departureTime` | string | No | Local departure datetime | `2026-11-28T06:45:00` |
| `arrivalTime` | string | No | Local arrival datetime | `2026-11-28T10:10:00` |
| `departureUtc` | string | No | Departure datetime in UTC | `...` |
| `arrivalUtc` | string | No | Arrival datetime in UTC | `...` |
| `duration` | string | No | Scheduled duration `HH:MM` | `03:25` |
| `faresLeft` | integer | No | Remaining fare inventory; `-1` when unknown | `9` |
| `infantsLeft` | integer | No | Remaining infant seats | `0` |
| `operatedBy` | string | Yes | Operating carrier when not Ryanair | — |
| `fareAmount` | number | No | Cheapest regular fare amount | `29.99` |
| `publishedFare` | number | No | Published fare before discounts | `34.99` |
| `currency` | string | No | Fare currency | `EUR` |
| `passengerType` | string | No | Fare passenger type such as `ADT` | `ADT` |
| `hasDiscount` | boolean | No | Whether a discount is applied | `false` |
| `discountAmount` | number | No | Discount amount | `0.0` |
| `isPrime` | boolean | No | Whether the fare is a Prime fare | `false` |
| `fareKey` | string | No | Fare identifier from the booking response | — |
| `stops` | integer | No | Number of stops | `0` |
| `segmentCount` | integer | No | Number of flight segments | `1` |
| `segments` | array | No | Segment list with times and flight numbers | `[...]` |
| `isRoundTrip` | boolean | No | Whether the search was a return trip | `true` |
| `market` | string | No | Ryanair market such as `de-de` | `de-de` |
| `adults` | integer | No | Adult passengers in the search | `1` |
| `teens` | integer | No | Teen passengers in the search | `0` |
| `children` | integer | No | Child passengers in the search | `0` |
| `infants` | integer | No | Infant passengers in the search | `0` |
| `promoCode` | string | No | Promo code applied to the search | — |
| `bookingUrl` | string | No | Ryanair flight-select URL | `https://www.ryanair.com/...` |

### Example dataset record

```json
{
  "recordType": "flight",
  "flightNumber": "FR 2527",
  "origin": "BER",
  "destination": "MAD",
  "direction": "outbound",
  "departureDate": "2026-11-28",
  "departureTime": "2026-11-28T06:45:00",
  "arrivalTime": "2026-11-28T10:10:00",
  "duration": "03:25",
  "fareAmount": 29.99,
  "currency": "EUR",
  "faresLeft": 9,
  "market": "de-de",
  "adults": 1,
  "bookingUrl": "https://www.ryanair.com/de/de/trip/flights/select?..."
}
```

The record above was produced by the input in the next section: `BER` to `MAD` on `2026-11-28`, return trip, `scrapeMode: "both"`.

### Query and input reference

| Input | Type | Required | Default | Accepted values | Description |
|---|---:|---|---|---|---|
| `originIata` | string | No | — | 3-letter IATA code | Departure airport |
| `destinationIata` | string | No | — | 3-letter IATA code | Arrival airport; empty expands all destinations from origin |
| `dateOut` | string | No | — | `YYYY-MM-DD` | Outbound date |
| `dateIn` | string | No | — | `YYYY-MM-DD` | Return date; omit for one-way |
| `dateOutEnd` | string | No | — | `YYYY-MM-DD` | Last outbound date when walking the calendar |
| `dateInEnd` | string | No | — | `YYYY-MM-DD` | Last return date when browsing inbound dates |
| `tripType` | string | No | `auto` | `auto`, `return`, `oneway` | Trip type |
| `routes` | array | No | — | Route objects | Extra routes with the same fields |
| `startUrls` | array | No | — | Ryanair flight-select URLs | URLs parsed from the query string |
| `adults` | integer | No | `1` | `1`–`25` | Adult passengers |
| `teens` | integer | No | `0` | `0`–`24` | Teen passengers |
| `children` | integer | No | `0` | `0`–`24` | Child passengers |
| `infants` | integer | No | `0` | `0`–`24` | Infant passengers |
| `promoCode` | string | No | — | Ryanair promo code | Promo code applied to the search |
| `includeConnectingFlights` | boolean | No | `false` | `true` / `false` | Include connecting itineraries |
| `includePrimeFares` | boolean | No | `false` | `true` / `false` | Request Prime fares |
| `flexDays` | integer | No | `2` | `0`–`6` | Days before and after requested dates |
| `market` | string | No | `en-ie` | e.g. `en-ie`, `de-de`, `es-es` | Market/locale |
| `scrapeMode` | string | No | `flights` | `flights`, `availableDates`, `both` | What to scrape |
| `maxItems` | integer | No | `0` | `0` = unlimited | Maximum records |
| `proxyConfiguration` | object | No | Residential | Apify proxy settings | Proxy configuration |

Minimal request:

```json
{
  "originIata": "BER",
  "destinationIata": "MAD",
  "dateOut": "2026-11-28"
}
```

Advanced request:

```json
{
  "originIata": "BER",
  "destinationIata": "MAD",
  "dateOut": "2026-11-28",
  "dateIn": "2026-12-01",
  "tripType": "return",
  "adults": 1,
  "market": "de-de",
  "flexDays": 2,
  "scrapeMode": "both",
  "maxItems": 100
}
```

### Retrieve the data through the API

1. Start the Actor with a JSON input containing `originIata`, `destinationIata`, and `dateOut`.
2. Wait for the run to finish, or use the synchronous dataset endpoint for smaller jobs.
3. Read records from the run's default dataset.
4. Paginate or export the dataset.

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("datascrapers/ryanair-scraper").call(
    run_input={
        "originIata": "BER",
        "destinationIata": "MAD",
        "dateOut": "2026-11-28",
        "dateIn": "2026-12-01",
        "scrapeMode": "both",
        "maxItems": 50,
    }
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["recordType"], item["flightNumber"], item.get("fareAmount"))
```

Apify's generated API tab documents the equivalent calls for other languages.

### Data quality and record handling

- **Completeness** — `fareAmount` is present only on `flight` records; `availableDate` records carry dates only.
- **Source changes** — fares and availability reflect the response at scrape time and can change between runs.
- **Deduplication** — the Actor does not deduplicate across runs; each run writes to a new dataset.
- **Recommended dedup key** — `flightKey` + `direction` + `departureDate` (+ `fareAmount`) for fare history; `origin|destination|departureDate` for calendar days.
- **Retry/error behavior** — per-window extraction fails soft, so a single bad date does not stop the run.

### Export and pipeline examples

| Destination | Recommended method | Typical use |
|---|---|---|
| PostgreSQL/Supabase | Dataset API or webhook consumer | Fare history and route research |
| Google Sheets | Apify integration | Deal tracking |
| S3/cloud storage | Scheduled export or integration | Price snapshots |

### Pricing and cost examples

Billing is **pay per event**: each dataset record pushed is one charge. Platform compute is included in the actor usage fee.

| Records | Estimated base cost |
|---:|---:|
| 1,000 | $2.00 |
| 10,000 | $20.00 |
| 100,000 | $200.00 |

Apify plan discounts reduce the per-event rate (for example Gold plans pay about $1.70 per 1,000 flights). Estimates depend on the verified pricing model and `scrapeMode`.

### Limitations and responsible data use

- Only publicly available Ryanair flight data is returned.
- Fares and availability change frequently; records reflect the moment of collection.
- Fields such as `fareAmount` and `faresLeft` are conditional on the record type and response.
- No historical snapshots are stored unless you keep them yourself.
- You are responsible for complying with Ryanair's terms and applicable laws.

### Dataset questions

#### What does one dataset item represent?

One priced flight or one available calendar date, depending on `scrapeMode`.

#### Which field should I use as a unique identifier?

Use `flightKey` plus `direction` and `departureDate` for flights; for calendar days use `origin|destination|departureDate`.

#### Are fields nullable or conditional?

Yes. `fareAmount` and related fare fields are only present on `flight` records; `availableDate` records carry no fares.

#### Can I retrieve the records as CSV or JSON?

Yes. Export the default dataset as JSON, CSV, Excel, or XML, or read it through the Apify Dataset API.

#### How do I paginate large datasets?

Set `maxItems` to cap output, or paginate the dataset through the Dataset API.

#### What counts as a billable result?

Each flight or available-date record pushed to the dataset is one event charge.

### Related datasets from Data Scrapers

- **[Booking.com Scraper](https://apify.com/datascrapers/booking-com-scraper)** — hotel availability and pricing for the same travel-intelligence workflows.
- **[Skyscanner Scraper](https://apify.com/datascrapers/skyscanner-scraper)** — flight search records that join with Ryanair route data for fare comparison.
- **[HRS Scraper](https://apify.com/datascrapers/hrs-scraper)** — hotel records for end-to-end trip planning.
- **[TripAdvisor Reviews Scraper](https://apify.com/datascrapers/tripadvisor-reviews-scraper)** — destination and property review data for travel research.

### Data Scrapers support

Need an additional field, record type, or export workflow? Contact Data Scrapers at stardustspotlight@gmail.com. Include a sample source URL, required fields, expected record volume, and preferred delivery format.

# Actor input Schema

## `originIata` (type: `string`):

3-letter IATA code of the departure airport, for example BER or STN.

## `destinationIata` (type: `string`):

3-letter IATA code of the arrival airport, for example MAD or BCN. Leave empty to scrape every destination served from the origin.

## `dateOut` (type: `string`):

Outbound travel date (YYYY-MM-DD). If omitted for flights mode, the first calendar date is used.

## `dateIn` (type: `string`):

Return travel date (YYYY-MM-DD). Leave empty for a one-way search.

## `dateOutEnd` (type: `string`):

Optional last outbound date. The Actor walks DateOut in flex-day windows up to this date, the same way the site calendar does.

## `dateInEnd` (type: `string`):

Optional last return date when browsing inbound dates with a fixed outbound date.

## `tripType` (type: `string`):

return uses dateIn. oneway ignores the return date. auto treats the search as return when dateIn is set.

## `routes` (type: `array`):

Optional extra routes. Each object may include originIata, destinationIata, dateOut, dateIn, and the same passenger fields as the top-level input.

## `startUrls` (type: `array`):

Optional Ryanair flight-select or search URLs. Origin, destination, dates, and passengers are read from the query string.

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

Number of adult passengers (16+).

## `teens` (type: `integer`):

Number of teen passengers (12-15).

## `children` (type: `integer`):

Number of child passengers (2-11).

## `infants` (type: `integer`):

Number of infant passengers (under 2).

## `promoCode` (type: `string`):

Optional Ryanair promo or voucher code applied to the fare search.

## `includeConnectingFlights` (type: `boolean`):

When enabled, the search includes connecting itineraries.

## `includePrimeFares` (type: `boolean`):

When enabled, Prime fares are requested in the availability search.

## `flexDays` (type: `integer`):

Days before and after the requested dates, matching the site calendar (0-6). Each request covers this window.

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

Ryanair market used in booking URLs and availability, for example en-ie, de-de, or es-es.

## `scrapeMode` (type: `string`):

flights returns priced flights. availableDates returns calendar dates that have a flight. both returns calendar dates then priced flights.

## `maxItems` (type: `integer`):

Maximum number of records to scrape (0 = unlimited).

## `proxyConfiguration` (type: `object`):

Residential proxies are recommended for reliable availability results.

## Actor input object example

```json
{
  "originIata": "BER",
  "destinationIata": "MAD",
  "dateOut": "2026-11-28",
  "dateIn": "2026-12-01",
  "tripType": "auto",
  "startUrls": [
    {
      "url": "https://www.ryanair.com/de/de/trip/flights/select?adults=1&teens=0&children=0&infants=0&dateOut=2026-11-28&dateIn=2026-12-01&isConnectedFlight=false&discount=0&promoCode=&isReturn=true&originIata=BER&destinationIata=MAD"
    }
  ],
  "adults": 1,
  "teens": 0,
  "children": 0,
  "infants": 0,
  "includeConnectingFlights": false,
  "includePrimeFares": false,
  "flexDays": 2,
  "market": "de-de",
  "scrapeMode": "flights",
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset of flight and available-date records

## `runStats` (type: `string`):

Record count and timestamps for this run

# 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 = {
    "originIata": "BER",
    "destinationIata": "MAD",
    "dateOut": "2026-11-28",
    "dateIn": "2026-12-01",
    "startUrls": [
        {
            "url": "https://www.ryanair.com/de/de/trip/flights/select?adults=1&teens=0&children=0&infants=0&dateOut=2026-11-28&dateIn=2026-12-01&isConnectedFlight=false&discount=0&promoCode=&isReturn=true&originIata=BER&destinationIata=MAD"
        }
    ],
    "market": "de-de",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datascrapers/ryanair-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 = {
    "originIata": "BER",
    "destinationIata": "MAD",
    "dateOut": "2026-11-28",
    "dateIn": "2026-12-01",
    "startUrls": [{ "url": "https://www.ryanair.com/de/de/trip/flights/select?adults=1&teens=0&children=0&infants=0&dateOut=2026-11-28&dateIn=2026-12-01&isConnectedFlight=false&discount=0&promoCode=&isReturn=true&originIata=BER&destinationIata=MAD" }],
    "market": "de-de",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("datascrapers/ryanair-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 '{
  "originIata": "BER",
  "destinationIata": "MAD",
  "dateOut": "2026-11-28",
  "dateIn": "2026-12-01",
  "startUrls": [
    {
      "url": "https://www.ryanair.com/de/de/trip/flights/select?adults=1&teens=0&children=0&infants=0&dateOut=2026-11-28&dateIn=2026-12-01&isConnectedFlight=false&discount=0&promoCode=&isReturn=true&originIata=BER&destinationIata=MAD"
    }
  ],
  "market": "de-de",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call datascrapers/ryanair-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datascrapers/ryanair-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/gnv9P0TA17BkHlbDu/builds/EfpOjDZA1ZxW4kHie/openapi.json
