Single Flight Detail

Get full metadata and the complete position track for a specific archived flight. Both endpoints require a flight_id UUID from flight history search — they are step 2 in the same workflow. Plan tiers: Historical ADS-B hub.

Requirements

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

Pro, Ultra, or Mega — use the path prefix that matches the window you need.

Learn more →

Single flight detail

Returns enriched metadata beyond search results — off-block/on-block times, arrival proximity, and audit timestamps. Block time is gate-to-gate time including taxi; off-block = gate departure, on-block = gate arrival. Takeoff and landing are wheels-up/wheels-down events, distinct from off-block/on-block.

Request

GEThttps://data.skylinkapi.com/v3.1/ultra/history/flight/{flight_id}
ParameterTypeRequiredDescription
flight_idstringYesFlight UUID from flight history search
MEGA path (`/mega/history/...`)Expand section
GEThttps://data.skylinkapi.com/v3.1/mega/history/flight/{flight_id}

Same parameters and response shape as ULTRA. Requires Ultra or Mega plan. flight_id values are interchangeable across tiers.

Response

{
  "flight_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "icao24": "40621d",
  "callsign": "BAW178",
  "flight_number": "BAW178",
  "tail_number": "G-XWBA",
  "aircraft_type_icao": "B77W",
  "aircraft_type_name": "Boeing 777-300ER",
  "airline_icao": "BAW",
  "airline_iata": "BA",
  "airline_name": "British Airways",
  "departure_airport_icao": "EGLL",
  "departure_airport_iata": "LHR",
  "departure_airport_name": "London Heathrow Airport",
  "arrival_airport_icao": "KJFK",
  "arrival_airport_iata": "JFK",
  "arrival_airport_name": "John F Kennedy International Airport",
  "flight_state": "ARCHIVED",
  "flight_start": "2026-05-12T19:42:05Z",
  "flight_end": "2026-05-13T03:11:10Z",
  "takeoff_time": "2026-05-12T19:45:00Z",
  "landing_time": "2026-05-13T03:08:00Z",
  "off_block_time": null,
  "on_block_time": null,
  "flight_duration_min": 443.0,
  "duration_source": "estimated",
  "distance_nm": 2998.4,
  "arrival_distance_nm": 2.1,
  "confidence": 1.0,
  "route_source": "vrs_confirmed",
  "gps_spoofing_suspected": false,
  "diversion_suspected": false,
  "created_at": "2026-05-12T19:40:00Z",
  "updated_at": "2026-05-13T03:15:00Z"
}

Returns the same core fields as a flight summary plus detail-only enrichment when available.

FieldTypeRequiredNull?Description
(all flight summary fields)---Same shape as search results
off_block_timestring | nullNoYesOff-block time when known (ISO 8601)
on_block_timestring | nullNoYesOn-block time when known (ISO 8601)
duration_sourcestring | nullNoYesHow duration was computed — when "estimated", block time was inferred from position data rather than recorded gate events (important for ESG or delay-reporting workflows)
arrival_distance_nmnumber | nullNoYesDistance from last position to arrival airport (nm)
created_atstring | nullNoYesWhen the archive record was created (ISO 8601)
updated_atstring | nullNoYesWhen the archive record was last updated (ISO 8601)

Client types

"""Typed models for Historical ADS-B - matches historical-adsb.mdx field tables."""from __future__ import annotationsfrom dataclasses import dataclassfrom typing import Literal@dataclassclass HistoricalFlightSummary:    flight_id: str    icao24: str | None    callsign: str | None    flight_number: str | None    tail_number: str | None    departure_airport_icao: str | None    arrival_airport_icao: str | None    flight_start: str    flight_end: str    takeoff_time: str | None    landing_time: str | None    flight_duration_min: float | None    distance_nm: float | None@dataclassclass HistoricalPosition:    timestamp: str    icao24: str    latitude: float    longitude: float    altitude_baro: float | None    ground_speed: float | None    track: float | None    vertical_rate: float | None    is_on_ground: bool@dataclassclass HistoricalFlightWindow:    flight_id: str    callsign: str | None    departure_airport_icao: str | None    arrival_airport_icao: str | None    takeoff_time: str | None    landing_time: str | None    flight_start: str    flight_end: str    flight_state: str | None@dataclassclass AirportTrafficFlight:    flight_id: str    icao24: str | None    callsign: str | None    departure_airport_icao: str | None    arrival_airport_icao: str | None    takeoff_time: str | None    landing_time: str | None    flight_duration_min: float | None    distance_nm: float | None@dataclassclass AirportTrafficResponse:    icao: str    direction: Literal["dep", "arr", "both"]    count: int    flights: list[AirportTrafficFlight]

