Save up to 17% with yearly billing

See pricing

ADS-B Aircraft Tracking

Get live aircraft positions, filter them for your map viewport, and check the ADS-B feed health. ADS-B (Automatic Dependent Surveillance–Broadcast) is the transponder signal broadcasting aircraft identity and position. Each live record includes ICAO24 (6-character hex code uniquely identifying an aircraft's transponder, e.g. 0A0022), position, barometric altitude (altitude measured by the aircraft's pressure altimeter, in feet MSL), ground speed, track (compass heading the aircraft is flying over the ground, in degrees true), and vertical rate (rate of climb or descent in feet per minute).

Data refreshes every few seconds. Pagination is opt-in: omit limit to receive the full matched set (use filters to bound size), or pass limit and offset to page through large result sets. For static registry details on a hex address, chain to Aircraft Lookup. For historical tracks, see Historical ADS-B.

Requirements

Auth
x-api-key on every request (direct subscription). Learn more →
EndpointWhen to use
GET /adsb/aircraftLive positions — map tiles, traffic boards, filtered feeds
GET /adsb/aircraft/statisticsFleet-wide aggregates — airborne vs on-ground, altitude stats
GET /adsb/healthFeed health — connection status and active aircraft count before starting a polling loop

Live aircraft

Returns currently tracked aircraft with latest position and flight data. Each record includes position, altitude, ground speed, track, vertical rate, and enrichment fields when available.

Request

GEThttps://data.skylinkapi.com/v3.1/adsb/aircraft
ParameterTypeRequiredDefaultDescription
icao24stringNo-Filter by 6-character hex transponder address (lowercase or uppercase; leading zeros preserved, e.g. 0A0022)
callsignstringNo-Partial callsign match (case-insensitive), e.g. DAH matches DAH2055
latnumberNo-Centre latitude for radius search (-90 to 90)
lonnumberNo-Centre longitude for radius search (-180 to 180)
radiusnumberNo-Search radius in kilometres (max 1000)
bboxstringNo-Bounding box lat1,lon1,lat2,lon2 — SW corner first, then NE. Example: 51.2,-0.8,51.6,-0.2
min_altnumberNo-Minimum altitude in feet
max_altnumberNo-Maximum altitude in feet
min_speednumberNo-Minimum ground speed in knots
max_speednumberNo-Maximum ground speed in knots
registrationstringNo-Filter by tail number
airlinestringNo-Filter by operating airline name
photosbooleanNofalseFetch thumbnail photos (slower; max 50 aircraft per page)
limitintegerNofull setPage size — omit to return all matches
offsetintegerNo0Skip count for pagination

Filter combination rules — the most common source of 422 errors:

Search modeRequired parametersNotes
Circlelat + lon + radiusAll three together
RectanglebboxSW corner first, then NE
Neither—Do not mix circle and bbox parameters
Partial geo—lat without lon (or vice versa) is rejected

Combine altitude and speed filters to isolate en-route traffic.

Important: photos defaults to false. Setting photos=true is slower and caps at 50 aircraft per page — enable only for detail views, not map tiles or high-frequency polling.

Response

{
  "aircraft": [
    {
      "icao24": "0A0022",
      "callsign": "DAH2055",
      "latitude": 51.274109,
      "longitude": -0.675964,
      "altitude": 9075.0,
      "ground_speed": 298.3,
      "track": 153.09,
      "vertical_rate": 2880.0,
      "is_on_ground": false,
      "last_seen": "2026-06-16T14:21:45.674566",
      "first_seen": "2026-06-16T14:17:09.312068",
      "registration": "7T-VJP",
      "aircraft_type": "Boeing B738",
      "airline": "Air Algerie",
      "photo_url": null
    }
  ],
  "total_count": 67,
  "timestamp": "2026-06-16T14:21:49.178448"
}
FieldTypeRequiredNull?Description
aircraftarrayYesNeverMatched aircraft (may be empty)
total_countintegerYesNeverNumber of aircraft in this response
timestampstring (ISO 8601)NoNeverWhen the snapshot was generated

Aircraft item (aircraft[])

FieldTypeRequiredNull?Description
icao24stringYesNeverICAO 24-bit hex identifier
callsignstring | nullNoYesFlight callsign when broadcast
latitudenumber | nullNoYesWGS-84 latitude
longitudenumber | nullNoYesWGS-84 longitude
altitudenumber | nullNoYesBarometric altitude in feet MSL
ground_speednumber | nullNoYesGround speed in knots
tracknumber | nullNoYesTrack angle in degrees (0–360)
vertical_ratenumber | nullNoYesVertical rate in feet per minute
is_on_groundboolean | nullNoYestrue when on the surface
last_seenstring (ISO 8601)YesNeverLast observation time
first_seenstring (ISO 8601)YesNeverFirst seen in current tracking session
registrationstring | nullNoYesTail number when resolved
aircraft_typestring | nullNoYesType description or ICAO designator
airlinestring | nullNoYesOperating airline when resolved
photo_urlstring | nullNoYesThumbnail URL when photos=true

