# SiteVerdict — UK261/EU261 Flight Compensation Checker (`siteverdict/siteverdict-flight-compensation`) Actor

Cited UK261 (£220/£350/£520) or EU261 (€250/€400/€600) estimate for a delayed, cancelled or overbooked flight IF the Regulation's conditions are met: reasons, certainty, time limit, ADR route, claim pack. Booking references are never stored. Not legal advice. Your API key or manual times.

- **URL**: https://apify.com/siteverdict/siteverdict-flight-compensation.md
- **Developed by:** [Aman Thakran](https://apify.com/siteverdict) (community)
- **Categories:** Travel, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## SiteVerdict — Flight Delay & UK261/EU261 Compensation Checker

**An estimate, in seconds, of which fixed-compensation band UK261 (£220 / £350 / £520) or EU261 (€250 / €400 / €600) would give for a delayed, cancelled or overbooked flight — IF the Regulation's conditions are met — with the reasons, the articles and court cases behind each point, the claim time limit, the UK ADR/PACT/court route and a claim-letter template.**

> ⚖️ **Estimate only. Not legal advice, and not a determination that you are owed anything.** The checker tests the conditions that can be tested from flight facts (route, carrier, delay, notice, distance). It cannot know *why* a flight was disrupted. Airlines may refuse to pay for "extraordinary circumstances", must prove them, and a dispute is decided by an ADR body or a court, not by this tool. Check with the airline, the UK CAA or the relevant EU enforcement body before relying on a result.

- **Deterministic and cited.** Every result is `yes` (the testable conditions are met), `no` or `maybe`, with a `certainty` grade (`likely` / `uncertain` / `unlikely`, or `not_applicable` when neither regulation applies), reasons that cite the Regulation articles (legislation.gov.uk / EUR-Lex) and the leading cases (Sturgeon, Germanwings, Wallentin-Hermann, Folkerts, Bossen, Wegener, Huzar, Chelluri and others), and an explicit list of what flight data cannot tell you. It is a rules engine, not an LLM guess.
- **Both regimes, post-Brexit.** UK261 (Reg 261/2004 as amended for the UK by SI 2019/278 and SI 2023/1370) and EU261 are assessed separately: departure/arrival state, operating-carrier licence (UK / EU "Community" / EEA-Swiss / other), pre-2021 flights, the single-booking connection rule, and the EU's 2026 reform date.
- **Flight data from your own licensed key, or none at all.** Lookups via **AeroDataBox** (RapidAPI, API.Market or direct), **FlightAware AeroAPI**, **Aviationstack** or **OAG** (experimental) using *your* key. It never scrapes airline or flight-tracker websites. Manual-times mode needs no key and is clock-change safe when you give the arrival time zone.
- **UK routing built in.** The CAA-approved ADR body for the operating airline (AviationADR or CEDR), PACT where there is none, and the court route (Money Claim Online, Simple Procedure in Scotland, small claims in Northern Ireland), plus an evidence checklist and a letter template.
- **Distances use the great-circle method** required by Art. 7(4), from the [OurAirports](https://ourairports.com/data/) open dataset (public domain, about 9,400 airports).

### Who it is for

- **Travellers and travel managers** checking one flight or a whole trip before writing to the airline.
- **Travel agents, TMCs and tour operators** triaging "is this worth claiming?" for clients in bulk, with a CSV per claim.
- **Claims-handling teams and legal-tech builders** who need a transparent, cited first-pass estimate with a stable JSON schema, and **AI agents** through the SiteVerdict MCP tool (see `MCP-TOOL.md`).

### What you get per flight

| Field | Meaning |
|---|---|
| `eligible` | `yes` = the conditions that can be tested are met; `no` = a tested condition fails or the flight is out of scope; `maybe` = something material is missing or the airline's reason may be an extraordinary circumstance. **Never a statement that money is owed.** |
| `certainty` | `likely` (conditions met and the stated cause is one courts generally do not accept as extraordinary), `uncertain` (cause unknown or facts missing), `unlikely`, `not_applicable`. The `assessment.unknowns[]` list says what no flight feed can establish. |
| `headline`, `primaryRegime`, `amountPerPassenger`, `currency`, `totalAmount` | The regime to claim under (normally the departure country's), the band amount in GBP **or** EUR (never converted), and the total for all passengers. |
| `reducedBy50`, `amountIfAirlineReduces` | The Art. 7(2) 50% reduction: `applied` for a 3–4h delay on flights over 3,500 km, or `possible` where the airline *may* reduce after re-routing. |
| `bandExplanation[]` | Plain English: the distance, the UK band in pounds and the EU band in euro side by side, and when the 50% rule bites. |
| `applicability` | Journey origin and final destination (single booking) vs this leg, zones (UK / EU / EEA_CH / SPECIAL / OTHER), operating vs marketing carrier, effective licence, why UK261 and EU261 do or do not apply, post-Brexit flag. |
| `regimes[]` | UK261 and EU261 assessed separately: scope (Art. 3), distance band, amount, reasons and citation ids. |
| `distanceKm`, `distanceBasis` | Great-circle distance from the first departure airport to the final destination (Bossen C-559/16). Figures within 25 km of a band edge are flagged. |
| `flight` | What your provider returned: scheduled and actual times (UTC and local), status, cancellation, diversion, aircraft, the provider's own distance, and notes. |
| `extraordinaryCircumstances` | How courts have treated the airline's *stated* reason (weather, ATC, own-staff strike, technical fault…), with case law. We cannot verify the reason itself. |
| `rightToCare` | Meals, communications, hotel and the 5-hour refund option (Arts 6, 8 and 9). |
| `claimTimeLimit` | England & Wales 6 years (Limitation Act 1980 s.9, named in UK261 Art. 3(9)); Scotland 5 years (estimate); Northern Ireland 6 years. EU limits are national and indicative. |
| `assessment` | **Stable structured schema 1.0** for integrators — see below. Includes `adrRoute` (ADR body / PACT / court), `nextSteps[]`, `evidence[]`, `limitationDeadline`, `disclaimer`. |
| `montrealConvention`, `links`, `citations[]` | Proven-loss notes (6,303 SDR delay cap from 28 Dec 2024), the airline claim page where a public URL was verified, CAA/ADR/Your Europe guidance, and the full reference list with URLs. CJEU rulings from after 2020 are flagged `ukBinding: false`. |

The dataset has four views: **Estimates**, **Flight data**, **Reasons & citations** and **Assessment**.

#### The `assessment` schema (version 1.0)

```json
{ "schemaVersion": "1.0", "regime": "UK261", "eligible": true, "band": 2, "bandLabel": "between 1,500 and 3,500 km",
  "amountGBP": 350, "amountEUR": null, "amountIfAirlineReduces": { "GBP": null, "EUR": null },
  "passengers": 2, "totalGBP": 700, "totalEUR": null,
  "reasons": ["Departs a UK airport — UK261 Art. 3(1)(a) covers any airline.", "Arrival delay 3h 25m at the final destination is 3 hours or more — ..."],
  "certainty": "uncertain", "certaintyBasis": "The testable conditions are met, but the cause of the disruption is unknown ...",
  "unknowns": ["The real cause of the disruption: weather ...", "..."],
  "limitationDeadline": { "jurisdiction": "england-wales", "label": "England & Wales", "deadline": "2032-09-14", "years": 6, "status": "in_time", "confidence": "statutory", "note": "..." },
  "adrRoute": { "body": "aviationadr", "name": "AviationADR (Consumer Dispute Resolution Ltd, CDRL)", "url": "...", "startUrl": "...", "basis": "...", "binding": "...", "caaApproved": true, "membershipVerified": true, "conflict": null,
                "court": { "region": "england-wales", "name": "Money Claim Online / county court small claims (England & Wales)", "url": "https://www.gov.uk/make-court-claim-for-money", "note": "..." } },
  "nextSteps": ["1. Write to the OPERATING airline ...", "2. Keep the evidence ...", "3. If the airline rejects ... escalate to ...", "4. Last resort: ..."],
  "evidence": [{ "item": "Booking confirmation ...", "why": "...", "required": "essential" }],
  "disclaimer": "ESTIMATE ONLY — ..." }
```

`eligible` is `true`, `false` or `"unknown"`. `amountGBP` is set only for UK261 and `amountEUR` only for EU261. `adrRoute` is `null` for EU261 claims (use the national enforcement body shown in `links`). Field names and types will not change within 1.x.

#### Claim pack (optional)

Set `claimPack: true` and the run also writes two files to the key-value store:

- `CLAIM-PACK.md` — one letter template per claim estimated `yes` or `maybe` under UK261 or EU261, addressed to the **operating** airline: the flight facts you supplied, the band claimed under the right article, a request that the airline state any extraordinary circumstances in writing, and the ADR/PACT escalation. Personal details are left as `[brackets]` for you to fill in offline. Claims the checker estimates `no`, or that fall outside both regulations, get no letter: they are listed under "Claims with no letter" with the reason, and the dataset row shows `claimPackLetter: { written: false, reason }`.
- `CLAIMS.csv` — one row per claim (reference = `claim-<n>`, route, carrier, delay, regime, eligible, certainty, band, amountGBP, amountEUR, limitation deadline, ADR body, top reason). No name, PNR, passport or contact fields exist in the schema.

**The `reference` you type is never stored** (since 1.1.0): every dataset row, CSV row and claim-pack entry is labelled `claim-<n>`, where n is the claim's position in `claims` (1-based). No copy, hash or other derivative of your reference is kept in the dataset, OUTPUT, claim pack, CSV or log, so the link between `claim-<n>` and your own label exists only in your input: keep your own list if you need it. Dataset rows arrive in completion order (claims run in parallel), so sort or join by `reference`, not by row position; CLAIM-PACK.md and CLAIMS.csv are already in input order. The field is still accepted (older inputs keep working) and still checked: anything that looks like a booking reference (PNR), a passport number, an e-mail address or a labelled ticket number makes the claim an uncharged error row with an explanation, and the row carries `referenceRefused: true`. The Apify platform keeps the run input itself (the INPUT record) under your account's data retention, so leave booking references, passport numbers, e-mail addresses and names out of the input altogether. Ordinary labels and flight numbers (`trip-1`, `claim1`, `BA2490`, `EZY123`) are accepted (and not stored). A 6-character upper-case code mixing letters and digits that is not a flight number of a known airline (`ABC123`) is refused as a likely booking reference, and so is a 6-letter upper-case code with no vowel (`XKPQLM`). A 6-letter upper-case word such as `LONDON` is accepted with a warning. `flightNumber` is screened the same way. In every field, a value that fails validation (for example an e-mail address typed into `departureAirport`, text in `cancellationNoticeDays` or `singleBooking`, or an arrival delay outside −1,440 to 43,200 minutes, i.e. 1 day early to 30 days late, whether typed in minutes or computed from `scheduledArrival`/`actualArrival`) is never repeated back: the error names the field and the reason only, and the claim is an uncharged error row. Number fields take JSON numbers and yes/no fields take JSON `true`/`false` (not text). Text fields have length limits (64 characters for `reference`, `flightNumber` and free-text fields; 32 for airport/airline codes and `date`; 40 for times): a longer value is refused before it is read, with an uncharged error row. A fractional `cancellationNoticeDays` (e.g. 13.5) is accepted and shown to 1 decimal place, rounded down.

### Pricing

Pay per event. You are charged only when an estimate is produced:

| Event | When it is charged | Price |
|---|---|---|
| `flight-checked` | Your flight-data provider found the flight **and** a cited UK261/EU261 estimate was produced | **$0.05** |
| `claim-assessed` | A cited estimate was produced from facts you entered yourself (no provider lookup) | **$0.02** |

**Not charged:** input errors, flights your provider could not find, rows where an estimate could not be built (these are saved with `charged: false`), and `sample` mode. The claim pack is included in the same event.

**Examples:** 100 manual claims = 100 × $0.02 = **$2.00**. 1,000 flights checked through your provider key = **$50.00**.

**Spending limit:** set *Maximum cost per run* in the run options. Before each paid lookup the Actor checks there is budget left, and it stops cleanly when the limit is reached, so your provider quota is not used for results you would not be charged for.

Your flight-data provider (AeroDataBox, FlightAware AeroAPI, Aviationstack or OAG) bills you separately under its own terms for the lookups made with your key.

### Examples

**1. Manual check, no key needed.** Gatwick to Faro, easyJet UK, landed 3h25 late, 2 passengers:

```json
{ "provider": "none", "claimPack": true,
  "claims": [ { "departureAirport": "LGW", "arrivalAirport": "FAO", "operatingCarrier": "EZY",
                "date": "2026-09-14", "scheduledArrival": "2026-09-14T09:50", "actualArrival": "2026-09-14T13:15",
                "arrivalTimeZone": "Europe/Lisbon", "passengers": 2 } ] }
```

→ row `claim-1`: `yes`, `certainty: uncertain` (cause unknown), UK261 band **£350 per passenger, £700 for two** if no extraordinary circumstances are proved; 1,688 km = band 2; ADR route AviationADR; letter and CSV written.

**2. Lookup with your AeroDataBox key (RapidAPI):**

```json
{ "provider": "aerodatabox", "aerodataboxGateway": "rapidapi", "apiKey": "<your RapidAPI key>",
  "claims": [ { "flightNumber": "BA117", "date": "2026-09-14" } ] }
```

**3. A cancellation:** you were told 3 days before, and the airline offered no re-routing:

```json
{ "claims": [ { "departureAirport": "STN", "arrivalAirport": "BCN", "operatingCarrier": "RYR",
                "date": "2026-09-21", "cancellationNoticeDays": 3, "rerouteOffered": false } ] }
```

**4. A connection on a single booking** (Edinburgh to London to New York), 3h20 late at the final destination: send `journeyOrigin: "EDI"`, `departureAirport: "LHR"`, `arrivalAirport: "JFK"`, `finalDestination: "JFK"`, `singleBooking: true` and `finalArrivalDelayMinutes: 200`. The estimate is £260, because the trip is band 3 and a 3–4h delay gets the 50% rate. The same legs on a **non-UK/EU carrier starting outside the UK** (e.g. Kansas City → Detroit → Heathrow → Mumbai on Delta/Air India) come back `no`: the booking is treated as departing from its first airport (Art. 3(1A); *Chelluri v Air India* \[2021] EWCA Civ 1953).

**5. Try it free:** set `provider: "sample"` and use the synthetic demo flights `BA9901` (2026-09-14), `U29902` (2026-09-20), `FR9903` (2026-09-21) and `LH9904` (2026-09-22). They aren't real flights and aren't charged.

#### All claim fields

`reference` (optional and never stored: rows are labelled `claim-<n>` by input position; never put PNRs, names or passport numbers in it), `flightNumber`, `date` (local departure date, `YYYY-MM-DD`), `departureAirport`, `arrivalAirport` (IATA or ICAO), `operatingCarrier` (IATA or ICAO; **ICAO is better** because group airlines share IATA codes, e.g. U2 = easyJet UK (EZY), easyJet Europe (EJU) or easyJet Switzerland (EZS)), `marketingCarrier` (optional, the code on the ticket when different), `carrierLicence` (`UK`, `EU`, `EEA_CH` or `OTHER`; overrides the built-in table), `disruption` (`auto`, `delay`, `cancellation`, `denied_boarding` or `diversion`), `scheduledArrival` / `actualArrival` (local time at the arrival airport, with no offset; or both with offsets), `arrivalTimeZone` (IANA zone such as `Europe/London`, makes the subtraction clock-change safe), `actualArrivalBasis` (`doors_open` — the legal arrival time — or `gate` or `runway`), `arrivalDelayMinutes`, `scheduledDeparture` / `actualDeparture` (for right-to-care thresholds), `journeyOrigin`, `finalDestination`, `singleBooking`, `finalArrivalDelayMinutes`, `cancellationNoticeDays`, `rerouteOffered`, `rerouteDepartedMinutesEarly`, `rerouteArrivalDelayMinutes`, `deniedBoardingVoluntary`, `deniedBoardingReason`, `airlineReason`, `passengers`, `jurisdiction` (`england-wales`, `scotland`, `northern-ireland`, `eu-de`, `eu-fr`, `eu-ie`, `eu-es`, `eu-other`), `adrBody` (`aviationadr`, `cedr` or `pact` to override routing), `checkedInOnTime`, `freeOrNonPublicFare` and `alreadyCompensatedElsewhere`.

**Manual values override provider values.** If you know the time the doors opened, enter it with `actualArrivalBasis: "doors_open"`.

### The rules applied (summary)

- **Scope (Art. 3(1), 3(1A)).** UK261 covers flights departing the UK on any airline; flights into the UK from abroad on a UK or EU (Community) **operating** carrier; and flights into the EU on a UK carrier. EU261 covers flights departing the EU, EEA or Switzerland on any airline, and flights into the EU on an EU, EEA or Swiss carrier. A journey booked as a single unit is judged as a whole from its first departure point (Art. 3(1A); *Wegener*; *Chelluri*). Arrival-based cover doesn't apply if you already got benefits in the departure country. Flights before 1 Jan 2021 are treated as EU261 throughout. The marketing carrier and the ticket seller are irrelevant.
- **Amounts (Art. 7).** UK: £220 (≤1,500 km), £350 (1,500–3,500 km), £520 (over 3,500 km). EU: €250, €400 and €600, where intra-EU flights over 1,500 km get €400. The pound figures are statutory amounts, not conversions. Distances are great-circle.
- **Delay (Art. 6(3), Sturgeon, Folkerts).** 3 hours or more at the final destination. Arrival means the time passengers may leave the aircraft (Art. 2(n); *Germanwings* C-452/13). For runway-time or estimated data near the threshold, the answer is `maybe`. A 3–4h delay on a non-intra-EU flight over 3,500 km gets 50% (£260 or €300).
- **Cancellation (Art. 5(1)(c)).** No compensation if you were told 14 or more days ahead. With 7–13 days' notice, none if re-routing left ≤2h earlier **and** arrived <4h later. With under 7 days' notice, none if re-routing left ≤1h earlier **and** arrived <2h later. The airline may cut the payment by 50% if the re-routing arrived within 2h, 3h or 4h (by distance band).
- **Denied boarding (Art. 4).** Compensation is due unless you volunteered or there were reasonable grounds (such as travel documents). The extraordinary-circumstances defence doesn't apply (C-22/11).
- **Extraordinary circumstances (Art. 5(3), 6(4), 2(o)).** We explain how your airline's *stated* reason has been treated by courts. Weather, ATC, security and third-party strikes come back `maybe` / `unlikely`. Ordinary technical faults (*Huzar*, *Wallentin-Hermann*, *van der Lans*), own-staff strikes and crew shortages are generally *not* extraordinary, so those stay `yes` / `likely`. The airline carries the burden of proof; we cannot check the facts.
- **Time limits.** Court claims: 6 years in England & Wales (Limitation Act 1980 s.9; *Dawson*), 5 years in Scotland (estimate), 6 years in Northern Ireland. ADR bodies and PACT only act after the airline's final response or 8 weeks of silence.
- **EU reform.** Regulation (EU) 2026/2202 was published on 2 Oct 2026 and most of it applies from 23 Oct 2027. For EU261 flights on or after that date, the result is `maybe` with a warning: the engine applies the current rules, and the amounts are unchanged.

### UK routing: ADR, PACT and court

| Operating airline (examples) | Route after the airline's final response or 8 weeks | Binding? |
|---|---|---|
| easyJet, Ryanair group, Wizz Air, Virgin Atlantic, TUI Airways, Air France, KLM, Delta, Turkish, TAP, airBaltic… | **AviationADR** (CDRL), CAA-approved, free | Member airlines are bound once you accept |
| British Airways, BA CityFlyer, BA Euroflyer, Cathay Pacific | **CEDR** aviation scheme, CAA-certified | Airline must comply within 20 working days of your acceptance |
| Jet2, Emirates, Lufthansa group\*, any airline not listed | **CAA PACT** (Passenger Advice and Complaints Team) | No — PACT gives an opinion and raises it with the airline |
| Last resort, all airlines | **Court**: Money Claim Online (England & Wales, fee £35–£115 for claims up to £3,000), Simple Procedure (Scotland, under £5,000), small claims (Northern Ireland, up to £5,000) | Yes |

Membership lists were read from the CAA ADR page and the bodies' sites on **24 Oct 2026**; they change, and where the two sources disagree (SAS) the output says so. \*The CAA page notes that the German body Schlichtung Reise & Verkehr may handle Lufthansa, Austrian, Brussels Airlines and SWISS complaints. Use `adrBody` to override.

### FAQ

**Is this telling me I am owed compensation?** No. It tells you which band the Regulation provides *if* its conditions are met, which conditions could be tested from your facts, and which could not. The `certainty` field and `assessment.unknowns` make the gap explicit.

**Do you scrape FlightAware, Flightradar24 or airline sites?** No. Flight data only comes from licensed APIs, through the key you supply. Without a key, you type the times in.

**Which provider should I use?** For occasional checks, AeroDataBox on RapidAPI or API.Market is the cheapest way to get past flights (≤ about a year back; this is the Flight Status (single day) endpoint, a TIER 2 call). FlightAware AeroAPI has the deepest history (back to 2011, depending on tier) and gate times. Aviationstack needs a paid plan for past dates and keeps about 3 months. The OAG adapter is experimental. Read your provider's licence: some tiers limit business use of the results.

**Is my key safe?** It's an Apify secret input. It's sent only to the provider you picked, never logged, and every record written to the dataset, the OUTPUT record or the claim pack is scrubbed for it (raw and URL-encoded). Provider error bodies are never echoed. The Aviationstack key travels in the query string, as that API requires, and we never log that URL.

**Why "maybe"?** Something material is unknown: the carrier's licence, the notice period, re-routing times, an estimated arrival, or an airline reason that courts often accept. The `reasons` field says exactly what's missing.

**Can I claim under both UK261 and EU261?** No, you can claim under only one. The tool names the primary regime (normally the departure country's) and shows the other as an alternative.

**Does it file claims?** No. It gives you an estimate, links and a letter template. Claiming directly with the airline is free; claims firms usually keep 25–35% plus VAT.

### Limits

- Flight data is only as good as your provider's feed. Small airports may have schedule-only data, and delays may be measured at touchdown rather than door opening. Diversions need you to supply the delay at the final destination.
- The carrier-licence table covers 108 common carriers as of 24 Oct 2026. For others, set `carrierLicence`.
- ADR membership lists are a snapshot (24 Oct 2026). Airlines not in the lists are routed to PACT with an "unverified" note.
- Special territories (Crown Dependencies, Gibraltar, Faroe Islands, Greenland and overseas territories) are treated as outside the UK and EU, and flagged.
- Not covered: downgrading (Art. 10), package-travel claims, other passenger-rights regimes (Canada APPR, US DOT, Türkiye SHY, Brazil), and national variations in how EU courts apply the rules.
- EU limitation periods are indicative only. Scotland's 5-year period has not been verified against Scottish case law (`confidence: "indicative-verify"`).
- Inbound single bookings where a UK/EU carrier operates the first leg but a non-UK/EU carrier operates the delayed leg (České aerolinie, C-502/18) are not modelled: the engine uses the delayed leg's operating carrier, so coverage may be understated (`no` or `maybe`). Check such cases yourself.

### Compliance and sources

- **Law:** [UK261 text](https://www.legislation.gov.uk/eur/2004/261/contents), [SI 2019/278](https://www.legislation.gov.uk/uksi/2019/278/contents) and [SI 2023/1370](https://www.legislation.gov.uk/uksi/2023/1370/made) (Open Government Licence v3.0); [EU261 on EUR-Lex](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32004R0261); CJEU judgments on [curia.europa.eu](https://curia.europa.eu); UK cases on [caselaw.nationalarchives.gov.uk](https://caselaw.nationalarchives.gov.uk). Rules re-verified against these sources on **24 Oct 2026**.
- **Guidance:** [UK CAA delays](https://www.caa.co.uk/air-passengers/travel-problems-and-rights/flight-delays-and-cancellations/delays/), [CAA ADR](https://www.caa.co.uk/air-passengers/travel-problems-and-rights/travel-complaints/alternative-dispute-resolution/), [CAA PACT](https://www.caa.co.uk/passengers-and-public/resolving-travel-problems/how-the-caa-can-help/how-the-caa-can-help/), [AviationADR](https://www.aviationadr.org.uk/), [CEDR](https://www.cedr-assist.com/consumer/aviation/overview/), [GOV.UK court claims](https://www.gov.uk/make-court-claim-for-money), [Your Europe](https://europa.eu/youreurope/citizens/travel/passenger-rights/air/index_en.htm).
- **Airport coordinates:** [OurAirports](https://ourairports.com/data/), public domain, snapshot taken 11 Oct 2026.
- **Flight data:** your own provider account under that provider's terms. You are the licensee; the Actor only displays the results to you and does not store them. AeroDataBox permits commercial use only through paid channels, requires attribution on free/trial channels, forbids sublicensing or redistributing contents and caps caching (7 days unless the plan says otherwise). FlightAware AeroAPI's Personal tier is for personal/academic use only; Standard permits business and B2C use; B2B use needs Premium. Aviationstack's Free plan is non-commercial. OAG permits internal business and commercial use per plan but forbids reselling or redistributing raw data. Read the licence that applies to **your** tier before using results for third parties.
- **Personal data:** none collected. Inputs are flight facts. `reference` is never stored (rows are labelled `claim-<n>`), and a claim whose `reference` looks like a booking reference, passport number or e-mail address is refused. Unknown fields (e.g. a passenger name or ticket number) are ignored and never stored. Don't put passenger names in any field if you share datasets (UK GDPR).
- Not affiliated with any airline, regulator, ADR body or flight-data provider.

# Changelog

This Actor's version history is a separate document: https://apify.com/siteverdict/siteverdict-flight-compensation/changelog.md

# Actor input Schema

## `claims` (type: `array`):

One object per flight. WITH a provider key: give flightNumber + date (local departure date, YYYY-MM-DD) and the Actor looks up scheduled/actual times. WITHOUT a key (provider = none): give departureAirport + arrivalAirport (IATA e.g. LHR or ICAO e.g. EGLL), operatingCarrier (e.g. BA, BAW, EZY) and either arrivalDelayMinutes or scheduledArrival + actualArrival (local time at the arrival airport, e.g. 2026-09-14T13:05). Optional: disruption (auto|delay|cancellation|denied_boarding|diversion), cancellationNoticeDays, rerouteOffered, rerouteDepartedMinutesEarly, rerouteArrivalDelayMinutes, deniedBoardingVoluntary, deniedBoardingReason (overbooking|operational|health|safety|security|travel_documents), airlineReason (weather|atc_restriction|technical_fault|strike_own_staff|strike_third_party|crew_shortage|bird_strike|...), journeyOrigin + finalDestination + finalArrivalDelayMinutes (single booking with connections), carrierLicence (UK|EU|EEA_CH|OTHER), passengers, jurisdiction (england-wales|scotland|northern-ireland|eu-de|eu-fr|eu-ie|eu-es|eu-other), checkedInOnTime, freeOrNonPublicFare, alreadyCompensatedElsewhere, reference (optional and never stored: every output row is labelled claim-<n>, the claim's position in this list; a claim whose reference looks like a booking reference, passport number or e-mail address is refused). 1.1.0: singleBooking (true = one booking, false = self-transfer), marketingCarrier, arrivalTimeZone (IANA, e.g. Europe/London), actualArrivalBasis (doors_open|gate|runway), adrBody (aviationadr|cedr|pact). See the README for every field. Output is an ESTIMATE of the statutory band if conditions are met — not a determination of entitlement.

## `provider` (type: `string`):

Licensed flight-status API to look flights up with YOUR key. 'none' = manual times only (no key needed). 'sample' = built-in synthetic demo flights (BA9901 2026-09-14, U29902 2026-09-20, FR9903 2026-09-21, LH9904 2026-09-22), free. We never scrape airline or flight-tracker websites.

## `apiKey` (type: `string`):

Your own key for the selected provider (RapidAPI key, API.Market key, AeroDataBox key, FlightAware x-apikey, Aviationstack access_key or OAG subscription key). Stored encrypted as an Apify secret, sent only to that provider, never logged or written to the output. You pay the provider directly under its own terms.

## `aerodataboxGateway` (type: `string`):

Where your AeroDataBox key comes from.

## `maxClaims` (type: `integer`):

Safety cap (hard limit 500). The run also stops when your maximum total charge is reached.

## `concurrency` (type: `integer`):

1 to 4. Keep low to respect the rate limit of your provider plan.

## `claimPack` (type: `boolean`):

Also write CLAIM-PACK.md (one letter template per claim to the operating airline, personal details left as \[brackets]) and CLAIMS.csv (one row per claim) to the key-value store. Included in the same event — no extra charge.

## Actor input object example

```json
{
  "claims": [
    {
      "departureAirport": "LGW",
      "arrivalAirport": "FAO",
      "operatingCarrier": "EZY",
      "date": "2026-09-14",
      "scheduledArrival": "2026-09-14T09:50",
      "actualArrival": "2026-09-14T13:15",
      "passengers": 2
    },
    {
      "departureAirport": "STN",
      "arrivalAirport": "BCN",
      "operatingCarrier": "RYR",
      "date": "2026-09-21",
      "cancellationNoticeDays": 3,
      "rerouteOffered": false
    }
  ],
  "provider": "none",
  "aerodataboxGateway": "rapidapi",
  "maxClaims": 100,
  "concurrency": 2,
  "claimPack": false
}
```

# Actor output Schema

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

No description

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

No description

## `files` (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 = {
    "claims": [
        {
            "departureAirport": "LGW",
            "arrivalAirport": "FAO",
            "operatingCarrier": "EZY",
            "date": "2026-09-14",
            "scheduledArrival": "2026-09-14T09:50",
            "actualArrival": "2026-09-14T13:15",
            "passengers": 2
        },
        {
            "departureAirport": "STN",
            "arrivalAirport": "BCN",
            "operatingCarrier": "RYR",
            "date": "2026-09-21",
            "cancellationNoticeDays": 3,
            "rerouteOffered": false
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("siteverdict/siteverdict-flight-compensation").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 = { "claims": [
        {
            "departureAirport": "LGW",
            "arrivalAirport": "FAO",
            "operatingCarrier": "EZY",
            "date": "2026-09-14",
            "scheduledArrival": "2026-09-14T09:50",
            "actualArrival": "2026-09-14T13:15",
            "passengers": 2,
        },
        {
            "departureAirport": "STN",
            "arrivalAirport": "BCN",
            "operatingCarrier": "RYR",
            "date": "2026-09-21",
            "cancellationNoticeDays": 3,
            "rerouteOffered": False,
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("siteverdict/siteverdict-flight-compensation").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 '{
  "claims": [
    {
      "departureAirport": "LGW",
      "arrivalAirport": "FAO",
      "operatingCarrier": "EZY",
      "date": "2026-09-14",
      "scheduledArrival": "2026-09-14T09:50",
      "actualArrival": "2026-09-14T13:15",
      "passengers": 2
    },
    {
      "departureAirport": "STN",
      "arrivalAirport": "BCN",
      "operatingCarrier": "RYR",
      "date": "2026-09-21",
      "cancellationNoticeDays": 3,
      "rerouteOffered": false
    }
  ]
}' |
apify call siteverdict/siteverdict-flight-compensation --silent --output-dataset

```

## MCP server setup

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

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/6xLpFJBZboTdvpo7T/builds/Zis9842IRcfK4jYrG/openapi.json
