# easyJet Scraper (`codingfrontend/easyjet-scraper`) Actor

Scrape public easyJet flight-search and low-fare route responses for one-way and round-trip itineraries when exact-date offers are exposed, with truthful diagnostics for month-level-only pages.

- **URL**: https://apify.com/codingfrontend/easyjet-scraper.md
- **Developed by:** [Coding Frontned](https://apify.com/codingfrontend) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 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.

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

## easyJet Scraper

### What does easyJet Scraper do?

This Actor reads public easyJet flight-search pages and extracts normalized flight-offer records when the public response exposes exact-date itinerary objects. Structured searches use airport codes, travel dates, trip type, and passenger counts to resolve the official public cheap-flights route. Fully formed public easyJet URLs are also supported.

The Actor does not log in, enter payment details, call private booking endpoints, solve CAPTCHAs, bypass access controls, or convert a month-level minimum into a dated flight.

### Current public-source boundary

The source boundary is HTTPS easyjet.com, including the public cheap-flights route. The current route page can render a low-fare finder with month-level prices such as September 2026 £31.99 and no exact-date flight objects. In that case the Actor emits a MONTHLY_FARE_ONLY diagnostic. A direct HTTP access challenge is emitted as SOURCE_BLOCKED. These are useful run outcomes, not successful exact-date flight extraction.

### Input

Use one or more structured searches or public easyJet URLs. The Actor requires at least one valid search or URL.

| Field | Type/default | Behavior |
| --- | --- | --- |
| searches | array | Objects with origin, destination, and departureDate. Optional returnDate, tripType, and passenger counts are source-request context. |
| startUrls | array | Fully formed HTTPS easyJet URLs. Invalid or duplicate entries are ignored; use a structured search when the URL is not valid. |
| maxItems | integer, default 100, range 1–1000 | Global maximum for emitted flight and diagnostic rows. |
| requestTimeoutSecs | integer, default 30, range 5–120 | Per-request timeout. |
| maxRetries | integer, default 1, range 0–2 | Finite retries for transient HTTP or transport failures. |
| retryDelayMs | integer, default 500, range 0–10000 | Bounded retry backoff in milliseconds. |
| requestDelayMs | integer, default 0, range 0–10000 | Respectful delay between ordered public requests. |
| proxyConfiguration | object, optional | One authorized standard Apify Proxy route for public requests; use is reported in OUTPUT. |
| fixtureJson | string, optional | Bounded offline JSON used for deterministic QA; no public request is made when present. |

For structured searches, normalized offers are retained only when their source-backed departureDate matches the requested departureDate. Passenger counts are carried into records when a source exposes or the request supplies them; they do not create availability that the source did not provide.

### Output

Each dataset item is either a flight record or a diagnostic record.

Normal flight fields contain only public business/source data: sourceUrl, canonicalUrl, sourceDomain, origin, destination, departureDate, optional returnDate, tripType, airline, optional flight number and times, durationMinutes, stops, price, currency, fareType, cabinClass, availability, passengerCount, bookingUrl, observedAt, and scrapedAt. Runtime identifiers, status flags, redirect/transport details, and extraction instrumentation are omitted from normal rows.

Diagnostic fields include recordType, dataAvailable=false, recordId, diagnosticCode, message, sourceUrl, canonicalUrl, finalUrl, sourceDomain, transport, extractionMethod, the requested route context when available, and scrapedAt.

The OUTPUT key-value record contains recordsCount, recordsStored, offerCount, diagnosticCount, observedDiagnosticCount, failedRequests, blockedCount, pagesFetched, pagesProcessed, dataAvailable, duplicate and drop counters, and completion time. Counts describe rows actually emitted to the dataset; suppressed diagnostic count is zero because diagnostics are not silently discarded.

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Example structured input

```
{
  "searches": [
    {
      "origin": "LGW",
      "destination": "AMS",
      "departureDate": "2026-10-01",
      "adults": 1,
      "tripType": "oneWay"
    }
  ],
  "maxItems": 100
}
```

### Example normal record

```
{
  "origin": "LGW",
  "destination": "AMS",
  "departureDate": "2026-10-01",
  "airline": "easyJet",
  "flightNumber": "U21234",
  "price": 49.99,
  "currency": "GBP",
  "sourceUrl": "https://www.easyjet.com/en/cheap-flights/LGW/AMS",
  "canonicalUrl": "https://www.easyjet.com/en/cheap-flights/LGW/AMS"
}
```

### Tips, cost, and limitations

Each public URL is fetched directly or through one supplied standard Apify Proxy route with bounded retries, an 8 MiB response-body limit, a three-hop official-host redirect limit, and a per-request timeout. Proxy rotation, login, stealth, CAPTCHA solving, and browser rendering are not used. Keep batches small and respect easyJet terms, robots guidance, rate limits, privacy obligations, and applicable law.

Actor cost depends on the actual runtime and platform allocation, including request time, retries, storage, and any platform resources used. No fixed price is promised here.

The Actor is not affiliated with easyJet. Public fare availability, prices, and dates can change after a run. A local fixture proves parser behavior only; it does not prove current source availability or Apify Cloud qualification.

### Local validation

From this Actor directory:

```
npm install
npm test
npm run lint
npm run validate
npm run check
apify validate-schema
apify run --purge --input-file test/inputs/fixture.json
```

To validate a particular stored run, set APIFY_LOCAL_STORAGE_DIR to that run's isolated storage before npm run validate. No remote build, run, deployment, or account mutation is performed by these local checks.

# Actor input Schema

## `searches` (type: `array`):

One or more public easyJet origin, destination, and date searches. Structured searches resolve to the official public cheap-flights route and filter embedded exact-date fares to the requested departure date; month-level low-fare charts are reported as diagnostics.

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

Optional fully formed public easyJet flight-search URLs.

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

Maximum number of unique flight offers to emit.

## `requestTimeoutSecs` (type: `integer`):

Maximum time to wait for a public easyJet page.

## `maxRetries` (type: `integer`):

Maximum finite retries for transient HTTP or transport failures.

## `retryDelayMs` (type: `integer`):

Bounded base retry delay.

## `requestDelayMs` (type: `integer`):

Respectful delay between ordered public requests.

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

Optional authorized standard Apify Proxy configuration for the public easyJet request.

## `fixtureJson` (type: `string`):

Optional JSON response used for local validation; no easyJet request is made when supplied.

## Actor input object example

```json
{
  "searches": [],
  "startUrls": [],
  "maxItems": 100,
  "requestTimeoutSecs": 30,
  "maxRetries": 1,
  "retryDelayMs": 500,
  "requestDelayMs": 0
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `output` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("codingfrontend/easyjet-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("codingfrontend/easyjet-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 '{}' |
apify call codingfrontend/easyjet-scraper --silent --output-dataset

```

## MCP server setup

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