Flight History Search

Search archived flights by tail number, callsign (flight callsign broadcast on ADS-B, e.g. BAW178), route, or hex code, and receive a list of flights with flight_id UUIDs. At least one filter is required. This is the mandatory first step in any historical ADS-B workflow — without a flight_id from search, the detail and track endpoints cannot be called.

Plan tiers and path-prefix rules: 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 (see hub comparison table).

Learn more →

Request

GEThttps://data.skylinkapi.com/v3.1/ultra/history/flights
ParameterTypeRequiredDefaultDescription
startstringNo24 h agoStart of query window — ISO 8601 datetime
endstringNonowEnd of query window — ISO 8601 datetime
icao24stringOne filter required-ICAO24 hex address (6 characters)
registrationstringOne filter required-Tail number (e.g. N12345, G-XWBA). Resolved to icao24 server-side
callsignstringOne filter required-Exact callsign match (e.g. BAW117)
departure_icaostringOne filter required-Departure airport ICAO (4 characters)
arrival_icaostringOne filter required-Arrival airport ICAO (4 characters)
limitintegerNo100Max flights returned (max 1,000 on ULTRA path)

If both registration and icao24 are supplied, they must refer to the same aircraft. On the ULTRA path the query window cannot exceed 90 days.

MEGA path (`/mega/history/...`)Expand section
GEThttps://data.skylinkapi.com/v3.1/mega/history/flights
ParameterTypeRequiredDefaultDescription
startstringNo24 h agoWindow start — ISO 8601 (max 365 days span on MEGA path)
endstringNonowWindow end — ISO 8601
icao24stringOne filter required-ICAO24 hex (6 characters)
registrationstringOne filter required-Tail number
callsignstringOne filter required-Exact callsign
departure_icaostringOne filter required-Departure ICAO
arrival_icaostringOne filter required-Arrival ICAO
limitintegerNo200Max flights (max 2,000 on MEGA path)

Requires Ultra or Mega RapidAPI plan. Same parameters and response shape as ULTRA — only window and limit caps differ. See the hub comparison table.

Response

{
  "filters": {
    "icao24": null,
    "registration": null,
    "resolved_icao24": null,
    "callsign": null,
    "departure_icao": "EGLL",
    "arrival_icao": null
  },
  "count": 1,
  "flights": [
    {
      "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",
      "flight_duration_min": 443.0,
      "distance_nm": 2998.4,
      "confidence": 1.0,
      "route_source": "vrs_confirmed",
      "gps_spoofing_suspected": false,
      "diversion_suspected": false
    }
  ]
}
FieldTypeRequiredDescription
filtersobjectYesEcho of applied search filters (see below)
countintegerYesNumber of items in flights
flightsarrayYesMatching flight summaries (may be empty)

Applied filters (filters)

FieldTypeRequiredNull?Description
icao24string | nullYesYesQueried ICAO24 hex, if any
registrationstring | nullYesYesQueried tail number, if any
resolved_icao24string | nullYesYesICAO24 resolved from registration, if supplied
callsignstring | nullYesYesQueried callsign, if any
departure_icaostring | nullYesYesQueried departure airport, if any
arrival_icaostring | nullYesYesQueried arrival airport, if any

Flight summary (flights[])

FieldTypeRequiredNull?Description
flight_idstringYesNeverUUID for detail and track lookups
icao24string | nullNoYesAircraft hex when known
callsignstring | nullNoYesADS-B callsign during the flight
flight_numberstring | nullNoYesNormalized flight number when resolved
tail_numberstring | nullNoYesTail number when known
aircraft_type_icaostring | nullNoYesICAO type code (e.g. B77W)
aircraft_type_namestring | nullNoYesHuman-readable aircraft type
airline_icaostring | nullNoYesAirline ICAO code
airline_iatastring | nullNoYesAirline IATA code
airline_namestring | nullNoYesAirline display name
departure_airport_icaostring | nullNoYesDeparture airport ICAO when resolved
departure_airport_iatastring | nullNoYesDeparture airport IATA
departure_airport_namestring | nullNoYesDeparture airport name
arrival_airport_icaostring | nullNoYesArrival airport ICAO when resolved
arrival_airport_iatastring | nullNoYesArrival airport IATA
arrival_airport_namestring | nullNoYesArrival airport name
flight_statestring | nullNoYesArchive state (e.g. ARCHIVED)
flight_startstringYesNeverFirst archived observation (ISO 8601)
flight_endstringYesNeverLast archived observation (ISO 8601)
takeoff_timestring | nullNoYesEstimated or detected takeoff (ISO 8601)
landing_timestring | nullNoYesEstimated or detected landing (ISO 8601)
flight_duration_minnumber | nullNoYesGate-to-gate duration in minutes
distance_nmnumber | nullNoYesGreat-circle distance in nautical miles
confidencenumber | nullNoYesRoute confidence score (0–1)
route_sourcestring | nullNoYesOpaque enum describing how the route was resolved — treat as a display value, not a key to match on
gps_spoofing_suspectedboolean | nullNoYesWhether GPS spoofing was flagged for this flight
diversion_suspectedboolean | nullNoYesWhether a route diversion was flagged for this flight

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