Enrichment fields (registration, aircraft_type, airline) may be null when the hex address is not in the registry or the feed lacks a callsign link.

GET
/adsb/aircraft
x-api-key<token>

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

In: header

Query Parameters

icao24?|

Filter by ICAO 24-bit aircraft identifier (6 hex characters)

callsign?|

Filter by flight callsign (partial match, case-insensitive)

lat?|

Center latitude for radius search

lon?|

Center longitude for radius search

radius?|

Search radius in kilometers

bbox?|

Bounding box as 'lat1,lon1,lat2,lon2' (SW,NE corners)

min_alt?|

Minimum altitude in feet

max_alt?|

Maximum altitude in feet

min_speed?|

Minimum ground speed in knots

max_speed?|

Maximum ground speed in knots

registration?|

Filter by aircraft registration

airline?|

Filter by operating airline

photos?Photos

Fetch aircraft photos from airport-data.com (slower, max 50 aircraft per page)

Defaultfalse
limit?|

Page size for pagination. Omit to return the full matched set.

offset?Offset

Number of aircraft to skip before returning results (for pagination).

Default0
Range0 <= value

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/adsb/aircraft"
{
  "aircraft": [
    {
      "icao24": "40621D",
      "callsign": "BAW123",
      "latitude": 51.4706,
      "longitude": -0.4619,
      "altitude": 35000,
      "ground_speed": 450.5,
      "track": 89.2,
      "vertical_rate": 0,
      "is_on_ground": false,
      "last_seen": "2026-02-11T12:00:00Z",
      "first_seen": "2026-02-11T11:45:00Z",
      "registration": "G-STBC",
      "aircraft_type": "Boeing 777-36N",
      "airline": "British Airways",
      "photo_url": "https://image.airport-data.com/aircraft/001912010.jpg"
    }
  ],
  "total_count": 4691,
  "timestamp": "2026-02-11T12:00:30Z"
}
{
  "error": "string",
  "detail": "string",
  "timestamp": "2019-08-24T14:15:22Z"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string",
      "input": null,
      "ctx": {}
    }
  ]
}
{
  "error": "string",
  "detail": "string",
  "timestamp": "2019-08-24T14:15:22Z"
}

Tracking statistics

Aggregate statistics about the currently tracked fleet — total aircraft, on-ground vs airborne counts, and altitude summary. No parameters required. Useful for monitoring dashboards.

Request

GEThttps://data.skylinkapi.com/v3.1/adsb/aircraft/statistics

No query or path parameters.

Response

{
  "total_aircraft": 9889,
  "positioned_aircraft": 9889,
  "on_ground": 412,
  "airborne": 9477,
  "altitude_stats": {
    "min_altitude": 100.0,
    "max_altitude": 56600.0,
    "avg_altitude": 21338.04
  },
  "timestamp": "2026-06-16T14:21:50.116343"
}
FieldTypeRequiredNull?Description
total_aircraftintegerYesNeverTotal tracked aircraft
positioned_aircraftintegerYesNeverAircraft with a known position
on_groundintegerYesNeverAircraft flagged on ground
airborneintegerYesNeverAircraft flagged airborne
altitude_statsobjectYesNeverFleet altitude summary
altitude_stats.min_altitudenumberYesNeverMinimum reported altitude (feet)
altitude_stats.max_altitudenumberYesNeverMaximum reported altitude (feet)
altitude_stats.avg_altitudenumberYesNeverMean altitude across fleet (feet)
timestampstring (ISO 8601)YesNeverSnapshot time
GET
/adsb/aircraft/statistics
x-api-key<token>

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

In: header

Response Body

application/json

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/adsb/aircraft/statistics"
{}
{
  "error": "string",
  "detail": "string",
  "timestamp": "2019-08-24T14:15:22Z"
}
{
  "error": "string",
  "detail": "string",
  "timestamp": "2019-08-24T14:15:22Z"
}

Service health

Returns ADS-B connection status and active aircraft count. Use for uptime monitoring and pre-flight checks before polling the live feed.

Request

GEThttps://data.skylinkapi.com/v3.1/adsb/health

No query or path parameters.

Response

{
  "status": "healthy",
  "connected": true,
  "active_aircraft_count": 9889,
  "connection_uptime": null,
  "last_message_received": "2026-06-16T14:21:46.212802"
}
FieldTypeRequiredNull?Description
statusstringYesNeverService status label, e.g. healthy
connectedbooleanYesNeverWhether the ADS-B hub connection is active
active_aircraft_countintegerYesNeverCurrently tracked aircraft
connection_uptimenumber | nullNoYesUptime in seconds when available
last_message_receivedstring (ISO 8601) | nullNoYesLast message timestamp from the feed
GET
/adsb/health
x-api-key<token>

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

In: header

Response Body

application/json

application/json

application/json

