# Emirates Skywards Miles Scraper (`leafy-dev-jr/emirates-skywards-miles-scraper`) Actor

Skywards miles calculator at scale: pull Emirates & flydubai earn miles (Skywards + Tier) for every route, cabin & tier in one run. Price a whole network in minutes.

- **URL**: https://apify.com/leafy-dev-jr/emirates-skywards-miles-scraper.md
- **Developed by:** [Leafy](https://apify.com/leafy-dev-jr) (community)
- **Categories:** Automation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.40 / 1,000 results

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/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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## Emirates & flydubai Skywards Miles Scraper

**Bulk-calculate Skywards earn miles across Emirates (EK) and flydubai (FZ) for any route, cabin, and tier — thousands of routes in one run, straight to a clean spreadsheet.**

Feed it a list of airports (or exact route pairs), pick your airlines, cabins, and Skywards tiers, and get back every combination priced out: **Skywards Miles** and **Tier Miles** for each fare bucket. No login, no manual clicking through the Miles Calculator one route at a time.

---

### Why use this

The official Miles Calculator prices **one airline, one route, one cabin, one tier at a time** through a [web form](https://www.emirates.com/english/skywards/miles-calculator/). Pricing a network by hand is days of clicking. This actor:

- ✅ **Fans out automatically** across every airline × origin × destination × cabin × tier you give it.
- ✅ **Covers Emirates and flydubai** in one run, with the correct fare buckets for each.
- ✅ **Returns clean, flat rows** ready for CSV / Excel / Google Sheets / a database.
- ✅ **Streams results live** — rows appear as they're scraped, so big jobs show progress immediately.
- ✅ **Scales to hundreds of thousands of rows** (the tools this is based on processed 500k+).

---

### What you get

One row per **airline × route × cabin × tier × fare**. Export to CSV, JSON, or Excel, or pull via API.

```json
{
    "Direction": "One Way",
    "Airline": "Emirates",
    "Leaving from": "DXB",
    "Going to": "LHR",
    "Cabin Class": "Business",
    "Skywards Tier": "Gold",
    "Fare": "Business Flex",
    "Skywards Miles": 6900,
    "Tier Miles": 5250,
    "Notes": "batch-6",
    "Scraped At": "2026-07-10T20:03:48.504Z"
}
````

| Field | Type | Description |
|---|---|---|
| `Direction` | string | `One Way` or `Round Trip` |
| `Airline` | string | `Emirates` or `flydubai` |
| `Leaving from` | string | Origin IATA code |
| `Going to` | string | Destination IATA code |
| `Cabin Class` | string | `Economy`, `Premium Economy`, `Business`, `First` (flydubai: Economy/Business only) |
| `Skywards Tier` | string | `Blue`, `Silver`, `Gold`, `Platinum` |
| `Fare` | string | Emirates: e.g. `Business Flex`, `Economy Saver`, `First Flexplus`. flydubai: `Economy Lite/Value/Flex`, `Business` |
| `Skywards Miles` | integer | Redeemable miles earned |
| `Tier Miles` | integer | Miles counting toward tier status |
| `Notes` | string | null | Whatever you typed in the optional **Notes** input, copied onto every row (else `null`) |
| `Scraped At` | string | ISO 8601 UTC timestamp of when that route was scraped |

***

### How it works

1. Builds every `airline × route × cabin × tier` combination from your input (or your explicit route pairs), skipping cabins an airline doesn't offer (e.g. flydubai First).
2. Calls the public Miles Calculator API once per combination, in parallel, with the right `airline` code.
3. Expands each response into fare rows using each airline's own fare buckets (Emirates: FlexPlus/Flex/Saver/Special, First = FlexPlus+Flex; flydubai Economy: Lite/Value/Flex; flydubai Business: Business).
4. Normalizes the miles and streams each row to your dataset live.

***

### Input

```json
{
    "milesType": "earn",
    "airlines": ["Emirates", "flydubai"],
    "routeInputMethod": "cross",
    "crossOrigins": ["DXB"],
    "crossDestinations": ["LHR", "JFK", "KTM"],
    "cabinClasses": ["Economy", "Business", "First"],
    "tiers": ["Blue", "Gold"],
    "journeyType": "One Way",
    "notes": "batch-6"
}
```

| Field | Type | Required | Default | What it does |
|---|---|---|---|---|
| `milesType` | string | yes | `earn` | `earn` is the only option today. `spend` / `upgrade` are shown in the dropdown but **coming soon** — picking one stops the run with a note. |
| `airlines` | string\[] | yes | both | `Emirates`, `flydubai`, or both. flydubai only prices Economy/Business. |
| `routeInputMethod` | string | yes | `cross` | Which route option you're using: `cross` (Option 1), `network` (Option 2), or `pairs` (Option 3) — see below. |
| `cabinClasses` | string\[] | yes | all 4 | Cabins to price (unsupported ones are skipped per airline). |
| `tiers` | string\[] | yes | all 4 | Skywards tiers to price. |
| `journeyType` | string | no | `One Way` | `One Way` or `Round Trip`. |
| `notes` | string | no | — | Free text copied into a `Notes` column on every row — tag/label your run. |
| `maxConcurrency` | int | no | `10` | Parallel API calls (1–50). |
| `maxRequestRetries` | int | no | `3` | Retries before a request is logged as failed. |

#### Routes: pick ONE option, fill in only its field(s)

All three options live in the **Routes** section. `routeInputMethod` decides which field(s) the actor reads.

| Option | `routeInputMethod` | What it prices | Its field(s) |
|---|---|---|---|
| **Option 1 — Cross** *(default)* | `cross` | Every origin paired with every destination | `crossOrigins` **and** `crossDestinations` *(free text)* |
| **Option 2 — Origin → all** | `network` | Every airport the airline serves, from your origin(s) | `networkOrigins` *(dropdown, multi-select, default DXB)* |
| **Option 3 — Route pairs** | `pairs` | Exactly the `FROM-TO` routes you list | `routePairs` *(free text, e.g. `"DXB-LHR"`)* |

##### Option 2 — one airline, all its routes

Pick a single airline, choose Option 2, and set the origin:

```json
{ "airlines": ["flydubai"], "routeInputMethod": "network", "networkOrigins": ["DXB"], "cabinClasses": ["Economy", "Business"], "tiers": ["Blue", "Gold", "Silver", "Platinum"] }
```

That prices every flydubai route from DXB (146 destinations). Emirates works the same way (144 airports). You can select **several origins** — each is priced against the whole network, so 3 origins ≈ 3× the calls (the run warns you). Tip: these runs are large, so narrow with cabins/tiers to keep cost down.

***

### FAQ

**What's the difference between Emirates and flydubai here?** Both earn Emirates Skywards miles. Emirates (EK) has 4 cabins and FlexPlus/Flex/Saver/Special fares; flydubai (FZ) has Economy (Lite/Value/Flex) and Business only. The actor handles each airline's fare structure automatically and tags every row with the `Airline`.

**Which miles are these — earning or redeeming?** Earning. `Skywards Miles` are redeemable miles you earn; `Tier Miles` count toward Silver/Gold/Platinum status. **Spend (redemption) and cabin-upgrade miles are coming soon** — they're listed under `milesType` in the input so you can see what's next.

**Why do Emirates First-class rows only show FlexPlus and Flex?** First doesn't sell Saver/Special buckets, so only those two are returned — matching the calculator.

**I selected First but got no flydubai rows for it.** flydubai doesn't offer Premium Economy or First — those cabins are simply skipped for flydubai. Emirates rows still include them.

**Some combos came back blank. Why?** Neither airline flies (or partner-prices) every airport pair. Blank rows mean the combo was checked and returned no miles — the actor keeps them so you can see it was checked (the `Fare`/miles columns are empty).

**What's the `Notes` column?** Whatever you type in the optional **Notes** input is copied onto every row — handy for tagging a batch, client, or date. Leave it blank and the column is empty.

**What's `Scraped At`?** An ISO 8601 UTC timestamp of when each route was fetched, so you always know how fresh a row is.

**Do I need a proxy?** No — proxy is off and the actor runs directly (the endpoint is open and global). Advanced users can still route through Apify Proxy via the API (see below).

**Are the numbers guaranteed accurate?** They come straight from the live Miles Calculator and change when earn rates are updated. Always treated as a snapshot at run time (see `Scraped At`).

***

### Known airport codes

Airport fields are **free text** — enter any 3-letter IATA code. For reference, here are all the airports Emirates and flydubai currently serve (253 in total; use the `originAll` method to hit a whole network without typing them):

```
ABJ ABV ACC ADD ADL AER AHB AJF AKL ALA ALG AMD AMM AMS AQI AQJ ARN ASB ASM ATH AWZ
BAH BCN BEG BEY BGW BGY BHX BKK BLQ BLR BND BNE BOG BOM BOS BRU BSL BSR BTS BUD BUS
CAG CAI CAN CCJ CCU CDG CEB CFU CGK CGP CHC CKY CMB CMN COK CPH CPT CRK CTA
DAC DAR DBV DEL DFW DME DMM DPS DSS DUB DUR DUS DXB DYU
EAM EBB EBL EDI ELQ ESB EVN EWR EZE  FCO FEG FRA FRU
GAN GBB GIG GIZ GLA GRU GVA GYD  HAM HAN HAS HBE HEL HGA HKG HKT HND HOF HRE HRI HYD
IAD IAH ICN IEV IFN IKA ISB IST ISU  JED JFK JIB JMK JNB JRO JTR JUB
KBV KHI KIH KIX KRK KRR KRT KTM KUF KUL KUT KWI KZN
LAD LAX LCA LED LGW LHE LHR LIS LJU LKO LOS LRR LUN LYP LYS
MAA MAD MAN MBA MCO MCT MCX MED MEL MEX MGQ MHD MIA MLA MLE MNL MRU MRV MUC MUX MXP
NBO NCE NCL NJF NMA NQZ NRT NUM  ODS OLB OPO ORD OSL OSS OTP OVB
PEE PEK PER PEW PNH PRG PSA PVG PZU  RGN RIX ROV RUH
SAW SEA SEZ SFO SGN SIN SJJ SKD SKG SKP SKT SLL SOF SSH STN SVO SVX SYD SYZ SZG
TBS TGD TIF TIV TLL TLV TPE TRV TUN TUU  UET UFA ULH
VCE VIE VKO VNO VOG VOZ  WAW  YNB YUL YYZ  ZAG ZNZ ZRH ZVH ZVJ ZYL
```

***

### Contact / feedback

Bug reports and feature requests (redemption miles, upgrade pricing, more Skywards partner airlines) welcome — email the developer @leafydevjr@gmail.com.

# Actor input Schema

## `milesType` (type: `string`):

Only "Earn" is available today. "Spend" and "Upgrade" are coming soon — selecting them stops the run with a note.

## `airlines` (type: `array`):

Which carriers to price. Both share the Emirates Skywards program and the same miles currency. flydubai only has Economy and Business cabins — other cabins are skipped for it automatically.

## `routeInputMethod` (type: `string`):

Option 1 — Cross: every origin paired with every destination. Option 2 — Origin → all destinations: every airport the airline serves, from your origin(s). Option 3 — Route pairs: exact FROM-TO routes.

## `crossOrigins` (type: `array`):

Departure airport codes (3 letters, e.g. DXB, LHR) — type any code, one per entry. Paired with every destination below. (Used only for Option 1 — Cross.)

## `crossDestinations` (type: `array`):

Arrival airport codes — type any code, one per entry. Same-airport pairs are skipped. (Used only for Option 1 — Cross.)

## `networkOrigins` (type: `array`):

Pick one or more departure airports. Each one is priced against every destination the airline serves. Tip: more than one origin makes a much bigger run (each origin adds a whole network). (Used only for Option 2.)

## `routePairs` (type: `array`):

Exact routes as "FROM-TO" (e.g. "DXB-LHR"), one per entry. (Used only for Option 3.)

## `cabinClasses` (type: `array`):

Which cabins to price. Emirates First only returns FlexPlus and Flex fares. flydubai only supports Economy and Business — Premium Economy and First are skipped for flydubai.

## `tiers` (type: `array`):

Which Skywards membership tiers to price. Earn miles differ by tier.

## `journeyType` (type: `string`):

One Way prices a single leg; Round Trip prices the return journey (~2× the miles).

## `notes` (type: `string`):

Any text here is copied into a "Notes" column on every output row — handy for tagging or labeling a batch/run.

## `maxConcurrency` (type: `integer`):

How many API calls to run in parallel. 10–20 is safe. Raise for very large jobs.

## `maxRequestRetries` (type: `integer`):

Retries for a failed request before it is logged as failed.

## Actor input object example

```json
{
  "milesType": "earn",
  "airlines": [
    "Emirates",
    "flydubai"
  ],
  "routeInputMethod": "cross",
  "crossOrigins": [
    "DXB"
  ],
  "crossDestinations": [
    "LHR",
    "JFK"
  ],
  "networkOrigins": [
    "DXB"
  ],
  "routePairs": [
    "DXB-LHR",
    "DXB-JFK"
  ],
  "cabinClasses": [
    "Economy",
    "Premium Economy",
    "Business",
    "First"
  ],
  "tiers": [
    "Blue",
    "Silver",
    "Gold",
    "Platinum"
  ],
  "journeyType": "One Way",
  "maxConcurrency": 10,
  "maxRequestRetries": 3
}
```

# Actor output Schema

## `overview` (type: `string`):

Every airline × route × cabin × tier × fare with its Skywards and Tier miles.

# 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 = {
    "crossOrigins": [
        "DXB"
    ],
    "crossDestinations": [
        "LHR",
        "JFK"
    ],
    "networkOrigins": [
        "DXB"
    ],
    "routePairs": [
        "DXB-LHR",
        "DXB-JFK"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("leafy-dev-jr/emirates-skywards-miles-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 = {
    "crossOrigins": ["DXB"],
    "crossDestinations": [
        "LHR",
        "JFK",
    ],
    "networkOrigins": ["DXB"],
    "routePairs": [
        "DXB-LHR",
        "DXB-JFK",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("leafy-dev-jr/emirates-skywards-miles-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 '{
  "crossOrigins": [
    "DXB"
  ],
  "crossDestinations": [
    "LHR",
    "JFK"
  ],
  "networkOrigins": [
    "DXB"
  ],
  "routePairs": [
    "DXB-LHR",
    "DXB-JFK"
  ]
}' |
apify call leafy-dev-jr/emirates-skywards-miles-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=leafy-dev-jr/emirates-skywards-miles-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Emirates Skywards Miles Scraper",
        "description": "Skywards miles calculator at scale: pull Emirates & flydubai earn miles (Skywards + Tier) for every route, cabin & tier in one run. Price a whole network in minutes.",
        "version": "0.1",
        "x-build-id": "OXnG40q6DReGkDF7L"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/leafy-dev-jr~emirates-skywards-miles-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-leafy-dev-jr-emirates-skywards-miles-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/leafy-dev-jr~emirates-skywards-miles-scraper/runs": {
            "post": {
                "operationId": "runs-sync-leafy-dev-jr-emirates-skywards-miles-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/leafy-dev-jr~emirates-skywards-miles-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-leafy-dev-jr-emirates-skywards-miles-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",
                "required": [
                    "milesType",
                    "airlines",
                    "routeInputMethod",
                    "cabinClasses",
                    "tiers"
                ],
                "properties": {
                    "milesType": {
                        "title": "Miles type",
                        "enum": [
                            "earn",
                            "spend",
                            "upgrade"
                        ],
                        "type": "string",
                        "description": "Only \"Earn\" is available today. \"Spend\" and \"Upgrade\" are coming soon — selecting them stops the run with a note.",
                        "default": "earn"
                    },
                    "airlines": {
                        "title": "Airlines",
                        "type": "array",
                        "description": "Which carriers to price. Both share the Emirates Skywards program and the same miles currency. flydubai only has Economy and Business cabins — other cabins are skipped for it automatically.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Emirates",
                                "flydubai"
                            ],
                            "enumTitles": [
                                "Emirates (EK)",
                                "flydubai (FZ)"
                            ]
                        },
                        "default": [
                            "Emirates",
                            "flydubai"
                        ]
                    },
                    "routeInputMethod": {
                        "title": "Route option",
                        "enum": [
                            "cross",
                            "network",
                            "pairs"
                        ],
                        "type": "string",
                        "description": "Option 1 — Cross: every origin paired with every destination. Option 2 — Origin → all destinations: every airport the airline serves, from your origin(s). Option 3 — Route pairs: exact FROM-TO routes.",
                        "default": "cross"
                    },
                    "crossOrigins": {
                        "title": "Option 1 · Cross — Origins (IATA codes)",
                        "type": "array",
                        "description": "Departure airport codes (3 letters, e.g. DXB, LHR) — type any code, one per entry. Paired with every destination below. (Used only for Option 1 — Cross.)",
                        "items": {
                            "type": "string"
                        }
                    },
                    "crossDestinations": {
                        "title": "Option 1 · Cross — Destinations (IATA codes)",
                        "type": "array",
                        "description": "Arrival airport codes — type any code, one per entry. Same-airport pairs are skipped. (Used only for Option 1 — Cross.)",
                        "items": {
                            "type": "string"
                        }
                    },
                    "networkOrigins": {
                        "title": "Option 2 · Origin(s) → all destinations",
                        "type": "array",
                        "description": "Pick one or more departure airports. Each one is priced against every destination the airline serves. Tip: more than one origin makes a much bigger run (each origin adds a whole network). (Used only for Option 2.)",
                        "items": {
                            "type": "string",
                            "enum": [
                                "ABJ",
                                "ABV",
                                "ACC",
                                "ADD",
                                "ADL",
                                "AER",
                                "AHB",
                                "AJF",
                                "AKL",
                                "ALA",
                                "ALG",
                                "AMD",
                                "AMM",
                                "AMS",
                                "AQI",
                                "AQJ",
                                "ARN",
                                "ASB",
                                "ASM",
                                "ATH",
                                "AWZ",
                                "BAH",
                                "BCN",
                                "BEG",
                                "BEY",
                                "BGW",
                                "BGY",
                                "BHX",
                                "BKK",
                                "BLQ",
                                "BLR",
                                "BND",
                                "BNE",
                                "BOG",
                                "BOM",
                                "BOS",
                                "BRU",
                                "BSL",
                                "BSR",
                                "BTS",
                                "BUD",
                                "BUS",
                                "CAG",
                                "CAI",
                                "CAN",
                                "CCJ",
                                "CCU",
                                "CDG",
                                "CEB",
                                "CFU",
                                "CGK",
                                "CGP",
                                "CHC",
                                "CKY",
                                "CMB",
                                "CMN",
                                "COK",
                                "CPH",
                                "CPT",
                                "CRK",
                                "CTA",
                                "DAC",
                                "DAR",
                                "DBV",
                                "DEL",
                                "DFW",
                                "DME",
                                "DMM",
                                "DPS",
                                "DSS",
                                "DUB",
                                "DUR",
                                "DUS",
                                "DXB",
                                "DYU",
                                "EAM",
                                "EBB",
                                "EBL",
                                "EDI",
                                "ELQ",
                                "ESB",
                                "EVN",
                                "EWR",
                                "EZE",
                                "FCO",
                                "FEG",
                                "FRA",
                                "FRU",
                                "GAN",
                                "GBB",
                                "GIG",
                                "GIZ",
                                "GLA",
                                "GRU",
                                "GVA",
                                "GYD",
                                "HAM",
                                "HAN",
                                "HAS",
                                "HBE",
                                "HEL",
                                "HGA",
                                "HKG",
                                "HKT",
                                "HND",
                                "HOF",
                                "HRE",
                                "HRI",
                                "HYD",
                                "IAD",
                                "IAH",
                                "ICN",
                                "IEV",
                                "IFN",
                                "IKA",
                                "ISB",
                                "IST",
                                "ISU",
                                "JED",
                                "JFK",
                                "JIB",
                                "JMK",
                                "JNB",
                                "JRO",
                                "JTR",
                                "JUB",
                                "KBV",
                                "KHI",
                                "KIH",
                                "KIX",
                                "KRK",
                                "KRR",
                                "KRT",
                                "KTM",
                                "KUF",
                                "KUL",
                                "KUT",
                                "KWI",
                                "KZN",
                                "LAD",
                                "LAX",
                                "LCA",
                                "LED",
                                "LGW",
                                "LHE",
                                "LHR",
                                "LIS",
                                "LJU",
                                "LKO",
                                "LOS",
                                "LRR",
                                "LUN",
                                "LYP",
                                "LYS",
                                "MAA",
                                "MAD",
                                "MAN",
                                "MBA",
                                "MCO",
                                "MCT",
                                "MCX",
                                "MED",
                                "MEL",
                                "MEX",
                                "MGQ",
                                "MHD",
                                "MIA",
                                "MLA",
                                "MLE",
                                "MNL",
                                "MRU",
                                "MRV",
                                "MUC",
                                "MUX",
                                "MXP",
                                "NBO",
                                "NCE",
                                "NCL",
                                "NJF",
                                "NMA",
                                "NQZ",
                                "NRT",
                                "NUM",
                                "ODS",
                                "OLB",
                                "OPO",
                                "ORD",
                                "OSL",
                                "OSS",
                                "OTP",
                                "OVB",
                                "PEE",
                                "PEK",
                                "PER",
                                "PEW",
                                "PNH",
                                "PRG",
                                "PSA",
                                "PVG",
                                "PZU",
                                "RGN",
                                "RIX",
                                "ROV",
                                "RUH",
                                "SAW",
                                "SEA",
                                "SEZ",
                                "SFO",
                                "SGN",
                                "SIN",
                                "SJJ",
                                "SKD",
                                "SKG",
                                "SKP",
                                "SKT",
                                "SLL",
                                "SOF",
                                "SSH",
                                "STN",
                                "SVO",
                                "SVX",
                                "SYD",
                                "SYZ",
                                "SZG",
                                "TBS",
                                "TGD",
                                "TIF",
                                "TIV",
                                "TLL",
                                "TLV",
                                "TPE",
                                "TRV",
                                "TUN",
                                "TUU",
                                "UET",
                                "UFA",
                                "ULH",
                                "VCE",
                                "VIE",
                                "VKO",
                                "VNO",
                                "VOG",
                                "VOZ",
                                "WAW",
                                "YNB",
                                "YUL",
                                "YYZ",
                                "ZAG",
                                "ZNZ",
                                "ZRH",
                                "ZVH",
                                "ZVJ",
                                "ZYL"
                            ]
                        }
                    },
                    "routePairs": {
                        "title": "Option 3 · Route pairs",
                        "type": "array",
                        "description": "Exact routes as \"FROM-TO\" (e.g. \"DXB-LHR\"), one per entry. (Used only for Option 3.)",
                        "items": {
                            "type": "string"
                        }
                    },
                    "cabinClasses": {
                        "title": "Cabin classes",
                        "type": "array",
                        "description": "Which cabins to price. Emirates First only returns FlexPlus and Flex fares. flydubai only supports Economy and Business — Premium Economy and First are skipped for flydubai.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Economy",
                                "Premium Economy",
                                "Business",
                                "First"
                            ],
                            "enumTitles": [
                                "Economy",
                                "Premium Economy",
                                "Business",
                                "First"
                            ]
                        },
                        "default": [
                            "Economy",
                            "Premium Economy",
                            "Business",
                            "First"
                        ]
                    },
                    "tiers": {
                        "title": "Skywards tiers",
                        "type": "array",
                        "description": "Which Skywards membership tiers to price. Earn miles differ by tier.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "Blue",
                                "Silver",
                                "Gold",
                                "Platinum"
                            ],
                            "enumTitles": [
                                "Blue",
                                "Silver",
                                "Gold",
                                "Platinum"
                            ]
                        },
                        "default": [
                            "Blue",
                            "Silver",
                            "Gold",
                            "Platinum"
                        ]
                    },
                    "journeyType": {
                        "title": "Journey type",
                        "enum": [
                            "One Way",
                            "Round Trip"
                        ],
                        "type": "string",
                        "description": "One Way prices a single leg; Round Trip prices the return journey (~2× the miles).",
                        "default": "One Way"
                    },
                    "notes": {
                        "title": "Notes (optional)",
                        "type": "string",
                        "description": "Any text here is copied into a \"Notes\" column on every output row — handy for tagging or labeling a batch/run."
                    },
                    "maxConcurrency": {
                        "title": "Max concurrent requests",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "How many API calls to run in parallel. 10–20 is safe. Raise for very large jobs.",
                        "default": 10
                    },
                    "maxRequestRetries": {
                        "title": "Max retries per request",
                        "minimum": 0,
                        "maximum": 10,
                        "type": "integer",
                        "description": "Retries for a failed request before it is logged as failed.",
                        "default": 3
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
