Agoda Flight Scraper
Pricing
Pay per event
Agoda Flight Scraper
Search Agoda flight itineraries by route and date: fares, carriers, stops, baggage and cancellation policy. No login needed.
Search Agoda flight itineraries by route and date: fares, carriers, stops,
baggage and cancellation policy. Wraps the same reverse-engineered,
already-verified Agoda Android-app API (searchapi.agoda.com) used by the
Agoda All-in-One API
actor — this actor is a narrow, run-based spin-off focused only on flight
search. No account, login, app or device needed.
Why
Agoda's flight-search API needs no login and no request signing to read —
the only quirks are a public per-app client key (not a secret) and a hard
pace limit (bursts trigger empty-bodied HTTP 502s, handled internally by
throttling and retrying every request). Flight search itself is
asynchronous server-side: a search is submitted, then the same request body
is re-polled until the upstream marks it complete. This actor mirrors that
protocol exactly (up to 5 polls per page) and paginates it up to
maxResults itineraries.
- Search filters and sorts are honest. Server-side flight filters (stops, airlines, departure/arrival times, duration, price range) and most upstream sort options were live-tested and found unreliable/inert on Agoda's own API — they validate but don't change the result. This actor does not pretend otherwise: those are not exposed as input fields. There is no client-side sort either, since a spin-off actor should not promise anything beyond what it genuinely does. If you need honest filtering, filter or sort the dataset rows yourself after the run.
- Unresolvable routes don't hang or error. A bad/nonexistent IATA pair
never completes upstream polling. After the polling cap, the actor
surfaces whatever partial data exists with on the affected rows (and a run-log warning), rather than hanging or throwing.search_page_is_completed: false
- Prices can differ between identical calls (Agoda's own live pricing engine, not a bug here) — expect small variance run to run.
Input
| Field | Required | Description |
|---|---|---|
origin | yes | Origin airport/city, 3-letter IATA code (e.g. CGK). |
destination | yes | Destination airport/city, 3-letter IATA code (e.g. SIN). |
departDate | no | Departure date, YYYY-MM-DD. Defaults to 30 days after the run date. |
returnDate | no | Return date, YYYY-MM-DD. Adds a return slice (round trip) when given; omit for one-way. |
adults | no | Adult passengers, 1-9 (default 1). |
children | no | Child passengers, 0-8 (default 0). |
infants | no | Lap-infant passengers, 0-8 (default 0). |
cabin | no | One of Economy, PremiumEconomy, Business, First (default Economy). |
currency | no | 3-letter ISO currency code for prices (default USD). |
locale | no | Response language as an Agoda locale, e.g. th-th, ja-jp (default en-us). Not every locale is translated server-side; unsupported ones silently fall back to English. |
maxResults | no | Stop after this many itineraries, 1-500 (default 20). Paginates the upstream search (20 itineraries per page) until this many are collected, the route runs out of results, or the search stops completing. |
Output
One dataset row per flight itinerary: price breakdown, ticketing carrier,
trip duration, cancellation policy, and the full outbound/inbound slice
(segments, layovers, baggage allowance, cabin, booking class). Each row
also carries search_* fields (route, dates, cabin, currency, page, and
whether that page's upstream polling completed) so a row is self-describing
without needing the run's input.
Pricing
Pay-per-event (PPE), tiered by Apify plan (FREE/BRONZE/SILVER/GOLD/PLATINUM/
DIAMOND = 100/92/85/78/72/68% of the FREE price). Same per-itinerary price
as the flight-itinerary event on the Agoda All-in-One API, for pricing
consistency across this account's Agoda product line. See the Actor's
Pricing tab for the exact current price.
Known limitations
- Upstream result filters (stops, airlines, times, duration, price) and upstream sort are validated but not applied server-side by Agoda's own API — not exposed here, see "Why" above.
/flight/searchunbundledpolls up to 5 times per page; a route with no real itineraries returns partial/empty results withsearch_page_is_completed: falserather than hanging.- 20 itineraries per upstream page;
maxResultsabove 20 means multiple upstream requests (and multiple poll cycles), so large values take proportionally longer. - This actor only searches; it does not book or hold fares.
Getting started
npm installnpm run start:dev