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.
| # | Question | Data used |
|---|---|---|
| 1 | Calculate CO₂ per passenger for KJFK → KLAX on B738 | GET /carbon/estimate |
| 2 | Build a carbon label for a flight search result | GET /carbon/estimate |
| 3 | Compare CO₂ across 3 transatlantic routes from EGLL | GET /carbon/estimate |
Requirements
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 rich1. 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.