{
  "openapi": "3.0.1",
  "info": {
    "title": "Flight Price Aggregator API 💰 — 7 Sources, One Query",
    "description": "Compare flight prices across Google Flights, Skyscanner, Kiwi, Ryanair, Wizz Air, EasyJet & Norwegian in one call — or batch 50 routes per run. Merges the same flight across sources and converts every currency to yours, so the cheapest tag is real. Optional per-route savings summary. JSON/CSV.",
    "version": "0.0",
    "x-build-id": "WU9UOw1NVmXRr9EBz"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/memo23~flights-aggregator-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-memo23-flights-aggregator-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/memo23~flights-aggregator-scraper/runs": {
      "post": {
        "operationId": "runs-sync-memo23-flights-aggregator-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/memo23~flights-aggregator-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-memo23-flights-aggregator-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": {
          "origin": {
            "title": "Origin (city or airport)",
            "type": "string",
            "description": "Origin as a city name (e.g. London, Barcelona) or an airport IATA code (e.g. LHR, JFK). A city resolves to its primary airport — pass an exact IATA to target another (e.g. STN)."
          },
          "destination": {
            "title": "Destination (city or airport)",
            "type": "string",
            "description": "Destination as a city name (e.g. Barcelona) or an airport IATA code (e.g. BCN, CDG)."
          },
          "departDate": {
            "title": "Departure date",
            "type": "string",
            "description": "Outbound date. Format YYYY-MM-DD (e.g. 2026-08-12)."
          },
          "returnDate": {
            "title": "Return date (optional)",
            "type": "string",
            "description": "Return date for a round trip. Leave empty for one-way."
          },
          "adults": {
            "title": "Adults",
            "minimum": 1,
            "maximum": 9,
            "type": "integer",
            "description": "Number of adult passengers.",
            "default": 1
          },
          "children": {
            "title": "Children",
            "minimum": 0,
            "maximum": 9,
            "type": "integer",
            "description": "Number of child passengers.",
            "default": 0
          },
          "currency": {
            "title": "Currency",
            "type": "string",
            "description": "Currency for price comparison (ISO 4217, e.g. USD, GBP, EUR). Sources that accept a currency are queried in it. Wizz Air and easyJet always price in the departure market's currency — those rows keep the price they actually quote in \"price\"/\"currency\", and also carry \"priceNormalized\" in this currency (ECB daily reference rates, plus a backup feed for the currencies the ECB doesn't publish — Wizz Air's ALL/RSD/MKD/BAM/GEL/MDL/UAH/AED markets) so the cheapest tag and the route summary compare like for like.",
            "default": "USD"
          },
          "cabinClass": {
            "title": "Cabin class",
            "enum": [
              "ECONOMY",
              "PREMIUM_ECONOMY",
              "BUSINESS",
              "FIRST"
            ],
            "type": "string",
            "description": "Preferred cabin class.",
            "default": "ECONOMY"
          },
          "routes": {
            "title": "Routes (batch mode)",
            "type": "array",
            "description": "Optional batch mode: search many routes in ONE run. Array of objects — each needs \"origin\" and \"destination\" (city name or IATA); \"departDate\"/\"returnDate\" are optional per route and fall back to the top-level dates. When set, the top-level origin/destination are ignored. Max 50 routes per run; each route bills one route-search event. Example: [{\"origin\":\"LHR\",\"destination\":\"BCN\"},{\"origin\":\"LHR\",\"destination\":\"MAD\",\"departDate\":\"2026-09-01\"}]"
          },
          "directOnly": {
            "title": "Direct flights only",
            "type": "boolean",
            "description": "Only keep nonstop flights (stops = 0). Price-only calendar rows (no stop data) are excluded whenever a stop/duration filter is active.",
            "default": false
          },
          "maxStops": {
            "title": "Max stops",
            "minimum": 0,
            "maximum": 5,
            "type": "integer",
            "description": "Only keep flights with at most this many stops (0 = nonstop). Leave empty for no limit."
          },
          "maxDurationMinutes": {
            "title": "Max total duration (minutes)",
            "minimum": 30,
            "type": "integer",
            "description": "Only keep flights whose total duration is at most this many minutes (e.g. 300 = 5h). Leave empty for no limit."
          },
          "includeRouteSummary": {
            "title": "Include route summary",
            "type": "boolean",
            "description": "Emit one cross-source comparison row per route into a separate \"route-summaries\" dataset: cheapest price and source per direction, the spread between the cheapest and most expensive source (what you save by booking the right one), every source's price, plus which sources answered, failed, or timed out. Kept out of the main dataset so your flight rows and CSV columns stay unchanged.",
            "default": false
          },
          "routeSummaryDatasetName": {
            "title": "Route summary dataset name",
            "type": "string",
            "description": "Where the route-summary rows go. Named datasets are per-account and append-only, so summaries from every run accumulate in one place — which is exactly what makes a scheduled fare watch readable as price history. Override it to keep separate watchlists, clients or environments apart. Only used when \"Include route summary\" is on.",
            "default": "route-summaries"
          },
          "sources": {
            "title": "Sources to query",
            "type": "array",
            "description": "Which flight sources to fan out to. Leave empty to query all seven. Note: Ryanair, Wizz Air, EasyJet and Norwegian only fly their own (mostly European) routes.",
            "items": {
              "type": "string",
              "enum": [
                "ryanair",
                "wizzair",
                "easyjet",
                "norwegian",
                "googleflights",
                "skyscanner",
                "kiwi"
              ]
            },
            "default": []
          },
          "maxPerSource": {
            "title": "Max offers per source",
            "minimum": 1,
            "maximum": 100,
            "type": "integer",
            "description": "Cap on the number of offers returned by each source before merging.",
            "default": 10
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Proxy for the rate-limit-sensitive sources (Skyscanner, Google Flights, Norwegian). Defaults to Apify Proxy in automatic mode, which works on every plan. If your account has RESIDENTIAL, selecting it gives the best success rate on those three sources — but it is NOT the default, because naming a proxy group your account lacks makes the run fail input validation before it starts.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}