Integration

Fetch enriched metadata for a single archived flight — off-block/on-block times, arrival proximity, and audit timestamps. The example below chains from a flight search result: it takes the first flight_id and fetches full detail, then maps gate times into a display object with a fallback when block times are null.

import osimport requestsBASE = "https://data.skylinkapi.com/v3.1"HEADERS = {    "x-api-key": os.getenv("SKYLINK_API_KEY") or os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}def fetch_flight_detail(flight_id: str, *, tier: str = "ultra") -> dict:    r = requests.get(        f"{BASE}/{tier}/history/flight/{flight_id}",        headers=HEADERS,        timeout=(10, 25),    )    r.raise_for_status()    return r.json()def search_one_flight(*, callsign: str = "BAW178", tier: str = "ultra") -> dict | None:    r = requests.get(        f"{BASE}/{tier}/history/flights",        headers=HEADERS,        params={"callsign": callsign, "limit": 1},        timeout=(10, 25),    )    r.raise_for_status()    flights = r.json().get("flights") or []    return flights[0] if flights else Noneif __name__ == "__main__":    import json    hit = search_one_flight()    if not hit:        print("No flight found")    else:        detail = fetch_flight_detail(hit["flight_id"])        print(json.dumps({"callsign": detail.get("callsign"), "flight_id": detail.get("flight_id"), "route": [detail.get("departure_airport_icao"), detail.get("arrival_airport_icao")]}, indent=2))

Implementation notes

Chain from search. Always obtain flight_id from Flight History Search first — guessing UUIDs returns 404. Detail and search use the same tier path (/ultra/... or /mega/...).

Block times vs takeoff/landing. off_block_time and on_block_time are gate events; takeoff_time and landing_time are wheels-up/wheels-down. Both may be null when ADS-B coverage was incomplete near the gate.

Raw position history. For a time-bounded timeline without flight segmentation, see Position History.

Error responses

Plan-gate 401/403: Historical ADS-B hub. Endpoint-specific:

404 — flight not found

{
  "detail": "Flight not found"
}

Returned when flight_id is not in the archive (unknown UUID, outside retention, or typo). Search again with a narrower window — see Flight History Search.

GET
/ultra/history/flight/{flight_id}
x-api-key<token>

Your SkyLink licence key, for keys bought direct from skylinkapi.com.

In: header

Path Parameters

flight_id*Flight Id

Response Body

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/ultra/history/flight/00000000-0000-0000-0000-000000000001"
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}
GET
/mega/history/flight/{flight_id}
x-api-key<token>

Your SkyLink licence key, for keys bought direct from skylinkapi.com.

In: header

Path Parameters

flight_id*Flight Id

Response Body

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/mega/history/flight/00000000-0000-0000-0000-000000000001"
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}

Flight track

Returns the full ADS-B position track for a specific flight, automatically bounded to its takeoff → landing window (5-minute pad on each side). Use this when you have a flight_id from search and want the path without computing the time window yourself.

Request

GEThttps://data.skylinkapi.com/v3.1/ultra/history/flight/{flight_id}/track
ParameterTypeRequiredDefaultDescription
flight_idstringYes-Flight UUID from search
limitintegerNo2000Max position rows (max 5,000 on ULTRA path)
MEGA path (`/mega/history/...`)Expand section
GEThttps://data.skylinkapi.com/v3.1/mega/history/flight/{flight_id}/track
ParameterTypeRequiredDefaultDescription
flight_idstringYes-Flight UUID
limitintegerNo5000Max positions (max 10,000 on MEGA path)

Requires Ultra or Mega plan. Same response shape as ULTRA.

Response