The typical workflow is search → detail (metadata) or search → track (map replay). Search with at least one filter, take a flight_id from the results, then call detail or track.

The example below searches by departure airport, fetches full metadata for the first match, and uses connect/read timeouts so batch jobs cannot hang indefinitely. On plans without Historical ADS-B access, handle gateway 401/403 before parsing JSON — see hub → Error responses.

import osimport requestsBASE = "https://data.skylinkapi.com/v3.1"HEADERS = {    "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}PLAN_GATED = {401, 403}def search_historical_flights(    *,    registration: str | None = None,    callsign: str | None = None,    icao24: str | None = None,    departure_icao: str | None = None,    arrival_icao: str | None = None,    start: str | None = None,    end: str | None = None,    limit: int = 10,    tier: str = "ultra",) -> dict:    """Search archived flights - at least one aircraft/route filter is required."""    params = {k: v for k, v in {        "registration": registration,        "callsign": callsign,        "icao24": icao24,        "departure_icao": departure_icao,        "arrival_icao": arrival_icao,        "start": start,        "end": end,        "limit": limit,    }.items() if v is not None}    r = requests.get(        f"{BASE}/{tier}/history/flights",        headers=HEADERS,        params=params,        timeout=(10, 25),    )    r.raise_for_status()    return r.json()def fetch_historical_flight_detail(flight_id: str, *, tier: str = "ultra") -> dict:    """Fetch full metadata for one archived flight by UUID."""    r = requests.get(        f"{BASE}/{tier}/history/flight/{flight_id}",        headers=HEADERS,        timeout=(10, 25),    )    r.raise_for_status()    return r.json()def search_then_detail(    *,    departure_icao: str,    limit: int = 1,    tier: str = "ultra",) -> dict | None:    """Search → pick first match → return full flight detail."""    search = search_historical_flights(        departure_icao=departure_icao,        limit=limit,        tier=tier,    )    flights = search.get("flights") or []    if not flights:        return None    return fetch_historical_flight_detail(flights[0]["flight_id"], tier=tier)if __name__ == "__main__":    import json    detail = search_then_detail(departure_icao="EGLL")    print(json.dumps(detail, indent=2, default=str) if detail else "No matching flight found")

Implementation notes

Pick the right path prefix. Use /ultra/history/... on Pro+ when a 90-day window is enough. Use /mega/history/... on Ultra/Mega when you need up to 365 days or higher per-request limits.

Chain by flight_id. Never guess time windows for track replay — search first, then call /history/flight/{flight_id}/track for an auto-bounded path.

Paginate large windows. If count equals your requested limit, narrow the start/end window or raise limit (within tier caps) and merge client-side.

Registration vs hex. Prefer registration when your users know tail numbers; use icao24 when ingesting raw ADS-B feeds.

Error responses

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

422 — no search filter

At least one of icao24, registration, callsign, departure_icao, or arrival_icao is required:

{
  "detail": [
    {
      "type": "value_error",
      "loc": ["query"],
      "msg": "At least one filter (icao24, registration, callsign, departure_icao, arrival_icao) is required"
    }
  ]
}

422 — window too wide

Returned when start/end span exceeds the path maximum — 90 days on /ultra/history/... or 365 days on /mega/history/...:

{
  "detail": "Query window exceeds maximum of 90 days for your plan on /ultra/history/..."
}

422 — registration and ICAO24 mismatch

When both identifiers are supplied but refer to different aircraft:

{
  "detail": "registration and icao24 refer to different aircraft"
}
GET
/ultra/history/flights
x-api-key<token>

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

In: header

Query Parameters

start?|

Start datetime ISO 8601. Defaults to 24 h ago.

end?|

End datetime ISO 8601. Defaults to now.

icao24?|

Filter by ICAO24 hex (6 chars)

registration?|

Filter by aircraft registration / tail number (e.g. 'N12345')

callsign?|

Filter by callsign (exact match, e.g. 'BAW123')

departure_icao?|

Filter by departure airport ICAO (4 chars)

arrival_icao?|

Filter by arrival airport ICAO (4 chars)

limit?Limit

Max records (default 100, max 1000)

Default100
Range1 <= value <= 1000

Response Body

application/json

application/json

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

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

In: header

Query Parameters

start?|

Start datetime ISO 8601. Defaults to 24 h ago.

end?|

End datetime ISO 8601. Defaults to now.

icao24?|

Filter by ICAO24 hex (6 chars)

registration?|

Filter by aircraft registration / tail number (e.g. 'N12345')

callsign?|

Filter by callsign (exact match, e.g. 'BAW123')

departure_icao?|

Filter by departure airport ICAO (4 chars)

arrival_icao?|

Filter by arrival airport ICAO (4 chars)

limit?Limit

Max records (default 200, max 2000)

Default200
Range1 <= value <= 2000

Response Body

application/json

application/json

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