Error handling
Caching and monitoring: Caching & monitoring.
Platform errors (401, 403, 422, 429, 5xx, retry/backoff, rate-limit headers): Error Handling.
Flight time: 422 — unrecognised airport codes
GET /ml/flight-time validates that both from and to resolve to known airports. An unknown or malformed code returns 422 with a detail message identifying which code failed.
| Code | Meaning | Fix |
|---|---|---|
422 | from or to not recognised | Use a valid ICAO (4-letter, e.g. KJFK) or IATA (3-letter, e.g. JFK) code. Resolve via Airport Search. |
404 | No route data for this pair | The model lacks enough historical data for this city pair. Show "Estimate unavailable." |
Note: The result is a statistical average derived from historical operational data — not a real-time forecast. Wind and live en-route conditions are not model inputs. Disclose this when presenting estimates to passengers or schedulers.
import os
import requests
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_flight_time(origin: str, destination: str, aircraft: str | None = None) -> dict | None:
"""
Fetch ML flight time estimate. Returns None on 404 (no data for pair).
Raises ValueError on 422 (invalid airport code).
"""
params: dict[str, str] = {"from": origin, "to": destination}
if aircraft:
params["aircraft"] = aircraft
r = requests.get(
f"{BASE}/ml/flight-time",
headers=HEADERS,
params=params,
timeout=(10, 15),
)
if r.status_code == 404:
return None
if r.status_code == 422:
detail = r.json().get("detail", "invalid airport code")
raise ValueError(f"422 Unprocessable: {detail}")
r.raise_for_status()
return r.json()
# Valid request — KJFK to KLAX
if __name__ == "__main__":
data = fetch_flight_time("KJFK", "KLAX", aircraft="B738")
if data:
print(
f"Estimated: {data['estimated_hours_display']} "
f"({data['min_minutes']}–{data['max_minutes']} min range)"
)
print("Statistical average — actual time varies with winds and routing.")
else:
print("No estimate available for this route.")
try:
fetch_flight_time("ZZZZ", "KLAX")
except ValueError as exc:
print(f"Caught expected error: {exc}")Carbon: 422 — missing required parameters
GET /carbon/estimate requires either an airport pair (departure_icao + arrival_icao) or a callsign. Omitting both returns 422.
| Code | Meaning | Fix |
|---|---|---|
422 | Neither airport pair nor callsign supplied | Provide departure_icao + arrival_icao, or a callsign. |
422 | Unrecognised airport code | Ensure ICAO codes are valid 4-letter identifiers. Resolve via Airport Search. |
404 | No emissions data for this pair | Route is outside model coverage. Show "Estimate unavailable." |
RFI disclosure: Passing include_rfi=true applies a Radiative Forcing Index multiplier (~2×) to the base CO₂ figure. When rfi_applied: true appears in the response, disclose in the UI that the displayed figure includes climate-forcing effects beyond CO₂ alone (per ICAO Doc 9988 guidance).
import os
import requests
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 | None = None,
arrival_icao: str | None = None,
callsign: str | None = None,
passengers: int = 1,
include_rfi: bool = False,
) -> dict | None:
"""
Fetch carbon estimate. Requires departure_icao+arrival_icao or callsign.
Returns None on 404. Raises ValueError on 422.
"""
params: dict[str, str | int] = {
"passengers": passengers,
"include_rfi": str(include_rfi).lower(),
}
if departure_icao:
params["departure_icao"] = departure_icao
if arrival_icao:
params["arrival_icao"] = arrival_icao
if callsign:
params["callsign"] = callsign
r = requests.get(
f"{BASE}/carbon/estimate",
headers=HEADERS,
params=params,
timeout=(10, 15),
)
if r.status_code == 404:
return None
if r.status_code == 422:
detail = r.json().get("detail", "validation error")
raise ValueError(f"422 Unprocessable: {detail}")
r.raise_for_status()
return r.json()
# 1. Attempt without required params — expect 422
if __name__ == "__main__":
try:
fetch_carbon()
except ValueError as exc:
print(f"Missing params error: {exc}")
data = fetch_carbon(departure_icao="KJFK", arrival_icao="KLAX", passengers=1)
if data:
co2 = data.get("co2_kg_per_passenger", 0.0)
rfi = data.get("rfi_applied", False)
print(f"CO₂/passenger: {co2:.1f} kg (RFI applied: {rfi})")
if rfi:
print(
"Disclosure: figure includes radiative forcing effects "
"(~2× base CO₂, ICAO Doc 9988)."
)
else:
print("No estimate available for this route.")For transient failures (429, 5xx), use the retry helper on Error Handling.
Related: Flight Time · Carbon Emissions · Caching & monitoring · Error Handling