curl -X GET "https://data.skylinkapi.com/v3.1/adsb/health"
{
  "status": "string",
  "connected": true,
  "active_aircraft_count": 0,
  "connection_uptime": 0,
  "last_message_received": "2019-08-24T14:15:22Z"
}
{
  "error": "string",
  "detail": "string",
  "timestamp": "2019-08-24T14:15:22Z"
}
{
  "error": "string",
  "detail": "string",
  "timestamp": "2019-08-24T14:15:22Z"
}

Client types

"""ADS-B live aircraft models for GET /adsb/aircraft."""from __future__ import annotationsfrom dataclasses import dataclass@dataclassclass AdsbAircraft:    icao24: str    callsign: str | None    latitude: float | None    longitude: float | None    altitude: float | None    ground_speed: float | None    track: float | None    vertical_rate: float | None    is_on_ground: bool | None    last_seen: str    first_seen: str    registration: str | None    aircraft_type: str | None    airline: str | None    photo_url: str | None@dataclassclass AdsbAircraftListResponse:    aircraft: list[AdsbAircraft]    total_count: int    timestamp: str | None@dataclassclass MapMarker:    """Compact model for map overlays."""    icao24: str    label: str    lat: float    lon: float    altitude_ft: float | None    on_ground: bool

Integration

Poll live aircraft near an airport for a traffic map overlay.

The example below requests a radius search with a page limit, uses short timeouts (10 s / 15 s), and maps results to map markers. Do not cache live positions — poll every 5–15 seconds depending on your quota and UX needs.

import osfrom dataclasses import dataclassimport requestsHEADERS = {    "x-api-key": os.getenv("SKYLINK_API_KEY", "YOUR_API_KEY")}BASE = "https://data.skylinkapi.com/v3.1"@dataclassclass MapMarker:    icao24: str    label: str    lat: float    lon: float    altitude_ft: float | None    on_ground: booldef fetch_aircraft_near(    *,    lat: float,    lon: float,    radius_km: float = 50,    limit: int = 100,) -> dict:    """Fetch live ADS-B aircraft within a radius. Do not cache - data is ephemeral."""    try:        r = requests.get(            f"{BASE}/adsb/aircraft",            headers=HEADERS,            params={                "lat": lat,                "lon": lon,                "radius": radius_km,                "limit": limit,                "photos": False,            },            timeout=(10, 15),        )    except requests.Timeout as exc:        raise RuntimeError("SkyLink timeout fetching ADS-B aircraft") from exc    r.raise_for_status()    return r.json()def to_map_markers(payload: dict) -> list[MapMarker]:    markers: list[MapMarker] = []    for ac in payload.get("aircraft", []):        lat = ac.get("latitude")        lon = ac.get("longitude")        if lat is None or lon is None:            continue        label = ac.get("callsign") or ac.get("registration") or ac["icao24"]        markers.append(            MapMarker(                icao24=ac["icao24"],                label=label,                lat=float(lat),                lon=float(lon),                altitude_ft=ac.get("altitude"),                on_ground=bool(ac.get("is_on_ground")),            )        )    return markersif __name__ == "__main__":    import json    payload = fetch_aircraft_near(lat=40.6413, lon=-73.7781, radius_km=80, limit=5)    print(json.dumps(payload, indent=2, default=str))

Implementation notes

Polling interval. ADS-B data updates every few seconds. Polling faster than ~5 s rarely improves freshness and consumes quota quickly.

Bounding queries. Always pass lat/lon/radius or bbox for map views — unfiltered global queries can return very large payloads.

Pagination. Use limit + offset when rendering tables. total_count reflects the current page size, not the global fleet count.

Enrichment gaps. registration and aircraft_type may be null for military, blocked, or unregistered hex codes. Fall back to callsign and ICAO24 display.

Live → performance chain. aircraft_type on the live feed is often a marketing string (e.g. "Boeing B738"), not an ICAO designator. To fetch Aircraft Performance, call Aircraft Lookup with icao24 and use aircraft.icao_type from the registry response.

ICAO24 normalization. Accept 6-character hex from ADS-B feeds; uppercase and lowercase are equivalent. Pad short addresses with leading zeros when your source omits them.

Error responses

For shared platform errors (auth, rate limits, server errors), see Error Handling. Endpoint-specific behavior:

404 — ICAO24 filter not found (live aircraft)

When filtering by icao24 and no aircraft matches:

{
  "error": "Aircraft not found",
  "detail": "No aircraft found with ICAO24 000000",
  "timestamp": "2026-06-16T14:00:00Z"
}

Only applies when icao24 is provided as a filter — not for empty radius searches.

422 — invalid filter combination

{
  "detail": [
    {
      "type": "greater_than",
      "loc": ["query", "radius"],
      "msg": "Input should be greater than 0"
    }
  ]
}

Occurs when numeric filters are out of range (for example radius ≤ 0 or altitude outside 0–60000 ft), or when circle and bbox parameters are mixed.


Related: Aircraft Lookup · Historical ADS-B · Flight Status