True Cost of Flying — Baggage Fee Scraper
Pricing
from $3.00 / 1,000 fare with baggage costs founds
True Cost of Flying — Baggage Fee Scraper
Find out what a Kiwi.com fare really costs once you add a bag. Every result comes back with its included allowance, the price of each extra cabin and checked bag, the weight and size limits, and a combined fare-plus-bags total ranked cheapest first. 37 currencies, no account needed.
The cheapest fare on the screen is very often not the cheapest trip. This actor searches Kiwi.com for a route and a date, and returns every fare with its baggage terms attached: how many cabin and checked bags the fare already includes, what each extra bag costs, how heavy and how large that bag is allowed to be, and the combined fare-plus-bags total — ranked cheapest first on the total rather than on the sticker price. On a real London → Dubai search, the €505 fare came third once a bag was added and a €523 fare came first, because the bags cost €217 on one and €144 on the other. That is the answer this actor exists to give, and it is normally buried several screens into an airline's own booking flow.
What you can do with it
- Answer "which fare is actually cheapest with a bag." Every result carries a combined total and a rank, so the reordering is done for you.
- Build a baggage-fee reference for a route, an airline or a whole market. Real prices, real weight limits and real size limits, per fare, not a policy page you have to interpret.
- Compare fare products of the same flight. The same departure is usually sold at more than one price with identical baggage terms; every one of them is returned and the cheapest is marked.
- Show travellers a true price in your own product. Fare, bag cost and total in the currency of the market you are selling into.
- Model ancillary revenue. How much of a trip's price is the bag, by carrier, by route, by cabin, over time.
- Flag trips where the bag is handled twice. Self-connected itineraries are marked, along with whether the bag has to be collected and re-checked on the way.
What you get
One row per fare product. Real example, abridged (the long identifier and the booking link are shortened here):
{"source": "kiwi","market": "US","currency": "USD","requestedCurrency": "USD","collectedAt": "2026-08-16T12:00:00.000Z","searchId": "JFK-LAX-2026-09-15","searchOrigin": "JFK","searchDestination": "LAX","requestedDepartureDate": "2026-09-15","tripType": "oneway","cabinClass": "ECONOMY","fareProductCode": "KIWI-BASIC","isCheapestFareOption": true,"fareOptionCount": 2,"basePrice": 176,"marketingCarrierName": "JetBlue Airways","flightNumbers": ["B6123"],"departureLocal": "2026-09-15T06:00:00","arrivalLocal": "2026-09-15T08:59:00","stopCount": 0,"durationMin": 359,"baggageDataPublished": true,"includedPersonalItem": 1,"includedHandBags": 1,"includedCheckedBags": 0,"handBagPrice1": 0,"checkedBagPrice1": 52.5,"checkedBagPrice2": 127.5,"checkedBagWeight": 22,"checkedBagWeightUnit": "KG","checkedBagDimensionsSum": 157,"handBagDimensions": "55 x 22 x 35 CM","checkedBagTiers": [{ "bags": 1, "price": 52.5, "currency": "USD", "includedInFare": 0, "weight": 22, "weightUnit": "KG", "dimensionsSum": 157, "dimensionsUnit": "CM" },{ "bags": 2, "price": 127.5, "currency": "USD", "includedInFare": 0, "weight": 22, "weightUnit": "KG", "dimensionsSum": 157, "dimensionsUnit": "CM" }],"handBagsPriced": 0,"checkedBagsPriced": 1,"checkedBagFee": 52.5,"baggageFeeTotal": 52.5,"allInPrice": 228.5,"rankByAllInPrice": 1,"isSelfTransfer": false,"baggageRecheckRequired": false,"bookingUrl": "https://www.kiwi.com/en/booking/?…","isEstimated": false}
Input reference
| Field | Type | Default | What it does |
|---|---|---|---|
origins | array | — | Where the trip starts: airport codes (JFK), city-wide codes (NYC), or names (London Heathrow). Several are allowed. |
destinations | array | — | Where the trip ends, same formats. Several are allowed. |
tripType | string | oneway | oneway or return. |
departureDates | array | — | Outbound dates, YYYY-MM-DD. Each date is a separate search. |
returnDates | array | — | Return dates for a return trip. Each is paired with each departure date. |
bagsToAdd | string | checked | Which bags to price on top of every fare: none, hand, checked or both. |
handBagsToAdd | integer | — | Optional exact number of cabin bags to price (0–2), overriding the choice above. |
checkedBagsToAdd | integer | — | Optional exact number of checked bags to price (0–3), overriding the choice above. |
cabinClass | string | ECONOMY | ECONOMY, PREMIUM_ECONOMY, BUSINESS or FIRST_CLASS. Allowances differ sharply by cabin. |
adults | integer | 1 | Adult travellers (1–9). |
children | integer | 0 | Children aged 2–11 in their own seat. |
infants | integer | 0 | Lap infants; cannot exceed the number of adults. |
currency | string | USD | One of 37 currencies. Every row also records the currency it was served in. |
market | string | US | The market the search is prepared for; recorded on every row. |
maxResultsPerSearch | integer | 30 | Flights to keep per route and date, up to 1,000. Each can produce more than one row. |
fareOptions | string | all | Keep every fare product a flight is sold as, or only the cheapest. |
maxStops | integer | — | Optional ceiling on stops (0–3). Empty means no limit. |
includeAllInPrice | boolean | true | Work out the fare-plus-bags total and rank each search on it. |
onlyFaresWithBaggagePrices | boolean | false | Drop fares whose baggage terms are not published, instead of returning them with empty columns. |
excludeSelfTransferFares | boolean | false | Leave out trips stitched together from separate tickets. |
Output fields
| Field | Type | What it is |
|---|---|---|
basePrice | number | The fare on its own, before any bag is added. |
currency | string | null | The currency this row was actually served in. null when the fare arrived without one. |
requestedCurrency / currencyMismatch | string / boolean | null | What you asked for, and whether it differs from what arrived. null means the row's own currency is missing, so the comparison cannot be made — never read that as "no mismatch". |
currencyMissing | boolean | true when the amounts on this row arrived with no currency code at all. They are still exactly what the source served, but nothing labels them, so they are never treated as the currency you asked for. |
allInPrice | number | null | Fare plus the bags you asked to price. null when the fare publishes no price for that many bags. |
rankByAllInPrice | number | null | Position within its own search, cheapest total first. Ties share a rank; an unknown total is left unranked. |
baggageFeeTotal / handBagFee / checkedBagFee | number | null | What the bags you asked for cost on this fare. |
includedHandBags / includedCheckedBags / includedPersonalItem | number | null | What the fare already includes. |
handBagPrice1 / handBagPrice2 | number | null | Total price for that many cabin bags. |
checkedBagPrice1 / checkedBagPrice2 / checkedBagPrice3 | number | null | Total price for that many checked bags. |
handBagTiers / checkedBagTiers / personalItemTiers | array | Every published tier: how many bags, the price, whether it is already in the fare, weight, each side and the sum of the three sides, with units. |
handBagDimensions | string | null | Cabin bag size as length x width x height with its unit. |
checkedBagWeight / checkedBagWeightUnit | number / string | Weight allowance for a checked bag and the unit it is stated in. |
checkedBagDimensionsSum / checkedBagDimensionsUnit | number / string | The published sum of the three sides, and its unit. |
baggageDataPublished | boolean | false means the source published no baggage terms for this fare — not that no bags are allowed. |
checkedBagsAvailable | boolean | null | Whether a checked bag can be bought on this fare at all. |
fareProductCode / fareProductName | string | Which fare product this row is. The same flight is often sold as several. |
isCheapestFareOption / fareOptionCount | boolean / number | Whether this is the cheapest product for that flight, and how many exist. |
marketingCarrier / marketingCarrierName / carrierCodes / carrierNames | string / array | The airlines on the trip. |
flightNumbers | array | Real flight numbers, in order. |
originCode / originName / destinationCode / destinationName | string | Where it actually leaves from and arrives at. |
departureLocal / arrivalLocal / returnDepartureLocal | string | Local times. |
stopCount / segmentCount | number | null | Shape of the trip. Both are null, never 0, when the flights behind the fare did not arrive — a trip with no flights in it does not exist, and 0 would read as "non-stop". |
routeDataPublished | boolean | false when the fare arrived without its flights. Such a row still carries a real price, but its stops, flight numbers, airports and times are unknown rather than empty. |
durationMin | number | Length of the trip. |
outboundDurationMin / inboundDurationMin | number | null | Each direction of a return trip. |
isSelfTransfer / pnrCount | boolean / number | Whether the trip is stitched from separate tickets, and how many. |
baggageRecheckRequired | boolean | null | Whether the bag has to be collected and re-checked on the way. false only on a trip published as non-stop; null when there is a connection whose terms were not published, or when the flights did not arrive at all. |
bookingUrl | string | A direct link to that exact fare on Kiwi.com. |
searchId / searchOrigin / searchDestination / requestedDepartureDate / requestedReturnDate | string | Which search produced the row. |
market / collectedAt | string | The market chosen, and when the row was collected. |
isEstimated | boolean | Always false. Every number on the row was published by the source. |
Pricing
You pay per result, not per run.
| What you pay for | Price |
|---|---|
| Fare with baggage costs found | $3.00 per 1,000 rows |
| All-in price worked out | $0.80 per 1,000 rows |
The first is charged for every row delivered. The second is charged only when a combined fare-plus-bags total was actually produced — a fare that publishes no price for the bags you asked about is delivered with an empty total and costs you nothing extra. Choose no bags and the total is simply the fare itself, so the second charge is not made at all. Switch the all-in price off and only the first charge applies.
Worked example. One route on one date, keeping 30 flights, most of them sold as two fare products, gives roughly 60 rows: 60 × $0.0030 = $0.18, plus $0.0008 for each row that got a total — say 55 of them, $0.044. About 22 cents for that search. Twenty routes across ten dates in one run, at the same shape, is around $44.
Limits & what this actor cannot do
- Fares and bag prices are a snapshot. Airline pricing changes continuously, and a fare or a fee seen now may be different minutes later.
- It reports what the source publishes to the public. It does not hold seats, does not book, and cannot guarantee a fare or a bag price is still available when you go to buy.
- Nothing is estimated. When a fare publishes no price for the number of bags you asked about, the total comes back empty with the reason attached — it is never filled in from another fare, another tier or another date. Second and third checked bags in particular are often not published at all.
baggageDataPublished: falsemeans unknown, not zero. Some fares arrive with no baggage terms; those rows carry empty baggage columns rather than a guess.- Bag prices are what the seller charges for that fare. An airline may price the same bag differently at the airport, at check-in, or through its own site, and oversized or overweight bags are charged separately.
- Weight and size limits are published in the units the source states them in. They are passed through as given, with the unit on every value, and are never converted.
- Results differ by market and currency. Fares, fare products and bag prices are not the same in every market; each row records the market chosen and the currency actually served.
- The source publishes a limited number of results for any one search, so a very broad search returns what it makes available rather than an unlimited list.
- Routes and schedules are seasonal. A route with no flights on the dates you searched is reported as having none, and that is separated in the run summary from a search that could not be completed.
- A search the source refuses to complete is reported as a failed search, never as "no fares found". That includes an answer that contradicts itself — no fares delivered while the same answer states how many were available — which is counted as a search that could not be completed rather than as a route with no flights. If every search in a run fails, the run itself fails rather than finishing green with an empty table.
- A fare that arrives incomplete says so on the row. One that arrives without its flights carries
routeDataPublished: falseand an unknown stop count instead of reading as a non-stop; one that arrives with no currency code carriescurrencyMissing: trueand an unknown mismatch instead of being treated as the currency you asked for. - Speed depends on the size of the job and on the source's own response times; no fixed throughput 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 an account on Kiwi.com? No. Nothing is signed in to and nothing is bought.
Does it need my login or password? No. There is nothing to configure beyond the search itself.
Are these fares and bag prices bookable? They are what the source published at the moment of collection, and every row carries a direct link to that exact fare. Prices move, so treat a row as a snapshot rather than a guarantee.
Why does the same flight appear more than once?
Because it is genuinely sold as more than one fare product, at different prices, usually with the same baggage terms. Both are returned, and isCheapestFareOption marks the cheaper one. Set fareOptions to cheapest to keep only that one.
Why is allInPrice sometimes empty?
Because that fare publishes no price for the number of bags you asked about. Filling it in would mean inventing a fee, so the field is left empty and allInPriceUnavailableReason says why.
Why does the cheapest fare sometimes rank third?
That is the point of the actor. A cheaper fare with an expensive bag can cost more than a dearer fare that includes one. rankByAllInPrice orders each search on the total, not on the sticker price.
Can I schedule it? Yes. Run it on a schedule to build your own history of fares and baggage prices for the routes you care about.


