How to handle duplicate IATA airline codes

By Airhex · · 5 min read

Departures board listing Jeju Air and Coyne Airways flights, both under the IATA code 7C

Most flight products quietly assume that an airline's two-character IATA code identifies exactly one airline. Usually it does. But IATA deliberately gives some codes to two airlines at the same time, and it recycles codes when airlines disappear. If your database uses the IATA code as the airline's key, sooner or later a traveller will see the wrong airline name or logo on their flight.

This guide explains why shared codes exist, what breaks when a product ignores them, and a data model that handles them cleanly.

Why IATA codes run out

IATA airline designators are two characters: letters, or a letter and a digit. That leaves roughly 1,200 usable combinations for well over a thousand passenger, cargo and charter carriers. IATA stretches that small space in two ways:

  • Controlled duplicates. The same code is given to two carriers whose operations are not expected to overlap: different regions, or one passenger and one cargo airline. IATA's directory marks the second holder with an asterisk, for example 7C*.
  • Reuse. When an airline stops flying, its code is withdrawn and, after a waiting period, can be assigned to a new airline.

Real examples

At the time of writing, the Airhex airline directory lists several active pairs that share a code, including these:

IATAAirlineICAOWhere it flies
7CJeju AirJJASouth Korea and the region (passenger)
7CCoyne AirwaysCOYUK-based cargo airline
SLThai Lion AirTLMThailand and the region
SLSAS ConnectSZSScandinavia and Europe
E2Eurowings EuropeEWEEurope
E2airHaifaHFAIsrael

Codes also change hands over time. Alitalia's AZ now belongs to ITA Airways, which took over the code in 2021 but flies under its own ICAO code, ITY (Alitalia was AZA). Continental's CO was retired after its merger with United and has since been assigned to other carriers. Any system that stored "CO = Continental" forever now has a problem.

What breaks when you treat the code as unique

  • Overwritten records. With the IATA code as primary key, importing the second airline either fails or silently replaces the first one.
  • Wrong branding. A Thai Lion Air flight appears with the SAS Connect name or logo, or the other way round, because the lookup returned the first match.
  • Merged networks. Route maps and schedule tools that group flights by code combine two unrelated airlines, so a Thai domestic carrier suddenly seems to fly in Scandinavia.
  • Rewritten history. After a code is reused, old bookings, reports and analytics attribute past flights to the new owner: Alitalia's flights start showing up as ITA Airways.
  • Wrong extras. The loyalty programme, check-in link or baggage policy of one airline is shown for the other.

A data model that copes

1. Give every airline its own ID

Use an internal ID as the primary key, and store the IATA code as an ordinary, non-unique column. Two airlines with the code SL are then simply two rows.

airlines
  id          -- your own key, never reused
  iata        -- 'SL'  (indexed, NOT unique)
  icao        -- 'TLM'
  name        -- 'Thai Lion Air'
  valid_from  -- when this airline got the code
  valid_to    -- when it lost it (NULL = still current)

2. Store the ICAO code as well

ICAO airline designators have three letters and are not shared the way IATA codes are: Thai Lion Air is TLM, SAS Connect is SZS. Schedule files, flight status feeds and ADS-B data often carry the ICAO code, so match on it first whenever it is there.

3. Resolve ambiguous codes with context

When a feed gives you only the IATA code and two airlines match, use what else you know:

  • Airports. An SL flight from Bangkok Don Mueang to Chiang Mai is Thai Lion Air; one from Copenhagen is SAS Connect.
  • Date. Which airline held the code on the day of the flight? An AZ flight in 2019 is Alitalia; in 2024 it is ITA Airways.
  • Service type. Passenger or cargo.
  • The airline name or ICAO code in the source record, if your supplier sends it.

If the context still doesn't settle it, don't guess silently: fall back to showing the code and log a warning.

4. Keep validity dates

The valid_from and valid_to columns let historical records keep pointing to the airline that actually flew them, while new bookings resolve to the current holder.

5. Make duplicates visible to your team

Show shared codes clearly in admin tools (for example SL* or a "shared code" badge) and log every lookup that returns more than one airline. Support staff will thank you the first time a traveller asks why their ticket shows a different airline.

6. Test it

Add a shared-code pair to your test fixtures and run search, booking, import and reporting against it. It is much cheaper to find the "first match wins" bug in a test than in production.

Sometimes several operators legitimately fly under one airline's code. Aer Lingus Regional flights are sold under Aer Lingus's EI, and Fiji Link flights under Fiji Airways' FJ. Here the code is correct; the operating airline is simply different. Store the marketing carrier and the operating carrier separately and show "Operated by…" when they differ.

The reverse also happens: one brand, many codes. LATAM's airlines fly as LA, JJ (LATAM Brasil), LP (LATAM Peru), XL (LATAM Ecuador) and 4C (LATAM Colombia). If you group results by brand, map those codes to one parent rather than assuming one brand means one code.

Keep the directory current

Codes are assigned, withdrawn and reassigned every week, so a one-off import goes stale quickly. Refresh your airline data at least weekly, compare it with the previous version, and review anything that changed hands. The Airhex airline database tracks shared and reused codes and links each code to its past and present holders; you can see what changes week to week in our recent changes feed and look up codes with the IATA codes API.

Checklist

  • The IATA code is not a unique key anywhere in your schema.
  • You store the ICAO code and use it when the source provides it.
  • Ambiguous lookups use airports, date and service type, and log a warning when unresolved.
  • Airline records have validity dates, so history stays correct after a code is reused.
  • Marketing and operating carriers are stored separately.
  • Your airline data is refreshed and diffed at least weekly.