Skip to content

US ๐Ÿ‡บ๐Ÿ‡ธ FAA Registry โ€‹

Nameus-faa-registry
CountryUnited States
Registration prefixN (no dash; N-number, e.g. N62770)
Data sourcehttps://registry.faa.gov/database/ReleasableAircraft.zip
FormatZIP of pipe-free CSV files (fixed URL; no discovery step)
Run frequencyWeekly (Saturday, 05:10 UTC)
Depends on Mictronics for ICAO hexNo โ€” master.txt (the registration file) publishes the Mode S code hex directly.

How it works โ€‹

The FAA Releasable Aircraft Database ZIP is downloaded from a fixed URL and extracted entirely in memory; filenames are lowercased, and a .txt.txt double-extension bug the FAA has occasionally shipped is normalized away. Three files are staged into a local SQLite database rather than written straight to Redis, so that per-tail registrations can be joined against reference tables cheaply:

  • engine.txt โ€” engine make/model/type/power reference, keyed by engine code
  • acftref.txt โ€” aircraft make/model/seats/category reference, keyed by aircraft code
  • master.txt โ€” one row per registered tail, keyed by icao_hex (only rows with a well-formed 6-character Mode S hex are kept)

This runner supports the 2017+ column layout only. Numeric FAA type codes (engine type, aircraft type, aircraft class, registrant type) are decoded via lookup tables into human-readable strings. Powerplant power is reported as thrust for jet/fan/ramjet engine types and as horsepower for piston/turboprop/turboshaft/2-4-cycle/rotary types. The final Redis write is driven by a single LEFT JOIN query across the staged tables and flushed to Redis in batches of 10,000. Every written record explicitly sets military: false โ€” this register is exclusively civil, and the explicit value ensures a stale military: true flag (from Mictronics or a prior record on a reused hex) is corrected on re-registration.

Deduced ICAO type designator โ€‹

The FAA register never publishes an ICAO type designator (e.g. C172) โ€” only a raw manufacturer/model string. Since Mictronics has no entry at all for a large share of these hexes, this runner deduces a designator for those hexes by consensus: hexes Mictronics does already label become training data, grouped by normalized (manufacturer, model); a group's majority Mictronics designator is applied to that group's other, unlabelled hexes when the group has at least 3 labelled examples and at least 90% agreement, otherwise the gap is left as-is. A deduced designator also gets its matching description_code, resolved from the aircraft:type:{designator} reference Redis already carries. See shared/type_designator_consensus.py and issue #1888 for the method and its measured precision/coverage.

Columns โ€‹

The FAA ZIP contains eight files (ardata.pdf, ACFTREF.txt, ENGINE.txt, DEALER.txt, DOCINDEX.txt, MASTER.txt, RESERVED.txt, DEREG.txt); this runner reads only acftref.txt, engine.txt, and master.txt, joined via the codes below. Column names below are verbatim from each file's real header row.

engine.txt โ€‹

Source columnImportedNotes
CODEโœ…Join key to master.txt's engine-code column
MFRโœ…โ†’ aircraft.powerplant.manufacturer
MODELโœ…โ†’ aircraft.powerplant.model
TYPEโœ…โ†’ aircraft.powerplant.type (decoded)
HORSEPOWERโœ…โ†’ aircraft.powerplant.power_value (piston/turboprop/turboshaft/2-4-cycle/rotary types)
THRUSTโœ…โ†’ aircraft.powerplant.power_value (turbo-jet/turbo-fan/ramjet types)

acftref.txt โ€‹

Source columnImportedNotes
CODEโœ…Join key to master.txt's aircraft-code column
MFRโœ…โ†’ aircraft.manufacturer
MODELโœ…โ†’ aircraft.model
TYPE-ACFTโœ…โ†’ aircraft.type (decoded)
TYPE-ENGโœ…โ†’ aircraft.powerplant.type (decoded; used if no matching engine.txt row)
AC-CATโœ…โ†’ aircraft.category (decoded)
BUILD-CERT-INDโŒPresent in source; not read by this runner
NO-ENGโœ…โ†’ aircraft.powerplant.count
NO-SEATSโœ…โ†’ aircraft.seats
AC-WEIGHTโŒPresent in source; not read by this runner
SPEEDโŒPresent in source; not read by this runner
TC-DATA-SHEETโŒPresent in source; not read by this runner
TC-DATA-HOLDERโŒPresent in source; not read by this runner

master.txt โ€‹

