Carbon labels

Runnable examples for estimating flight CO₂ emissions per passenger and across route sets. See the Carbon Emissions reference for methodology details and RFI guidance.

#QuestionData used
1Calculate CO₂ per passenger for KJFK → KLAX on B738GET /carbon/estimate
2Build a carbon label for a flight search resultGET /carbon/estimate
3Compare CO₂ across 3 transatlantic routes from EGLLGET /carbon/estimate

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. CO₂ per passenger: KJFK → KLAX on B738

Question: How much CO₂ does a single passenger produce on a B738 flight from New York to Los Angeles?

The estimate follows ICAO Doc 9988 methodology. By default, RFI is not applied — pass include_rfi=true for a climate-adjusted figure (roughly 2× the base CO₂).

import os

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

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_carbon(
    departure_icao: str,
    arrival_icao: str,
    aircraft_type: str | None = None,
    passengers: int = 1,
    include_rfi: bool = False,
) -> dict | None:
    params: dict[str, str | int | bool] = {
        "departure_icao": departure_icao,
        "arrival_icao": arrival_icao,
        "passengers": passengers,
        "include_rfi": str(include_rfi).lower(),
    }
    if aircraft_type:
        params["aircraft_type"] = aircraft_type
    r = requests.get(
        f"{BASE}/carbon/estimate",
        headers=HEADERS,
        params=params,
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def main() -> None:
    data = fetch_carbon("KJFK", "KLAX", aircraft_type="B738", passengers=1)
    if not data:
        console.print("[red]No carbon estimate returned.[/red]")
        return

    co2_pax = data.get("co2_kg_per_passenger", 0.0)
    co2_total = data.get("co2_kg_total", 0.0)
    rfi = data.get("rfi_applied", False)

    body = (
        f"Route:           [bold]{data.get('departure_icao')} → "
        f"{data.get('arrival_icao')}[/bold]\n"
        f"Aircraft:        {data.get('aircraft_type', '—')}\n"
        f"Distance:        {data.get('distance_nm', 0):,.1f} nm\n"
        f"CO₂/passenger:   [bold green]{co2_pax:.1f} kg[/bold green]  "
        f"({co2_pax / 1000:.3f} t)\n"
        f"CO₂ total load:  {co2_total:,.1f} kg\n"
        f"Methodology:     {data.get('methodology', 'ICAO Doc 9988')}\n"
        f"RFI applied:     {'Yes' if rfi else 'No'}"
    )

    console.print(Panel(body, title="Carbon Estimate", style="green"))
    console.print(
        "[dim]Use include_rfi=true for climate-adjusted estimates "
        "(applies ~2× multiplier per ICAO guidance).[/dim]"
    )


if __name__ == "__main__":
    main()

Output: A panel showing route, aircraft, distance, CO₂ per passenger in kg and tonnes, total aircraft load, methodology, and RFI flag.


2. Carbon label for a flight search result

Question: What carbon label category should be shown for a passenger on EGLL → KJFK on an A380?

Categorise the per-passenger CO₂ figure into LOW / MEDIUM / HIGH / VERY HIGH for display in a ticket search UI.

import os

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

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_carbon(
    departure_icao: str,
    arrival_icao: str,
    aircraft_type: str | None = None,
    passengers: int = 1,
    include_rfi: bool = False,
) -> dict | None:
    params: dict[str, str | int] = {
        "departure_icao": departure_icao,
        "arrival_icao": arrival_icao,
        "passengers": passengers,
        "include_rfi": str(include_rfi).lower(),
    }
    if aircraft_type:
        params["aircraft_type"] = aircraft_type
    r = requests.get(
        f"{BASE}/carbon/estimate",
        headers=HEADERS,
        params=params,
        timeout=(10, 15),
    )
    if r.status_code == 404:
        return None
    r.raise_for_status()
    return r.json()


def co2_category(kg: float) -> tuple[str, str]:
    """Return (label, rich color) based on per-passenger kg thresholds."""
    if kg < 50:
        return "LOW", "green"
    if kg < 150:
        return "MEDIUM", "yellow"
    if kg < 400:
        return "HIGH", "orange3"
    return "VERY HIGH", "red"


def main() -> None:
    data = fetch_carbon(
        "EGLL", "KJFK", aircraft_type="A388", passengers=1, include_rfi=False
    )
    if not data:
        console.print("[red]No carbon estimate returned.[/red]")
        return

    co2_pax = data.get("co2_kg_per_passenger", 0.0)
    label, color = co2_category(co2_pax)
    route = f"{data.get('departure_icao')} → {data.get('arrival_icao')}"

    body = (
        f"[bold]{route}[/bold]  ·  {data.get('aircraft_type', '—')}\n\n"
        f"CO₂ per passenger:  [bold {color}]{co2_pax:.1f} kg[/bold {color}]\n"
        f"Carbon category:    [bold {color}]{label}[/bold {color}]\n\n"
        f"[dim]< 50 kg = LOW  |  50–150 kg = MEDIUM  |  "
        f"150–400 kg = HIGH  |  > 400 kg = VERY HIGH[/dim]"
    )

    console.print(Panel(body, title="Carbon Label", style=color))


if __name__ == "__main__":
    main()

Output: A colour-coded carbon label panel showing the route, CO₂ per passenger in kg, and the category (LOW / MEDIUM / HIGH / VERY HIGH) — mirroring what a ticket search UI would display.


3. Transatlantic route CO₂ comparison from EGLL

Question: Which transatlantic route from London produces the least CO₂ per passenger?

Fetch three routes concurrently and rank by per-passenger CO₂ ascending. Shorter distances and newer aircraft types generally produce less CO₂.

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"

ROUTES = [
    ("EGLL", "KJFK", "A388"),
    ("EGLL", "KEWR", "B77W"),
    ("EGLL", "KBOS", "B738"),
]


def fetch_carbon(
    departure: str, arrival: str, aircraft: str
) -> tuple[str, str, str, dict | None]:
    try:
        r = requests.get(
            f"{BASE}/carbon/estimate",
            headers=HEADERS,
            params={
                "departure_icao": departure,
                "arrival_icao": arrival,
                "aircraft_type": aircraft,
                "passengers": 1,
                "include_rfi": "false",
            },
            timeout=(10, 15),
        )
        if r.status_code == 404:
            return departure, arrival, aircraft, None
        r.raise_for_status()
        return departure, arrival, aircraft, r.json()
    except Exception as exc:  # noqa: BLE001
        console.print(f"[red]{departure}→{arrival}: {exc}[/red]")
        return departure, arrival, aircraft, None


def main() -> None:
    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as pool:
        results = list(pool.map(lambda r: fetch_carbon(*r), ROUTES))

    valid = [
        (dep, arr, ac, d)
        for dep, arr, ac, d in results
        if d and d.get("co2_kg_per_passenger") is not None
    ]
    valid.sort(key=lambda x: x[3].get("co2_kg_per_passenger", 0))

    table = Table(title="Transatlantic CO₂ Comparison (1 passenger, no RFI)", show_lines=True)
    table.add_column("Route", style="cyan", no_wrap=True)
    table.add_column("Aircraft", justify="center")
    table.add_column("Distance (nm)", justify="right")
    table.add_column("CO₂/pax (kg)", justify="right", style="bold")

    for i, (dep, arr, ac, d) in enumerate(valid):
        distance = d.get("distance_nm")
        dist_str = f"{distance:,.0f}" if distance else "—"
        co2 = d.get("co2_kg_per_passenger", 0.0)
        star = " ★" if i == 0 else ""
        table.add_row(
            f"{dep} → {arr}",
            ac,
            dist_str,
            f"{co2:.1f}{star}",
        )

    console.print(table)
    console.print(
        "[dim]★ = lowest CO₂/pax. Shorter routes and newer aircraft types "
        "generally produce less CO₂ per passenger.[/dim]"
    )


if __name__ == "__main__":
    main()

Output: A table sorted by CO₂ per passenger ascending, with the lowest-emission option marked ★. Shows route, aircraft type, distance, and per-passenger CO₂ in kilograms.