# FAA Aircraft Registry Scraper - Owners & Expiring Registrations (`groundplanes/faa-aircraft-registry-owners`) Actor

Aircraft registration data from the official FAA Releasable Aircraft database: registrations expiring soon, newly issued or recently deregistered. N-number, make/model, year, engine, owner company and address. Filter by state, aircraft and engine type. Business owners by default.

- **URL**: https://apify.com/groundplanes/faa-aircraft-registry-owners.md
- **Developed by:** [Groundplane Labs](https://apify.com/groundplanes) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 aircraft records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## FAA Aircraft Registry Scraper - Owners & Expiring Registrations

Filter the official daily Federal Aviation Administration (FAA) Civil Aircraft Registry (`ReleasableAircraft.zip`, ~300,000+ registered US civil aircraft) joined with aircraft model (`ACFTREF.txt`), engine (`ENGINE.txt`), and deregistration (`DEREG.txt`) reference tables. Identify corporate, LLC, partnership, and fleet aircraft owners flagged by registration lifecycle signals: expiring registrations, newly issued certificates, or recent deregistrations.

### What it does

Every US civil aircraft („N-Number“) must maintain an active registration with the FAA Civil Aviation Registry. Raw FAA bulk files split aircraft ownership (`MASTER.txt`), make/model specs (`ACFTREF.txt`), engine specs (`ENGINE.txt`), and deregistered aircraft (`DEREG.txt`) across separate fixed-width CSV files with numeric code lookups.

This Actor:

- Streams the official daily `ReleasableAircraft.zip` bulk archive directly to temporary disk and parses it with low-memory streaming CSV readers.
- Verifies the `MASTER.txt` schema header (`N-NUMBER,SERIAL NUMBER,MFR MDL CODE`) before processing.
- Joins every aircraft record to `ACFTREF.txt` (manufacturer, model, aircraft type) and `ENGINE.txt` (engine manufacturer, engine model, engine type).
- Filters by four aviation registration signals:
  - **`EXPIRING_SOON`** — Active registrations expiring within `expiringWithinDays` (default 180) through the end of that calendar month, soonest expiration first. Many owners renew months early, so 180 days gives a fuller list than 90.
  - **`NEWLY_ISSUED_30_DAYS`** — Certificates issued within the past 30 days (sorted newest certificate first).
  - **`RECENTLY_DEREGISTERED_30_DAYS`** — Aircraft cancelled/deregistered in `DEREG.txt` within the past 30 days (sorted newest cancellation first).
  - **`ALL_ACTIVE`** — All valid (`STATUS CODE = V`) registrations matching your state, aircraft-type, and engine-type filters.
- Excludes private individual owners and co-owner registrations (`TYPE REGISTRANT` 1, 4 and 9, which are almost always people) by default (`includeIndividualOwners: false`), so results focus on corporations, LLCs, partnerships and government entities. Partnership registrations (type 2) are kept only when the name carries a business marker such as LTD, LP, LLC, LLP, PARTNERSHIP, INC, CORP, CO or TRUST, because many are two people registered together.

> **Note on expirations:** FAA mails renewal notices about 6 months ahead and most owners renew early, so very few registrations appear in the next 1-3 months. Most expirations in the data show up 3 or more months out. That's why `expiringWithinDays` defaults to 180.

### Who it's for

- **Aviation MROs, avionics shops, and maintenance providers** reaching out to corporate and LLC aircraft operators ahead of registration renewals or after new acquisitions.
- **Aircraft brokers, lenders, and aviation insurance agencies** tracking newly certificated and recently deregistered fixed-wing and rotorcraft assets.
- **FBOs, hangar operators, and charter management companies** mapping turbine, turboprop, and multi-engine fleets by state.
- **Aerospace market researchers** analyzing fleet composition and ownership trends.

### Input

- **`expiringWithinDays`** *(integer)* — Window for `EXPIRING_SOON`, 1-730 days. Default `180`.
- **`registrationSignal`** *(string enum)* — `"EXPIRING_SOON"` (default), `"NEWLY_ISSUED_30_DAYS"`, `"RECENTLY_DEREGISTERED_30_DAYS"`, or `"ALL_ACTIVE"`.
- **`states`** *(array of strings)* — Two-letter US state codes for the registrant's address. Default: `["AZ", "TX"]`. Leave empty (`[]`) for all states.
- **`aircraftTypes`** *(array of strings)* — FAA aircraft type codes (`"4"` Fixed Wing Single-Engine, `"5"` Fixed Wing Multi-Engine, `"6"` Rotorcraft, `"1"` Glider, `"2"` Balloon, `"3"` Blimp/Dirigible, `"7"` Weight-Shift-Control, `"8"` Powered Parachute, `"9"` Gyroplane, `"H"` Hybrid Lift, `"O"` Other). Default: `["4", "5", "6"]`.
- **`engineTypes`** *(array of strings)* — Optional FAA engine type codes (`"1"` Reciprocating, `"2"` Turbo-prop, `"3"` Turbo-shaft, `"4"` Turbo-jet, `"5"` Turbo-fan, etc.). Default: `[]` (all engine types).
- **`includeIndividualOwners`** *(boolean)* — Defaults to `false` to exclude individual consumer registrants and co-owners (`TYPE REGISTRANT` 1, 4 and 9) and return only business/institutional registrant types (2, 3, 5, 7 and 8).
- **`nNumbers`** *(array of strings)* — Optional list of specific N-Numbers (with or without leading `"N"`, e.g. `["N10004", "101UV"]`) to filter from the bulk file. Default: `[]`.
- **`maxItems`** *(integer)* — Maximum rows to return. Default: `200`.

#### Example input JSON

```json
{
  "registrationSignal": "EXPIRING_SOON",
  "states": ["AZ", "TX"],
  "aircraftTypes": ["4", "5", "6"],
  "engineTypes": [],
  "includeIndividualOwners": false,
  "nNumbers": [],
  "maxItems": 200
}
```

#### Example run options (default max charge $50)

Set a default maximum charge of **$50** (`"maxTotalChargeUsd": 50`) in your run options:

```json
{
  "maxTotalChargeUsd": 50
}
```

### Output

Results are deduplicated by `nNumber + serialNumber` and sorted by the signal's primary date (`expirationDate` ascending for `EXPIRING_SOON`; `certIssueDate` descending for `NEWLY_ISSUED_30_DAYS` and `ALL_ACTIVE`; `cancelDate` descending for `RECENTLY_DEREGISTERED_30_DAYS`).

| Field | Type | Description |
|---|---|---|
| `nNumber` | `string` | FAA registration number with leading `"N"`. |
| `serialNumber` | `string \| null` | Airframe manufacturer serial number. |
| `manufacturer` | `string \| null` | Aircraft manufacturer name (`ACFTREF.txt`). |
| `model` | `string \| null` | Aircraft model designation (`ACFTREF.txt`). |
| `aircraftType` | `string \| null` | Decoded aircraft category (e.g. `Fixed Wing Multi-Engine`, `Rotorcraft`). |
| `engineType` | `string \| null` | Decoded engine category (e.g. `Turbo-fan`, `Turbo-prop`, `Reciprocating`). |
| `engineManufacturer` | `string \| null` | Engine manufacturer name (`ENGINE.txt`). |
| `engineModel` | `string \| null` | Engine model designation (`ENGINE.txt`). |
| `yearManufactured` | `integer \| null` | Four-digit manufacturing year. |
| `registrantType` | `string \| null` | Decoded registrant type (`Corporation`, `LLC`, `Partnership`, `Co-Owned`, `Government`, `Individual`, etc.). |
| `registrantName` | `string \| null` | Registered owner name. |
| `street` | `string \| null` | Mailing street address line 1. |
| `street2` | `string \| null` | Mailing street address line 2. |
| `city` | `string \| null` | Mailing city. |
| `state` | `string \| null` | Two-letter state code. |
| `zip` | `string \| null` | Mailing postal ZIP code. |
| `country` | `string \| null` | Two-letter country code. |
| `certIssueDate` | `string \| null` | Certificate issue date (`YYYY-MM-DD`). |
| `lastActionDate` | `string \| null` | Last registration action date (`YYYY-MM-DD`). |
| `expirationDate` | `string \| null` | Registration expiration date (`YYYY-MM-DD`). |
| `daysUntilExpiration` | `integer \| null` | Calendar days until `expirationDate`. |
| `airworthinessDate` | `string \| null` | Airworthiness certificate date (`YYYY-MM-DD`). |
| `cancelDate` | `string \| null` | Deregistration cancellation date (`YYYY-MM-DD`, populated for `DEREG.txt` rows). |
| `statusCode` | `string \| null` | Raw FAA status code (`V` = Valid, etc.). |
| `registrationSignal` | `string` | Registration signal matched for this row. |
| `faaUrl` | `string` | Direct link to the FAA Aircraft Inquiry N-Number record. |

#### Sample output row (synthetic example)

```json
{
  "nNumber": "N999EX",
  "serialNumber": "525B-0999",
  "manufacturer": "TEXTRON AVIATION INC",
  "model": "525B",
  "aircraftType": "Fixed Wing Multi-Engine",
  "engineType": "Turbo-fan",
  "engineManufacturer": "WILLIAMS",
  "engineModel": "FJ44 SERIES",
  "yearManufactured": 2020,
  "registrantType": "LLC",
  "registrantName": "EXAMPLE FLIGHT HOLDINGS LLC",
  "street": "100 AVIATION WAY STE 200",
  "street2": null,
  "city": "SCOTTSDALE",
  "state": "AZ",
  "zip": "85260",
  "country": "US",
  "certIssueDate": "2020-01-15",
  "lastActionDate": "2023-01-23",
  "expirationDate": "2027-01-31",
  "daysUntilExpiration": 99,
  "airworthinessDate": "2020-01-10",
  "cancelDate": null,
  "statusCode": "V",
  "registrationSignal": "EXPIRING_SOON",
  "faaUrl": "https://registry.faa.gov/AircraftInquiry/Search/NNumberResult?nNumberTxt=999EX"
}
```

### How pricing works

Pay per result: $0.003 per aircraft record returned ($3.00 per 1,000), plus a tiny Apify actor-start fee. You only pay for rows returned. Set `"maxTotalChargeUsd": 50` in your run options to cap spend automatically.

### Privacy and intended use

This Actor returns public government records that include registered owner names and addresses, some of them private individuals. Use them only for lawful purposes such as research, due diligence, compliance and relevant B2B outreach. Do not spam, harass or resell personal data, and follow the laws that apply to you (for example CAN-SPAM, TCPA, GDPR/CCPA and state privacy laws) plus any terms set by the source agency. You are responsible for how you use the data. To report a data or privacy issue, open a ticket in this Actor's Issues tab.

### Data source and terms

- **Official source:** [FAA Releasable Aircraft Database Download](https://www.faa.gov/licenses_certificates/aircraft_certification/aircraft_registry/releasable_aircraft_download).
- **Update frequency:** Published and updated daily by the FAA Civil Aviation Registry (federal public data).
- **Affiliation disclaimer:** This Actor is an independent tool and is **not affiliated with or endorsed by the Federal Aviation Administration (FAA) or the U.S. Department of Transportation**.

### Compliance

The FAA Releasable Aircraft Registry publishes mailing addresses for registered aircraft owners as a matter of federal public record (it does not contain phone numbers or email addresses). `includeIndividualOwners` defaults to `false` so individual consumer registrants are excluded unless explicitly requested. Buyers are responsible for complying with the Telephone Consumer Protection Act (TCPA), the National Do-Not-Call Registry, the CAN-SPAM Act, and all applicable federal and state privacy laws before any outreach. Do not use this Actor for consumer or individual targeting.

### Limits and FAQ

- **Why do FAA registrations expire on the last day of the month?**
  Under 14 CFR § 47.40, FAA aircraft registration certificates expire on the last calendar day of the month. Consequently, `EXPIRING_SOON` includes through the last day of the calendar month at the end of the window.
- **Why does the Actor download the bulk ZIP instead of scraping `aircraftinquiry` web pages?**
  The official daily bulk file (`ReleasableAircraft.zip`) is faster, complete across all ~300,000+ registrations, and avoids hammering individual web inquiry pages.

### Changelog

- **v0.1 (2026-10-23):** Initial release with streaming bulk ZIP download, `MASTER.txt` / `DEREG.txt` / `ACFTREF.txt` / `ENGINE.txt` join, and privacy-first registrant filtering.

# Actor input Schema

## `registrationSignal` (type: `string`):

Select the registration lifecycle signal to filter on.

## `expiringWithinDays` (type: `integer`):

Used with the Expiring soon signal. FAA registrations expire on the last day of the month and many owners renew months early, so 180 days gives a much fuller list than 90.

## `states` (type: `array`):

Two-letter US state codes for registrant mailing address (e.g. \['AZ', 'TX']). Leave empty for all states.

## `aircraftTypes` (type: `array`):

FAA aircraft type codes: 4 (Fixed Wing Single-Engine), 5 (Fixed Wing Multi-Engine), 6 (Rotorcraft), 1 (Glider), 2 (Balloon), 3 (Blimp/Dirigible), 7 (Weight-Shift-Control), 8 (Powered Parachute), 9 (Gyroplane), H (Hybrid Lift), O (Other).

## `engineTypes` (type: `array`):

Optional FAA engine type codes: 1 (Reciprocating), 2 (Turbo-prop), 3 (Turbo-shaft), 4 (Turbo-jet), 5 (Turbo-fan). Leave empty for all engine types.

## `includeIndividualOwners` (type: `boolean`):

Defaults to false, which excludes individual owners and co-owner registrations (TYPE REGISTRANT 1, 4 and 9, which are almost always people). Only corporations, LLCs, partnerships, non-citizen corporations and government registrants (2, 3, 5, 7, 8) are returned.

## `nNumbers` (type: `array`):

Optional list of exact N-Numbers (with or without leading 'N', e.g. \['N100', '101UV']) to look up from the bulk file.

## `maxItems` (type: `integer`):

Maximum number of aircraft records to return.

## Actor input object example

```json
{
  "registrationSignal": "EXPIRING_SOON",
  "expiringWithinDays": 180,
  "states": [
    "AZ",
    "TX"
  ],
  "aircraftTypes": [
    "4",
    "5",
    "6"
  ],
  "engineTypes": [],
  "includeIndividualOwners": false,
  "nNumbers": [],
  "maxItems": 200
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "registrationSignal": "EXPIRING_SOON",
    "states": [
        "AZ",
        "TX"
    ],
    "aircraftTypes": [
        "4",
        "5",
        "6"
    ],
    "engineTypes": [],
    "includeIndividualOwners": false,
    "nNumbers": [],
    "maxItems": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("groundplanes/faa-aircraft-registry-owners").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "registrationSignal": "EXPIRING_SOON",
    "states": [
        "AZ",
        "TX",
    ],
    "aircraftTypes": [
        "4",
        "5",
        "6",
    ],
    "engineTypes": [],
    "includeIndividualOwners": False,
    "nNumbers": [],
    "maxItems": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("groundplanes/faa-aircraft-registry-owners").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "registrationSignal": "EXPIRING_SOON",
  "states": [
    "AZ",
    "TX"
  ],
  "aircraftTypes": [
    "4",
    "5",
    "6"
  ],
  "engineTypes": [],
  "includeIndividualOwners": false,
  "nNumbers": [],
  "maxItems": 200
}' |
apify call groundplanes/faa-aircraft-registry-owners --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,groundplanes/faa-aircraft-registry-owners"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/thHZh3E3dlPVMZnVm/builds/YLgoaTRbFU4tR8Qj2/openapi.json
