Schedules

Runnable examples for airport departure and arrival boards using the Schedules endpoint. Covers single-airport boards, delay analytics, and side-by-side traffic comparisons.

#QuestionData used
1Show today's next departures from KJFKSchedules (departures)
2How many flights are delayed or cancelled at EGLL today?Schedules (departures)
3Side-by-side arrivals and departures count at KJFKSchedules (arrivals + departures)

Requirements

Auth
x-api-key on every request (direct subscription). Learn more →

Install

The scripts below use requests for API calls and rich for terminal output. Install once:

pip install requests rich

1. Today's departures from KJFK

Question: Show today's next departures from KJFK.

Flight row keys use title case: Flight, Time, Status, Airline, Airport. Lowercase keys return None.

import os

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"

STATUS_STYLE: dict[str, str] = {
    "Departed": "green",
    "Delayed": "yellow",
    "Cancelled": "red",
    "Scheduled": "white",
    "Arrived": "green",
}


def fetch_departures(icao: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/schedules/departures",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("flights", [])


def main() -> None:
    flights = fetch_departures("KJFK")
    if not flights:
        console.print("[yellow]No departure data returned for KJFK.[/]")
        return

    display = flights[:10]

    table = Table(title=f"KJFK Departures — showing {len(display)} of {len(flights)}")
    table.add_column("Flight", style="cyan")
    table.add_column("Airline")
    table.add_column("Destination")
    table.add_column("Time")
    table.add_column("Status")

    for f in display:
        status = f.get("Status", "—")
        style = STATUS_STYLE.get(status, "white")
        table.add_row(
            f.get("Flight", "—"),
            f.get("Airline", "—"),
            f.get("Airport", "—"),
            f.get("Time", "—"),
            f"[{style}]{status}[/]",
        )

    console.print(table)


if __name__ == "__main__":
    main()

Output: A table of up to 10 departures with flight number, airline, destination airport code, scheduled time, and color-coded status (green = Departed, yellow = Delayed, red = Cancelled).


2. Delay and cancellation summary at EGLL

Question: How many flights are currently delayed or cancelled at EGLL today?

import os

import requests
from rich.console import Console
from rich.panel import Panel
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"


def fetch_departures(icao: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/schedules/departures",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("flights", [])


def main() -> None:
    flights = fetch_departures("EGLL")
    if not flights:
        console.print("[yellow]No departure data returned for EGLL.[/]")
        return

    delayed = [f for f in flights if f.get("Status") == "Delayed"]
    cancelled = [f for f in flights if f.get("Status") == "Cancelled"]
    on_time = len(flights) - len(delayed) - len(cancelled)

    summary = (
        f"Total departures: [bold]{len(flights)}[/]\n"
        f"On time / departed: [green]{on_time}[/]\n"
        f"Delayed: [yellow]{len(delayed)}[/]\n"
        f"Cancelled: [red]{len(cancelled)}[/]"
    )
    console.print(Panel(summary, title="EGLL Departure Summary"))

    if delayed or cancelled:
        table = Table(title="Delayed and Cancelled Flights")
        table.add_column("Flight", style="cyan")
        table.add_column("Airline")
        table.add_column("Time")
        table.add_column("Status")

        for f in delayed:
            table.add_row(
                f.get("Flight", "—"),
                f.get("Airline", "—"),
                f.get("Time", "—"),
                "[yellow]Delayed[/]",
            )
        for f in cancelled:
            table.add_row(
                f.get("Flight", "—"),
                f.get("Airline", "—"),
                f.get("Time", "—"),
                "[red]Cancelled[/]",
            )

        console.print(table)


if __name__ == "__main__":
    main()

Output: A summary panel with total, on-time, delayed, and cancelled counts, followed by a table listing each affected flight with airline, time, and status.


3. Side-by-side arrivals and departures at KJFK

Question: How do today's total arrivals and departures compare at KJFK, including disruption counts?

Fetches both directions concurrently to reduce wall-clock time.

import os
import concurrent.futures

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"


def fetch_schedule(icao: str, direction: str) -> list[dict]:
    r = requests.get(
        f"{BASE}/schedules/{direction}",
        headers=HEADERS,
        params={"icao": icao},
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return []
    r.raise_for_status()
    return r.json().get("flights", [])


def summarize(flights: list[dict]) -> dict[str, int]:
    delayed = sum(1 for f in flights if f.get("Status") == "Delayed")
    cancelled = sum(1 for f in flights if f.get("Status") == "Cancelled")
    return {
        "total": len(flights),
        "delayed": delayed,
        "cancelled": cancelled,
        "on_time": len(flights) - delayed - cancelled,
    }


def main() -> None:
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as ex:
        fut_arr = ex.submit(fetch_schedule, "KJFK", "arrivals")
        fut_dep = ex.submit(fetch_schedule, "KJFK", "departures")
        arrivals = fut_arr.result()
        departures = fut_dep.result()

    arr_stats = summarize(arrivals)
    dep_stats = summarize(departures)

    table = Table(title="KJFK Traffic Summary — Today")
    table.add_column("Direction", style="cyan")
    table.add_column("Total", justify="right")
    table.add_column("Delayed", justify="right")
    table.add_column("Cancelled", justify="right")
    table.add_column("On Time", justify="right")

    table.add_row(
        "Arrivals",
        str(arr_stats["total"]),
        f"[yellow]{arr_stats['delayed']}[/]",
        f"[red]{arr_stats['cancelled']}[/]",
        f"[green]{arr_stats['on_time']}[/]",
    )
    table.add_row(
        "Departures",
        str(dep_stats["total"]),
        f"[yellow]{dep_stats['delayed']}[/]",
        f"[red]{dep_stats['cancelled']}[/]",
        f"[green]{dep_stats['on_time']}[/]",
    )

    console.print(table)


if __name__ == "__main__":
    main()

Output: A two-row table comparing arrivals and departures at KJFK: total flight count, delayed, cancelled, and on-time counts side by side.