{
  "flight_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "icao24": "40621d",
  "callsign": "BAW178",
  "registration": "G-XWBA",
  "aircraft_type_icao": "B77W",
  "departure_airport_icao": "EGLL",
  "departure_airport_iata": "LHR",
  "arrival_airport_icao": "KJFK",
  "arrival_airport_iata": "JFK",
  "takeoff_time": "2026-05-12T19:45:00Z",
  "landing_time": "2026-05-13T03:08:00Z",
  "count": 1287,
  "positions": [
    {
      "timestamp": "2026-05-13T03:08:05Z",
      "icao24": "40621d",
      "latitude": 40.6413,
      "longitude": -73.7781,
      "altitude_baro": 0,
      "ground_speed": 12,
      "track": 90,
      "vertical_rate": 0,
      "callsign": "BAW178",
      "is_on_ground": true,
      "registration": "G-XWBA",
      "aircraft_type": "B77W",
      "gps_spoofed": false
    }
  ]
}
FieldTypeRequiredNull?Description
flight_idstringYesNeverFlight UUID
icao24string | nullNoYesAircraft hex
callsignstring | nullNoYesADS-B callsign
registrationstring | nullNoYesTail number when known
aircraft_type_icaostring | nullNoYesICAO type code
departure_airport_icaostring | nullNoYesDeparture airport ICAO
departure_airport_iatastring | nullNoYesDeparture airport IATA
arrival_airport_icaostring | nullNoYesArrival airport ICAO
arrival_airport_iatastring | nullNoYesArrival airport IATA
takeoff_timestring | nullNoYesTakeoff time bounding the track (ISO 8601)
landing_timestring | nullNoYesLanding time bounding the track (ISO 8601)
countintegerYesNeverNumber of items in positions
positionsarrayYesNeverPosition snapshots (newest-first)

Position snapshot (positions[])

Same field names as live ADS-B positions. JSON path: positions[].

FieldTypeRequiredNull?Description
timestampstringYesNeverObservation time (ISO 8601)
icao24stringYesNeverAircraft hex
latitudenumberYesNeverWGS-84 latitude (decimal degrees)
longitudenumberYesNeverWGS-84 longitude (decimal degrees)
altitude_baronumber | nullNoYesBarometric altitude in feet MSL
ground_speednumber | nullNoYesGround speed in knots
tracknumber | nullNoYesTrack heading in degrees true
vertical_ratenumber | nullNoYesVertical rate in feet per minute
callsignstring | nullNoYesADS-B callsign at this snapshot
is_on_groundbooleanYesNevertrue when the aircraft was on the ground
registrationstring | nullNoYesTail number when known
aircraft_typestring | nullNoYesICAO type code when known
gps_spoofedboolean | nullNoYesWhether this snapshot was flagged as GPS-spoofed

Track integration

Replay a gate-to-gate position track for map display. The example below chains from a search result: it takes a flight_id, fetches the track with a 45-second read timeout (large tracks can be slow), downsamples to every 5th position for web map performance, and handles 404 when a flight falls outside the retention window.

import osimport requestsBASE = "https://data.skylinkapi.com/v3.1"HEADERS = {    "x-api-key": os.getenv("SKYLINK_API_KEY") or os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}def fetch_flight_track(flight_id: str, *, tier: str = "ultra") -> dict:    r = requests.get(        f"{BASE}/{tier}/history/flight/{flight_id}/track",        headers=HEADERS,        timeout=(10, 30),    )    r.raise_for_status()    return r.json()def search_one_flight(*, callsign: str = "BAW178", tier: str = "ultra") -> dict | None:    r = requests.get(        f"{BASE}/{tier}/history/flights",        headers=HEADERS,        params={"callsign": callsign, "limit": 1},        timeout=(10, 25),    )    r.raise_for_status()    flights = r.json().get("flights") or []    return flights[0] if flights else Noneif __name__ == "__main__":    import json    hit = search_one_flight()    if not hit:        print("No flight found")    else:        track = fetch_flight_track(hit["flight_id"])        print(json.dumps({"count": track.get("count"), "positions": len(track.get("positions") or [])}, indent=2))

Important: Track and position history return positions newest-first. Reverse chronologically for map replay. At 5-second sampling, a 10-hour flight is ~7,200 points — downsample for web maps.

GET
/ultra/history/flight/{flight_id}/track
x-api-key<token>

Your SkyLink licence key, for keys bought direct from skylinkapi.com.

In: header

Path Parameters

flight_id*Flight Id

Query Parameters

limit?Limit

Max position rows (default 2000, max 5000)

Default2000
Range1 <= value <= 5000

Response Body

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/ultra/history/flight/00000000-0000-0000-0000-000000000001/track"
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}
GET
/mega/history/flight/{flight_id}/track
x-api-key<token>

Your SkyLink licence key, for keys bought direct from skylinkapi.com.

In: header

Path Parameters

flight_id*Flight Id

Query Parameters

limit?Limit

Max position rows (default 5000, max 10000)

Default5000
Range1 <= value <= 10000

Response Body

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/mega/history/flight/00000000-0000-0000-0000-000000000001/track"
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}