# Agoda Flights Scraper — Fares, OTA Offers & Price API (`sian.agency/agoda-flight-scraper`) Actor

Scrape Agoda Flights fares by route and date. One-way and round-trip itineraries with airlines, flight numbers, segments, durations, stops and 14+ OTA booking offers per flight (provider prices, booking URLs, baggage rules). Flight price tracker and airfare data API for fare monitoring.

- **URL**: https://apify.com/sian.agency/agoda-flight-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Travel, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 flight itinerary extracteds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Agoda Flights Scraper — Fares, OTA Offers & Flight Price API 🚀

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Booking.com Scraper](https://img.shields.io/badge/Store-Booking.com%20Scraper-003580)](https://apify.com/sian.agency/booking-com-scraper?fpr=sian) [![Trip.com Scraper](https://img.shields.io/badge/Store-Trip.com%20Scraper-287DFA)](https://apify.com/sian.agency/trip-com-scraper?fpr=sian) [![Airbnb Property Scraper](https://img.shields.io/badge/Store-Airbnb%20Property%20Scraper-FF5A5F)](https://apify.com/sian.agency/airbnb-property-scraper?fpr=sian)

#### 🎉 Every itinerary ships with its FULL OTA booking-offer ladder — 14+ provider prices, booking URLs & baggage rules per flight
##### Built for fare trackers, travel-deal aggregators, and OTA price-monitoring teams

---

### 📋 Overview

**Turn any route + date into structured flight-fare data in minutes** — one-way and round-trip itineraries with airlines, flight numbers, segments, stops, durations, and the complete list of OTA booking offers competing on each flight.

**Why professionals choose us:**
- ✅ **14+ booking offers per itinerary**: see every OTA's price, booking URL, booking country and baggage rules on the same flight — not just one headline fare
- ⚡ **Hundreds of itineraries per search**: 200+ one-way and 1,500+ round-trip combinations on busy routes, paginated automatically
- 🎯 **Structured to the segment**: airline code + name, flight number, aircraft, airport codes, per-leg durations and stops — analysis-ready
- 💰 **Pay per result**: cheap per-row pricing; only successful itinerary rows are charged
- 💎 **Itinerary re-pricing mode**: feed back any row's shareable URL and get a live, re-priced offer ladder — the core of a fare-alert loop
- ✨ **NEW**: best / cheapest / cheapest-direct flags plus sort by best, price, or duration

---

### ✨ Features

- ✈️ **One-way & round-trip search** — 3-letter IATA pair + date (+ optional return date)
- 🏷 **Full OTA offer ladder** — every booking option with provider, price, currency, booking URL and baggage allowances
- 🥇 **Best-offer headline** — the top offer per itinerary, plus best/cheapest/cheapest-direct flags
- 🛫 **Segment-level detail** — airline, flight number, aircraft, airports, times, durations, stops
- 👨‍👩‍👧 **Passenger mix** — adults, children, infants; cabin class selection
- 🚀 **Bulk routes** — search many routes in one run (PAID)
- 🎫 **Details mode** — re-fetch specific itineraries by shareable URL or search/result reference
- 📊 **Fare KPIs + HTML report** — cheapest fare, price & duration distributions, nonstop count, airline and provider breakdowns
- 🔁 **Automatic dedup** — itineraries deduplicated across pages and routes

---

### 🎬 Quick Start

Pick a route, pick a date, press Start. The actor searches, waits for fares to fill, paginates, and pushes one clean row per itinerary.

```bash
curl -X POST "https://api.apify.com/v2/acts/sian.agency~agoda-flight-scraper/runs?token=YOUR_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"origin": "JFK", "destination": "LAX", "date": "2026-08-10"}'
````

***

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Enter a route

Set the origin and destination IATA codes (e.g. JFK → LAX) and a departure date — or leave the date empty to search 30 days ahead.

#### Step 2: Run the actor

Fares fill within seconds; the actor collects itineraries page by page up to your `maxResults`.

#### Step 3: Export your data

Download JSON, CSV, or Excel from the dataset — every row carries the full booking-offer ladder.

**That's it! In under 2 minutes, you'll have:**

- Priced itineraries with airlines, segments and durations
- Every OTA's competing offer on each flight
- A fare report with cheapest / median prices and provider breakdowns

***

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| searchMode | string | No | `search` (default) or `details` |
| origin | string | search | 3-letter IATA departure airport (e.g. `JFK`) |
| destination | string | search | 3-letter IATA arrival airport (e.g. `LAX`) |
| date | string | No | Departure date `YYYY-MM-DD` (empty = 30 days from today) |
| returnDate | string | No | Return date — makes the search round-trip |
| adults / children / infants | integer | No | Passenger mix (defaults 1 / 0 / 0) |
| cabin | string | No | Economy (default), Premium\_Economy, Business, First |
| sortOrder | string | No | `best` (default), `price`, `duration` |
| routes | array | No | Bulk route objects `{origin, destination, date, returnDate}` (PAID: unlimited) |
| maxResults | integer | No | Max itineraries per route (default 30) |
| flightUrls | array | details | Shareable flight URLs from a previous search |
| flightRefs | array | details | `{searchId, resultId}` pairs from a previous search |

**Example — round-trip search:**

```json
{
  "origin": "BKK",
  "destination": "SIN",
  "date": "2026-08-10",
  "returnDate": "2026-08-17",
  "adults": 2,
  "sortOrder": "price"
}
```

**Example — re-price saved itineraries:**

```json
{
  "searchMode": "details",
  "flightUrls": [
    "https://flights.agoda.com/flights/JFK-LAX/2026-08-10/details/c0b8fae339ab097af3a2c41dad49c563?searchId=0HDiFhsesx"
  ]
}
```

***

### 📤 Output

Results are saved to the Apify dataset with **20+ fields** including:

| Field | Type | Description |
|-------|------|-------------|
| route | string | IATA pair, e.g. `JFK-LAX` |
| departureDate / returnDate | string | Search dates |
| bestOffer | object | Headline offer: provider, price, currency, booking URL, baggage |
| bookingOptions | array | The full OTA offer ladder (14+ providers on busy routes) |
| totalBookingOptions | number | Offer count for this itinerary |
| airlines | array | Unique operating airlines |
| legs | array | Per-direction legs with segment-level airline / flight number / aircraft / airports / times |
| totalStops / totalDurationMinutes | number | Trip totals |
| isBest / isCheapest / isCheapestDirect | boolean | Ranking flags |
| shareableUrl | string | Feed back into details mode to re-price |
| resultId / searchId | string | Reference pair for details mode |

**Example row (trimmed):**

```json
{
  "_type": "flightItinerary",
  "route": "JFK-LAX",
  "departureDate": "2026-08-10",
  "tripType": "oneway",
  "isBest": true,
  "bestOffer": { "provider": "SUPERAIR", "price": 252, "currency": "USD", "bookingUrl": "https://flights.agoda.com/book/flight?..." },
  "totalBookingOptions": 14,
  "airlines": ["JetBlue"],
  "totalStops": 0,
  "totalDurationMinutes": 348,
  "legs": [{ "legIndex": 0, "stops": 0, "segments": [{ "airlineCode": "B6", "flightNumber": "123", "originCode": "JFK", "destinationCode": "LAX", "aircraft": "Airbus A318/A319/A320/A321" }] }],
  "shareableUrl": "https://flights.agoda.com/flights/JFK-LAX/2026-08-10/details/..."
}
```

***

### 💼 Use Cases & Examples

#### 1. Fare tracking & price alerts

**Deal hunters and travel apps poll routes daily and diff the cheapest fares.**

**Input:** A route + date on a schedule
**Output:** Cheapest / best itineraries with prices per OTA
**Use:** Price-drop alerts, booking-timing models, historical fare curves

#### 2. OTA price monitoring

**Revenue and pricing teams see exactly which OTA undercuts whom on the same flight.**

**Input:** Competitive routes
**Output:** 14+ competing offers per itinerary with provider names and prices
**Use:** Rate-parity monitoring, commission and markup analysis

#### 3. Travel-deal aggregation

**Newsletter and deal-site operators harvest cheap fares at scale.**

**Input:** Bulk `routes` array across origins
**Output:** Hundreds of priced itineraries per run with booking links
**Use:** Deal feeds, fare-of-the-day content, affiliate booking funnels

#### 4. Airline & route analysis

**Analysts study schedules, connections, aircraft and durations.**

**Input:** Route + date
**Output:** Segment-level airline / flight number / aircraft / stops data
**Use:** Market-share studies, connectivity benchmarks, schedule monitoring

#### 5. Itinerary re-pricing pipelines

**Fare-alert products re-check saved flights before notifying users.**

**Input:** `details` mode with saved shareable URLs
**Output:** Live re-priced offer ladders per itinerary
**Use:** "Your flight dropped $40" notifications with fresh booking links

***

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/agoda-flight-scraper').call({
  origin: 'JFK',
  destination: 'LAX',
  date: '2026-08-10'
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/agoda-flight-scraper').call(
    run_input={'origin': 'JFK', 'destination': 'LAX', 'date': '2026-08-10'}
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~agoda-flight-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"origin": "BKK", "destination": "SIN", "date": "2026-08-10", "returnDate": "2026-08-17"}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: Daily schedule per watched route
2. **HTTP Request**: Call the actor API
3. **Process**: Compare cheapest fare vs yesterday's
4. **Action**: Send the price-drop alert with the booking link

***

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **1 route, 25 itineraries** per run — full feature access, same data quality
- No credit card required
- Perfect for testing a route before scaling

#### PAID Tier (Production Ready)

- **Unlimited** routes and itineraries per run
- Bulk `routes` arrays for multi-route sweeps
- Pay-per-result: only successful itinerary rows are charged

💰 **Best value in the flight category** — every row already includes the multi-OTA offer ladder other tools sell as a separate premium event.

🔗 [View current pricing](https://apify.com/sian.agency/agoda-flight-scraper?fpr=sian)

***

### ❓ Frequently Asked Questions

**Q: How many itineraries can I get per route?**
A: Busy routes return 200+ one-way and 1,500+ round-trip itineraries. Set `maxResults` to control how many you collect (30 per page).

**Q: Why does the run wait a few seconds before rows appear?**
A: Fares fill asynchronously at the source. The actor polls automatically (up to ~90 s) until results arrive — you never get an empty first page.

**Q: Can I search premium cabins?**
A: Yes — Economy is the most reliable. Premium cabins depend on route availability and may return no results on some routes.

**Q: How do I re-check a fare later?**
A: Save the row's `shareableUrl` (or `searchId` + `resultId`) and run `details` mode — you get a live re-priced itinerary with the full offer ladder.

**Q: What output formats are available?**
A: JSON, CSV, Excel — export directly from the Apify dataset.

**Q: Is this legal?**
A: Yes — we only extract publicly available fare data. See the [legal section](#%EF%B8%8F-is-it-legal-to-scrape-data) below.

**Q: How long does a run take?**
A: A single route typically completes in 30–90 seconds including the fare-fill wait; bulk runs scale linearly per route.

***

### 🐛 Troubleshooting

**Search returns 0 itineraries**

- Check the IATA codes are real airports (3 letters, e.g. JFK, not "New York")
- Make sure the date is in the future
- Very thin routes may genuinely have no bookable fares for that date

**Details mode says the reference expired**

- Search sessions age out; re-run a search on the same route to mint fresh `searchId`/`resultId` values

**Premium cabin returns an error**

- Retry with `cabin: "Economy"` — premium-cabin inventory is not available on all routes

**Fewer rows than maxResults**

- The route only has that many distinct itineraries; check the run report's "Total Found Upstream"

***

### ⚠️ Trademark Disclaimer

Agoda is a registered trademark of Agoda Company Pte. Ltd. This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Agoda. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

***

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

***

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- For issues or questions, open an issue in the actor's repository
- Check [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian) for more automation tools
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

# Actor input Schema

## `searchMode` (type: `string`):

What to fetch.

• **search** — one-way or round-trip fare search by route + date (paginated, 30 itineraries/page)
• **details** — re-fetch specific itineraries by shareable flight URL or searchId + resultId (live re-priced booking offers)

## `origin` (type: `string`):

3-letter IATA code of the departure airport. Examples: **JFK** (New York), **BKK** (Bangkok), **SIN** (Singapore), **LHR** (London Heathrow).

## `destination` (type: `string`):

3-letter IATA code of the arrival airport. Examples: **LAX** (Los Angeles), **SIN** (Singapore), **DXB** (Dubai).

## `date` (type: `string`):

Departure date in **YYYY-MM-DD** format. Must be in the future.

💡 **TIP:** Leave empty to automatically search 30 days from today — handy for scheduled fare-tracking runs.

## `returnDate` (type: `string`):

Return date in **YYYY-MM-DD** format. When set, the search becomes **round-trip** and every itinerary carries both legs. Leave empty for one-way.

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

Adult passengers (12+). Default: 1.

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

Child passengers (ages 2–11). Default: 0.

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

Infant passengers (under 2). Default: 0.

## `cabin` (type: `string`):

Cabin class for the search. **Economy** is the most reliable; premium cabins depend on availability for the route and may return no results.

## `sortOrder` (type: `string`):

How upstream ranks itineraries.

• **best** — balance of price + duration + stops
• **price** — cheapest first
• **duration** — shortest first

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

🚀 **BULK PROCESSING:** Search many routes in one run. Each object needs `origin` and `destination`; `date` and `returnDate` are optional (empty date = 30 days from today).

```json
[
  { "origin": "JFK", "destination": "LAX", "date": "2026-08-10" },
  { "origin": "BKK", "destination": "SIN", "date": "2026-08-10", "returnDate": "2026-08-17" }
]
```

📊 **TIER-BASED LIMITS:**

- **FREE users:** 1 route per run
- **PAID users:** Unlimited routes

💡 When provided, this overrides the single origin/destination fields above.

## `maxResults` (type: `integer`):

Maximum itineraries to collect per route (30 per page upstream). FREE tier is capped at 25 itineraries per run.

## `flightUrls` (type: `array`):

🎫 **DETAILS MODE:** Shareable Agoda Flights URLs from a previous search run (every search row includes one in `shareableUrl`). Each URL is re-fetched live with its full booking-offer ladder.

Format: `https://flights.agoda.com/flights/JFK-LAX/2026-08-10/details/<resultId>?searchId=<searchId>`

📊 **TIER-BASED LIMITS:**

- **FREE users:** 1 itinerary per run
- **PAID users:** Unlimited

## `flightRefs` (type: `array`):

🎫 **DETAILS MODE (alternative input):** Explicit references from a previous search — each object needs the search row's `searchId` and `resultId`.

```json
[
  { "searchId": "0HDiFhsesx", "resultId": "c0b8fae339ab097af3a2c41dad49c563" }
]
```

## Actor input object example

```json
{
  "searchMode": "search",
  "origin": "JFK",
  "destination": "LAX",
  "date": "2026-08-10",
  "returnDate": "2026-08-17",
  "adults": 1,
  "children": 0,
  "infants": 0,
  "cabin": "Economy",
  "sortOrder": "best",
  "maxResults": 30
}
```

# Actor output Schema

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

Structured itinerary rows — route, dates, legs/segments, stops, durations, best offer and every OTA booking option with prices, booking URLs and baggage rules.

## `htmlReport` (type: `string`):

HTML summary with run stats and fare KPIs (cheapest fare, price + duration distributions, nonstop count, airline and OTA-provider breakdowns) plus per-query totals.

# 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 = {
    "origin": "JFK",
    "destination": "LAX"
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/agoda-flight-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 = {
    "origin": "JFK",
    "destination": "LAX",
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/agoda-flight-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "origin": "JFK",
  "destination": "LAX"
}' |
apify call sian.agency/agoda-flight-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sian.agency/agoda-flight-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

````json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Agoda Flights Scraper — Fares, OTA Offers & Price API",
        "description": "Scrape Agoda Flights fares by route and date. One-way and round-trip itineraries with airlines, flight numbers, segments, durations, stops and 14+ OTA booking offers per flight (provider prices, booking URLs, baggage rules). Flight price tracker and airfare data API for fare monitoring.",
        "version": "1.0",
        "x-build-id": "PANmtTSXKtyZdejfq"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/sian.agency~agoda-flight-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-sian.agency-agoda-flight-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/sian.agency~agoda-flight-scraper/runs": {
            "post": {
                "operationId": "runs-sync-sian.agency-agoda-flight-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/sian.agency~agoda-flight-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-sian.agency-agoda-flight-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "searchMode": {
                        "title": "🧭 Mode",
                        "enum": [
                            "search",
                            "details"
                        ],
                        "type": "string",
                        "description": "What to fetch.\n\n• **search** — one-way or round-trip fare search by route + date (paginated, 30 itineraries/page)\n• **details** — re-fetch specific itineraries by shareable flight URL or searchId + resultId (live re-priced booking offers)",
                        "default": "search"
                    },
                    "origin": {
                        "title": "🛫 Origin airport (IATA)",
                        "type": "string",
                        "description": "3-letter IATA code of the departure airport. Examples: **JFK** (New York), **BKK** (Bangkok), **SIN** (Singapore), **LHR** (London Heathrow).",
                        "default": "JFK"
                    },
                    "destination": {
                        "title": "🛬 Destination airport (IATA)",
                        "type": "string",
                        "description": "3-letter IATA code of the arrival airport. Examples: **LAX** (Los Angeles), **SIN** (Singapore), **DXB** (Dubai).",
                        "default": "LAX"
                    },
                    "date": {
                        "title": "📅 Departure date",
                        "type": "string",
                        "description": "Departure date in **YYYY-MM-DD** format. Must be in the future.\n\n💡 **TIP:** Leave empty to automatically search 30 days from today — handy for scheduled fare-tracking runs."
                    },
                    "returnDate": {
                        "title": "🔁 Return date (optional)",
                        "type": "string",
                        "description": "Return date in **YYYY-MM-DD** format. When set, the search becomes **round-trip** and every itinerary carries both legs. Leave empty for one-way."
                    },
                    "adults": {
                        "title": "🧑 Adults",
                        "minimum": 1,
                        "maximum": 9,
                        "type": "integer",
                        "description": "Adult passengers (12+). Default: 1.",
                        "default": 1
                    },
                    "children": {
                        "title": "🧒 Children",
                        "minimum": 0,
                        "maximum": 8,
                        "type": "integer",
                        "description": "Child passengers (ages 2–11). Default: 0.",
                        "default": 0
                    },
                    "infants": {
                        "title": "👶 Infants",
                        "minimum": 0,
                        "maximum": 4,
                        "type": "integer",
                        "description": "Infant passengers (under 2). Default: 0.",
                        "default": 0
                    },
                    "cabin": {
                        "title": "💺 Cabin class",
                        "enum": [
                            "Economy",
                            "Premium_Economy",
                            "Business",
                            "First"
                        ],
                        "type": "string",
                        "description": "Cabin class for the search. **Economy** is the most reliable; premium cabins depend on availability for the route and may return no results.",
                        "default": "Economy"
                    },
                    "sortOrder": {
                        "title": "↕️ Sort order",
                        "enum": [
                            "best",
                            "price",
                            "duration"
                        ],
                        "type": "string",
                        "description": "How upstream ranks itineraries.\n\n• **best** — balance of price + duration + stops\n• **price** — cheapest first\n• **duration** — shortest first",
                        "default": "best"
                    },
                    "routes": {
                        "title": "🚀 Bulk routes (multiple searches)",
                        "type": "array",
                        "description": "🚀 **BULK PROCESSING:** Search many routes in one run. Each object needs `origin` and `destination`; `date` and `returnDate` are optional (empty date = 30 days from today).\n\n```json\n[\n  { \"origin\": \"JFK\", \"destination\": \"LAX\", \"date\": \"2026-08-10\" },\n  { \"origin\": \"BKK\", \"destination\": \"SIN\", \"date\": \"2026-08-10\", \"returnDate\": \"2026-08-17\" }\n]\n```\n\n📊 **TIER-BASED LIMITS:**\n- **FREE users:** 1 route per run\n- **PAID users:** Unlimited routes\n\n💡 When provided, this overrides the single origin/destination fields above."
                    },
                    "maxResults": {
                        "title": "🔢 Max itineraries per route",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum itineraries to collect per route (30 per page upstream). FREE tier is capped at 25 itineraries per run.",
                        "default": 30
                    },
                    "flightUrls": {
                        "title": "🔗 Shareable flight URLs",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "🎫 **DETAILS MODE:** Shareable Agoda Flights URLs from a previous search run (every search row includes one in `shareableUrl`). Each URL is re-fetched live with its full booking-offer ladder.\n\nFormat: `https://flights.agoda.com/flights/JFK-LAX/2026-08-10/details/<resultId>?searchId=<searchId>`\n\n📊 **TIER-BASED LIMITS:**\n- **FREE users:** 1 itinerary per run\n- **PAID users:** Unlimited",
                        "items": {
                            "type": "string"
                        }
                    },
                    "flightRefs": {
                        "title": "🆔 Search/result references",
                        "type": "array",
                        "description": "🎫 **DETAILS MODE (alternative input):** Explicit references from a previous search — each object needs the search row's `searchId` and `resultId`.\n\n```json\n[\n  { \"searchId\": \"0HDiFhsesx\", \"resultId\": \"c0b8fae339ab097af3a2c41dad49c563\" }\n]\n```"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
````
