A corporate flight department managing three to thirty aircraft has a surprisingly basic monitoring problem: where are our airplanes right now? The answer is usually "someone checks FlightRadar24" or "the pilots call when they land." Neither of those is a system. One is a consumer website that anyone else can also see (including people you might not want knowing where your CEO is flying), and the other depends on someone remembering to make a phone call.
This post is about building a private fleet tracker that shows your aircraft and only your aircraft, sends alerts when things happen, and feeds data into maintenance tracking — all from an API you control.
Why not just use a consumer tracker?
Three reasons, in order of how often they come up:
Privacy. Consumer flight trackers show everyone's aircraft to everyone. Corporate operators frequently don't want their tail numbers and routes visible to competitors, journalists, or the general public. The FAA's LADD program can block your aircraft from some public feeds, but LADD only covers US airspace, only applies to some data sources, and doesn't block ADS-B receivers that anyone can operate. A private tracker built on your own infrastructure doesn't share its output with the world.
Reliability. A consumer tracker is a free service with no SLA. If it goes down during the 20 minutes your aircraft is on approach to an unfamiliar field, nobody at the FBO knows to expect it. A paid API with a contractual SLA is something you can depend on operationally.
Customisation. You don't just want a dot on a map. You want an alert when the aircraft departs, another when it lands, a log entry for maintenance-hour tracking, and maybe a notification to the ground transport provider at the destination. Consumer trackers don't do callbacks.
![]()
Building a fleet tracker
The simplest version is a script that polls for your aircraft by their ICAO24 hex codes and displays the result. A corporate fleet is small enough — usually under 30 aircraft — that you can poll for each one individually without hitting rate limits.
import requests, time
BASE = "https://skylink-api.p.rapidapi.com"
H = {"X-RapidAPI-Key": KEY, "X-RapidAPI-Host": "skylink-api.p.rapidapi.com"}
# Your fleet — ICAO24 hex codes for each aircraft
FLEET = {
"a1b2c3": "N100AB", # Gulfstream G650
"d4e5f6": "N200CD", # Challenger 350
"a7b8c9": "N300EF", # King Air 350
}
def check_fleet():
for hex_code, reg in FLEET.items():
r = requests.get(f"{BASE}/aircraft/icao24/{hex_code}", headers=H,
timeout=10)
data = r.json()
pos = data.get("position", {})
if pos.get("latitude"):
status = "ON GROUND" if pos.get("is_on_ground") else "AIRBORNE"
print(f"{reg} ({hex_code}): {status} "
f"alt={pos.get('altitude')} "
f"gs={pos.get('ground_speed')} "
f"last_seen={pos.get('last_seen')}")
else:
print(f"{reg} ({hex_code}): no position data")
while True:
check_fleet()
print("---")
time.sleep(30)For a more polished version, wrap this in a small web app — Flask, FastAPI, whatever your team knows — and plot the positions on a Leaflet map. The web app is internal-only, behind your VPN or SSO, so the data never leaves your network.
Event detection and alerting
The fleet tracker becomes operationally useful when it detects events and pushes notifications instead of requiring someone to watch a screen.
The events that matter for a corporate flight department:
Departure. The aircraft was on the ground at a known location and is now airborne. Detect this by watching is_on_ground flip from true to false. When it happens, send a notification to the flight department manager and the destination FBO.
Arrival. The inverse — is_on_ground flips to true and the aircraft is at or near the destination. Trigger the ground transport notification and log the block-in time.
Diversion. The aircraft was expected at airport A but is now heading toward airport B. This is harder to detect automatically — you need to compare the current heading and nearest airport against the filed destination. It's worth building because a diversion triggers a cascade of logistics changes that need to start immediately.
Maintenance alert. After each flight, increment the aircraft's flight-hour counter. When it approaches a scheduled inspection interval, flag it. ADS-B doesn't give you exact engine hours, but block-to-block time (departure to arrival, as detected by state transitions) is close enough for scheduling purposes. The actual hobbs time comes from the pilot's log, but the API-derived estimate means the maintenance planner isn't surprised.
from datetime import datetime, timezone
# Simple departure detection
last_state = {}
def detect_events(hex_code, reg, pos):
on_ground = pos.get("is_on_ground", True)
prev = last_state.get(hex_code, True)
last_state[hex_code] = on_ground
if prev and not on_ground:
print(f"DEPARTURE: {reg} is airborne")
# send_alert(f"{reg} departed", ...)
elif not prev and on_ground:
lat, lon = pos.get("latitude"), pos.get("longitude")
print(f"ARRIVAL: {reg} on ground at {lat:.3f}, {lon:.3f}")
# send_alert(f"{reg} landed", ...)
# log_flight_hours(hex_code, ...)![]()
ICAO24 hex codes vs. registration lookups
You need the ICAO24 hex code for each aircraft in your fleet to query the ADS-B feed. If you only know the registration (tail number), the registration lookup endpoint converts it:
r = requests.get(f"{BASE}/aircraft/registration/N100AB", headers=H)
data = r.json()
hex_code = data.get("icao24")
ac_type = data.get("aircraft_type")
print(f"N100AB -> {hex_code}, type: {ac_type}")Do this lookup once and store the mapping. Hex codes don't change unless the aircraft is re-registered in a different country, which for a corporate fleet is rare.
Handling LADD and privacy blocks
If your aircraft is enrolled in the FAA's LADD (Limiting Aircraft Data Displayed) program, some data sources will suppress it. ADS-B is a broadcast protocol — any receiver within line of sight picks it up regardless of LADD status — so the aircraft may still appear in ADS-B feeds depending on the feed's data sources and filtering policies.
For corporate flight departments, this creates a bit of a paradox: you want your aircraft to be invisible on public trackers but visible to your own tools. The way to handle this is to use the ICAO24 hex code to query the feed directly (you know your own hex codes) rather than relying on being able to search by registration or callsign, which LADD may suppress.
If privacy is a hard requirement — you need to guarantee that your aircraft's movements are not visible to anyone except your team — then ADS-B feeds of any kind (including ours) are the wrong tool, because the protocol is an open broadcast. No feed operator can prevent a third party from operating their own receiver. What an API gives you is a private view of data that is, by the nature of the protocol, publicly receivable.
What you need
For a fleet of 10 aircraft polled every 30 seconds, you're looking at roughly 28,800 requests per day. That's within the Pro tier. The endpoints you need — ICAO24 lookup, registration lookup, ADS-B positions — are all in the standard API docs.
Start with the free trial to build the prototype with one or two aircraft, then scale up. For flight departments that need guaranteed uptime and don't want to explain to the chief pilot why the tracker was down, Enterprise includes the 99.9% SLA and priority support.