Source columnImportedNotes
N-NUMBERโœ…โ†’ registration (prefixed with N)
SERIAL NUMBERโœ…โ†’ aircraft.serial_number
MFR MDL CODEโœ…Join key to acftref.txt
ENG MFR MDLโœ…Join key to engine.txt
YEAR MFRโœ…โ†’ aircraft.manufactured_date
TYPE REGISTRANTโœ…โ†’ registrant.type (decoded)
NAMEโœ…โ†’ registrant.names[0]
STREETโœ…โ†’ registrant.street
STREET2โœ…โ†’ registrant.street
CITYโœ…โ†’ registrant.city
STATEโœ…โ†’ registrant.administrative_area
ZIP CODEโœ…โ†’ registrant.postal_code
REGIONโŒPresent in source; not read by this runner
COUNTYโŒPresent in source; not read by this runner
COUNTRYโœ…โ†’ registrant.country (defaults to US)
LAST ACTION DATEโŒPresent in source; not read by this runner
CERT ISSUE DATEโŒPresent in source; not read by this runner
CERTIFICATIONโŒPresent in source; not read by this runner
TYPE AIRCRAFTโŒPresent in source; not read by this runner
TYPE ENGINEโŒPresent in source; not read by this runner
STATUS CODEโŒPresent in source; not read by this runner
MODE S CODEโŒPresent in source; not read by this runner (distinct from MODE S CODE HEX, below, which is used)
FRACT OWNERโŒPresent in source; not read by this runner
AIR WORTH DATEโŒPresent in source; not read by this runner
OTHER NAMES(1-5)โœ…โ†’ registrant.names[1:]
EXPIRATION DATEโŒPresent in source; not read by this runner
UNIQUE IDโŒPresent in source; not read by this runner
KIT MFRโŒPresent in source; not read by this runner
KIT MODELโŒPresent in source; not read by this runner
MODE S CODE HEXโœ…โ†’ icao_hex; rows without a well-formed 6-character hex are discarded

See specs/data-dictionary.yaml (us-faa-registry entry) for full column semantics and cross-source schema notes.

Example Output โ€‹

Read back the merged record for a given ICAO hex (combines this runner's data with Mictronics and any other sources that have written to the same key):

bash
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 A833A4 | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "category": "Land",
        "manufactured_date": "2008-01-01T00:00:00Z",
        "manufacturer": "CESSNA",
        "manufacturer_model": "CESSNA 172 Skyhawk",
        "model": "172S",
        "powerplant": {
            "count": 1,
            "manufacturer": "LYCOMING",
            "model": "IO-360-L2A",
            "power_type": "Horsepower",
            "power_value": 180,
            "type": "Piston"
        },
        "seats": 4,
        "serial_number": "172S10747",
        "type": "Airplane",
        "type_designator": "C172"
    },
    "data_sources": [
        "mictronics",
        "us-faa-registry"
    ],
    "icao_hex": "A833A4",
    "military": false,
    "registrant": {
        "administrative_area": "FL",
        "city": "WINTER PARK",
        "country": "US",
        "names": [
            "HOG ISLAND FLYING LLC"
        ],
        "postal_code": "327893726",
        "street": [
            "807 W MORSE BLVD STE 101"
        ],
        "type": "LLC"
    },
    "registration": "N62770"
}
bash
docker run --rm --network host redis:latest redis-cli EVAL "$(cat ./shared/lua/merge_aircraft.lua)" 0 A8AE7F | python3 -m json.tool --sort-keys --no-ensure-ascii
json
{
    "aircraft": {
        "category": "Land",
        "manufactured_date": "1990-01-01T00:00:00Z",
        "manufacturer": "BOEING",
        "manufacturer_model": "BOEING 757-200",
        "model": "757-232",
        "powerplant": {
            "count": 2,
            "type": "Turbo-fan"
        },
        "seats": 178,
        "serial_number": "24421",
        "type": "Airplane",
        "type_designator": "B752"
    },
    "data_sources": [
        "mictronics",
        "us-faa-registry"
    ],
    "icao_hex": "A8AE7F",
    "military": false,
    "registrant": {
        "administrative_area": "GA",
        "city": "ATLANTA",
        "country": "US",
        "names": [
            "DELTA AIR LINES INC"
        ],
        "postal_code": "303543743",
        "street": [
            "1775 M H JACKSON SERVICE RD",
            "DEPT 595 AIRCRAFT REGISTRATIONS"
        ],
        "type": "Corporation"
    },
    "registration": "N659DL"
}

Configuration โ€‹

See Data Runners for the full list of environment variables every runner reads. This runner writes aircraft:registry:{icao_hex} with a fixed 14-day TTL (ENRICHMENT_TTL_SECONDS in shared/timing.py).

MQTT โ€‹

Published once, at the end of a run, to SkyFollower/runner/us-faa-registry/statistic/{name} (all retained):

Topic suffixValueFormat
records_importede.g. 271Integer as string
last_run_ate.g. 2026-07-07T14:32:01.123456+00:00ISO 8601 UTC
last_run_statusSuccess or FailureString

Home Assistant autodiscovery configs are also published (retained) to homeassistant/sensor/SkyFollower_runner_us_faa_registry_{name}/config for each of the three stats above.