A tail number — the registration painted on the fuselage and tail of every aircraft, like N12345 or G-STBC — is the single most useful identifier in aviation software. It's what a spotter photographs, what shows up on a flight-tracking row, and what a maintenance system files under. But on its own it's just a string. Turning G-STBC into "British Airways Boeing 777-300ER, serial 38287" is a lookup problem, and this post covers what a tail number actually encodes and how to resolve one to full aircraft data with a single API call.
What a tail number actually is
The tail number (formally the aircraft registration) is a unique identifier assigned by a national aviation authority when an aircraft is entered on that country's civil register. It's the aviation equivalent of a license plate: tied to the airframe, unique within its country, and legally required to be displayed. Every registration starts with a country prefix, which is why you can often guess an aircraft's home country from the tail alone:
| Prefix | Country | Example |
|---|---|---|
N | United States | N12345 |
G- | United Kingdom | G-STBC |
D- | Germany | D-AIMA |
F- | France | F-GSPA |
VH- | Australia | VH-OQA |
JA | Japan | JA8089 |
C- | Canada | C-FGRY |
PH- | Netherlands | PH-BVA |
The US is the odd one out: it uses a bare N with no hyphen, and the format is flexible (N1 through N99999, plus letter suffixes like N600WN). Most other countries use a hyphen followed by a fixed number of letters. This matters when you validate input — a regex that assumes a hyphen will reject every US tail number.

Registration is not the same as the ICAO24 or the flight number
Three identifiers get confused constantly, and a good aircraft data layer keeps them distinct:
- Registration / tail number (
G-STBC) — the human-readable, painted-on identifier tied to the airframe for its life on that register. - ICAO24 / hex code (
40621D) — a 6-character hexadecimal address baked into the transponder and broadcast on ADS-B. It's what you receive from a live tracking feed, and it's also tied to the airframe, but it's a machine identifier, not a marketing one. - Flight number (
BA123) — tied to a route on a schedule, not to an aircraft. The same tail flies dozens of different flight numbers, and the same flight number is flown by a different tail every day.
The practical upshot: if your UI already has a tail number (from a schedule row, a spotting log, a fleet page), you look it up by registration. If you're ingesting a live ADS-B feed, you get hex codes and look them up by ICAO24. Both should resolve to the same underlying aircraft record.
Resolving a tail number by API
SkyLink API's aircraft lookup endpoint takes a registration on the path and returns the aircraft's type, operator, manufacturer, serial number, and community photos from a registry of 615,000+ records refreshed daily:
curl "https://skylink-api.p.rapidapi.com/aircraft/registration/G-STBC" \
-H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
-H "X-RapidAPI-Host: skylink-api.p.rapidapi.com"{
"query": "G-STBC",
"found": true,
"aircraft": {
"registration": "G-STBC",
"icao24": "40621D",
"icao_type": "B77W",
"type_name": "BOEING 777-36NER",
"manufacturer": "Boeing Company",
"manufacturer_and_model": "Boeing Company BOEING 777-36NER",
"owner_operator": "British Airways",
"airline_code": null,
"is_private_operator": false,
"serial_number": "38287",
"photos": ["https://..."]
}
}One field is worth calling out for anyone new to this API: found. When no aircraft matches, the endpoint does not return a 404. It returns HTTP 200 with "found": false and "aircraft": null. Check the found boolean in the body — treating a missing aircraft as an HTTP error will make your error handling fire on perfectly valid "not in the registry yet" responses.
const res = await fetch(
`https://skylink-api.p.rapidapi.com/aircraft/registration/${reg}`,
{
headers: {
"X-RapidAPI-Key": process.env.RAPIDAPI_KEY,
"X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
},
}
);
const data = await res.json(); // 200 even when nothing matched
if (!data.found) {
return { status: "unknown", registration: reg }; // not an error path
}
return data.aircraft;
Enriching a live ADS-B feed by ICAO24
The same registry is addressable by ICAO24, which is the piece you need when the data is coming off the air rather than out of a database. A live tracker gives you a hex code and a position; the lookup gives you back the tail, type, and operator to label the marker:
curl "https://skylink-api.p.rapidapi.com/aircraft/icao24/40621D?photos=false" \
-H "X-RapidAPI-Key: $RAPIDAPI_KEY" \
-H "X-RapidAPI-Host: skylink-api.p.rapidapi.com"Note photos=false. Photos default to true because they're handy on a detail view, but they add latency — so on map overlays, list views, and batch enrichment jobs where you're resolving hundreds of hex codes, turn them off. Once you have icao_type (the 4-character ICAO type code like B77W), you can chain to the aircraft performance endpoint for cruise speed, range, and wake category to complete the picture.
Practical notes for building on it
A few things that will save you debugging time:
- Normalize input. Uppercase the registration and strip stray spaces before you query.
g-stbcandG-STBCshould hit the same record; don't make the API guess. - Cache aggressively. An airframe's type, manufacturer, and serial number effectively never change, and even operator changes are slow. Cache resolved records for hours or days — this is reference data, not live data.
- Expect registry lag. The database refreshes daily, but brand-new registrations and same-week ownership changes may not have propagated from the national authority yet.
found: falseon a tail you know exists usually means "not synced yet," not "invalid." - Batch off the hot path. If you're enriching a whole schedule or a fleet page, resolve tails in a background job and store the result, rather than blocking the page render on a per-row lookup.
Tail-number lookup pairs naturally with the rest of a flight data stack: resolve the aircraft on a live tracking map, decorate schedule rows with the actual type flying today, or build a public aircraft page around the registration, type, and photos.
SkyLink API gives you a free tier of 1,000 requests/month to test tail-number and ICAO24 lookups against, with paid plans starting at $18.59/mo once you're ready for production traffic. It's available through the free trial — sign up, grab a key, and turn a tail number into full aircraft data in one call.
