ML Flight Time Estimation
Gate-to-gate flight time between any two airports, predicted by a GradientBoosting model trained on historical operational data (R² ≈ 0.98). Block time is the scheduled gate-to-gate duration — equivalent to gate-to-gate — including taxi at both ends.
Use this endpoint when you need block-time estimates for scheduling, connection buffers, or delay-risk dashboards without maintaining your own statistical route tables.
Provide origin and destination as ICAO or IATA codes. Pass an optional ICAO aircraft type code (B738, A320, B77W) for a tighter estimate; when omitted, the model uses typical jet cruise parameters for the city pair. The API returns a point estimate, min/max bounds, and a human-readable duration string.
Important: Wind and live en-route weather are not model inputs — the result is a statistical average for the route and aircraft category, not a forecast for a specific departure time.
Request
Requirements
x-api-key on every request (direct subscription). Learn more →https://data.skylinkapi.com/v3.1/ml/flight-time| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from | string | Yes | - | Origin airport ICAO or IATA code (3–4 characters), e.g. KSFO, SFO |
to | string | Yes | - | Destination airport ICAO or IATA code, e.g. KJFK, JFK |
aircraft | string | No | model default | ICAO aircraft type code, e.g. B738, A320, C172 |
Response
{
"origin": "KSFO",
"destination": "KJFK",
"aircraft_type": "B738",
"distance_nm": 2241.75,
"estimated_minutes": 294,
"estimated_hours_display": "4h 54m",
"min_minutes": 259,
"max_minutes": 329,
"model_version": "2.0.0-wind"
}Prediction object
| Field | Type | Required | Null? | Description |
|---|---|---|---|---|
origin | string | Yes | Never | Resolved origin ICAO code |
destination | string | Yes | Never | Resolved destination ICAO code |
aircraft_type | string | null | No | Yes | Aircraft type used for the prediction, or null when omitted |
distance_nm | number | Yes | Never | Great-circle distance in nautical miles |
estimated_minutes | integer | Yes | Never | Gate-to-gate estimate in minutes (includes average taxi at both ends) |
estimated_hours_display | string | Yes | Never | Human-readable duration, e.g. "4h 54m" |
min_minutes | integer | Yes | Never | Lower bound of the estimate range |
max_minutes | integer | Yes | Never | Upper bound of the estimate range |
model_version | string | Yes | Never | Model artifact version string |
Important: Use estimated_minutes for calculations and estimated_hours_display for passenger-facing labels. Show min_minutes–max_minutes as a range when you need uncertainty bands (connection planning, SLA buffers).
Client types
"""ML flight time response models for /ml/flight-time."""from __future__ import annotationsfrom dataclasses import dataclass@dataclassclass FlightTimeRequest: """Query input for GET /ml/flight-time.""" from_airport: str to_airport: str aircraft: str | None = None@dataclassclass FlightTimePrediction: origin: str destination: str aircraft_type: str | None distance_nm: float estimated_minutes: int estimated_hours_display: str min_minutes: int max_minutes: int model_version: strIntegration
Route planners typically cache ML flight-time results per city pair because the underlying model changes infrequently. The example below fetches a prediction, maps it to a compact view model (block_minutes, display, range), and uses explicit connect/read timeouts so a slow inference call cannot block your worker.
import osfrom dataclasses import dataclassimport requestsBASE = "https://data.skylinkapi.com/v3.1"HEADERS = { "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}@dataclassclass FlightTimeEstimate: origin: str destination: str block_minutes: int display: str min_minutes: int max_minutes: int distance_nm: floatdef fetch_flight_time(*, origin: str, destination: str, aircraft: str | None = None) -> dict: """Fetch ML gate-to-gate flight time between two airports.""" params: dict[str, str] = {"from": origin.upper(), "to": destination.upper()} if aircraft: params["aircraft"] = aircraft.upper() r = requests.get(f"{BASE}/ml/flight-time", headers=HEADERS, params=params, timeout=(10, 20)) r.raise_for_status() return r.json()def flight_time_estimate(origin: str, destination: str, aircraft: str | None = None) -> FlightTimeEstimate: data = fetch_flight_time(origin=origin, destination=destination, aircraft=aircraft) return FlightTimeEstimate( origin=data["origin"], destination=data["destination"], block_minutes=int(data["estimated_minutes"]), display=data["estimated_hours_display"], min_minutes=int(data["min_minutes"]), max_minutes=int(data["max_minutes"]), distance_nm=float(data["distance_nm"]), )if __name__ == "__main__": import json from dataclasses import asdict estimate = flight_time_estimate("KJFK", "KLAX", aircraft="B738") print(json.dumps(asdict(estimate), indent=2))Implementation notes
Aircraft type. Narrow-body codes (B738, A320) vs wide-body (B77W, A359) materially change block time on long routes — pass aircraft when your schedule row already knows the equipment.
Bounds vs point estimate. min_minutes and max_minutes bracket typical operational variance. Do not treat them as hard operational limits.
Important: If the ML model is temporarily unavailable, SkyLink may fall back to a distance/speed calculation. Check model_version when auditing predictions for ESG or scheduling workflows.
Error responses
For shared platform errors (auth, rate limits, validation envelopes), see Error Handling. Endpoint-specific behavior:
422 — invalid airport code
Returned when from or to cannot be resolved to a known airport, or when query parameters fail validation.
Your SkyLink licence key, for keys bought direct from skylinkapi.com.
In: header
Query Parameters
Origin airport ICAO or IATA code
3 <= length <= 4Destination airport ICAO or IATA code
3 <= length <= 4Aircraft type code (e.g. B738, A320, C172)
length <= 4Response Body
application/json
application/json
curl -X GET "https://data.skylinkapi.com/v3.1/ml/flight-time?from=stri&to=stri"{
"origin": "string",
"destination": "string",
"aircraft_type": "string",
"distance_nm": 0,
"estimated_minutes": 0,
"estimated_hours_display": "string",
"min_minutes": 0,
"max_minutes": 0,
"model_version": "string"
}{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string",
"input": null,
"ctx": {}
}
]
}