Search for flights and return available options.
Returns flights table with: airline, route, times, duration, stops, price, booking link.
═══════════════════════════════════════════════════════════════════════════
SEARCH MODES (mutually exclusive)
═══════════════════════════════════════════════════════════════════════════
1. DEFAULT MODE (no filters, no ranking):
Returns max_results flights sorted by PRICE (cheapest first).
Use for: "find flights", "cheapest flights"
2. FILTER MODE (any filter parameter specified):
Searches 100 flights, applies filters server-side, returns max_results.
Filters: time ranges, price limits, airports, stops, airlines, duration.
Results sorted by PRICE after filtering.
Use for: "morning flights", "under 200 EUR", "direct only", "from MXP"
3. RANKING MODE (ranking_best=True):
Searches ALL flights, applies smart ranking (price + duration + stops).
Returns top max_results by overall value.
Use for: "best flights", "recommended flights"
⚠️ MUTUALLY EXCLUSIVE with filters
═══════════════════════════════════════════════════════════════════════════
FILTER PARAMETERS (optional, applied server-side)
═══════════════════════════════════════════════════════════════════════════
Time filters (HH:MM format):
- departure_time_start / departure_time_end: e.g., "06:00" to "12:00" for morning
- arrival_time_start / arrival_time_end: e.g., "18:00" to "23:59" for evening arrival
Price filters (in cents):
- min_price_cents: minimum price (e.g., 5000 = 50 EUR)
- max_price_cents: maximum price (e.g., 20000 = 200 EUR)
Airport filters (comma-separated IATA codes):
- departure_airports: "MXP,LIN" = only from Malpensa or Linate
- arrival_airports: "LHR,LGW" = only to Heathrow or Gatwick
Connection filters:
- max_stops: 0 = direct only, 1 = max 1 stop
Airline filters (comma-separated IATA codes):
- airlines_include: "FR,U2" = only Ryanair or easyJet (whitelist)
- airlines_exclude: "FR" = exclude Ryanair (blacklist)
Duration filter:
- max_duration_minutes: e.g., 180 = max 3 hours
Examples:
- Morning direct flights under 150 EUR:
departure_time_start="06:00", departure_time_end="12:00", max_stops=0, max_price_cents=15000
- Flights from Malpensa only, max 2 hours:
departure_airports="MXP", max_duration_minutes=120
═══════════════════════════════════════════════════════════════════════════
HARD CONSTRAINTS
═══════════════════════════════════════════════════════════════════════════
1. Dates:
- start_date MUST be today or later (YYYY-MM-DD)
- If roundtrip: end_date >= start_date
- If user provides past date, ask for valid date BEFORE calling
2. Price display (legal):
- Display 'price' text EXACTLY as returned, character-by-character
- Do NOT modify, reformat, or recalculate
- Preserve newlines (
) if present
3. Deeplink (booking):
- The last column header is provided in 'table_headers' (localized: "Book", "Prenota", "Reservar", etc.)
- Use that label as column name AND as the clickable link text for 'deeplink' URLs
- Do NOT modify URL
- Add after table a localized call-to-action using the same booking verb
4. Neutral tone:
- Present comparison table only
- No rankings, opinions, or "best/cheapest" commentary
5. Ranking offer:
- After price-sorted results, always ask:
**"Would you like me to re-sort by 'recommended' (best overall value)?"**
- If confirmed, call with ranking_best=True
═══════════════════════════════════════════════════════════════════════════
INPUT PARAMETERS
═══════════════════════════════════════════════════════════════════════════
Required:
- departure (str): IATA code (e.g., "MIL", "MXP")
- arrival (str): IATA code (e.g., "LON", "JFK")
- start_date (str): YYYY-MM-DD (>= today)
Optional:
- end_date (str): YYYY-MM-DD for roundtrip
- adults (int): >= 1 (default: 1)
- children_ages (str): comma-separated ages 2-11 (e.g., "3,8")
- infants_ages (str): comma-separated ages 0-1 (e.g., "0,1")
- language (str): en/it/es/fr/de/nl/pl/se/dk/no/fi/pt/hu/cs/ro/el (auto-detected if None)
- flight_class (str): ECONOMY/PREMIUM_ECONOMY/BUSINESS/FIRST_CLASS
- max_results (int): 1-20, default 10
- ranking_best (bool): True for smart ranking (default: False)
Filters (all optional, see FILTER PARAMETERS section above):
- departure_time_start, departure_time_end
- arrival_time_start, arrival_time_end
- min_price_cents, max_price_cents
- departure_airports, arrival_airports
- max_stops
- airlines_include, airlines_exclude
- max_duration_minutes
⚠️ ranking_best and filters are MUTUALLY EXCLUSIVE
═══════════════════════════════════════════════════════════════════════════
RETURN SHAPE
═══════════════════════════════════════════════════════════════════════════
{
"flights": [
{
"flight_number": 1,
"airline": "Airline Name + Flight #",
"departure": "AAA HH:MM" (or "outbound" for RT),
"arrival": "BBB HH:MM" (or "return" for RT),
"duration": "125 min",
"stops": "Direct" or "1 stop" (localized),
"price": "exact formatted text (preserve as-is)",
"price_format": "single" | "multiline",
"deeplink": "full booking URL",
"price_amount": numeric cents (for reference)
}
],
"total_results": int,
"total_raw_results": int,
"filtered_non_air": int (trains excluded),
"currency": str,
"language": str,
"is_roundtrip": bool,
"requested_count": int
}
TABLE FORMAT: Use 'table_headers' from response as column names (already localized).
The last column is the booking link (e.g. "Book", "Prenota", "Reservar", "Réserver", "Buchen").
Render each deeplink as [localized_label](url). Display ALL flights in the response.
search_flights