# FCC Amateur Radio License Search (`automation-lab/fcc-amateur-radio-license-search`) Actor

Search official FCC amateur-radio licenses by call sign, public licensee name, state, city, and status. Export class, dates, FRN, public identity and location, trustee fields, and ULS identifiers.

- **URL**: https://apify.com/automation-lab/fcc-amateur-radio-license-search.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## FCC Amateur Radio License Search

Search and export **FCC amateur radio license** records by exact call sign, public licensee name, state, city, status, or a combination of filters.

The Actor reads the official Federal Communications Commission Universal Licensing System (ULS) amateur-license archive. It returns current call signs, operator classes, license status, grant and expiry dates, public FRN, public licensee identity and address, previous call-sign fields, trustee fields, and source identifiers in consistent JSON records.

Use it to verify one callsign, refresh a club roster, review amateur credentials, build a geographic license list, or load official FCC data into a spreadsheet or data pipeline.

### What does this FCC amateur radio license search do?

Each run downloads the official FCC complete amateur-license archive, streams the relevant ULS files, joins license, entity, and amateur-operator records by FCC unique system identifier, applies your filters, and saves only matching records.

You can:

- look up one or many exact amateur call signs;
- find public license records whose licensee name contains a phrase;
- build active-license lists for states, territories, or cities;
- combine call sign, name, location, and status filters;
- export normalized results as JSON, CSV, Excel, XML, or RSS;
- schedule the same query to refresh credential or roster data;
- retrieve results through the Apify API or MCP server.

This Actor is specifically scoped to amateur-radio licenses in the FCC archive. It does not mix commercial, aviation, marine, public-safety, broadcast, or experimental radio services into the output.

### Who is it for?

- **Amateur-radio clubs** refreshing member and trustee records.
- **Event coordinators** verifying call signs and operator classes.
- **Credentialing teams** checking public grant, expiry, and status information.
- **Market researchers** studying amateur-license distribution by location.
- **Journalists and researchers** working with attributable FCC ULS records.
- **Data engineers** loading official license snapshots into a warehouse.
- **Automation teams** scheduling recurring roster or compliance refreshes.

### Why use this Actor?

FCC ULS data is public, but its web search can be slow and its bulk files use separate record layouts. Building a reliable join requires knowledge of FCC record types and identifiers.

This Actor provides:

- a source-specific amateur-license product rather than a mixed wireless-license feed;
- official FCC bulk data with no private account, login, or API key;
- one typed output shape across license, entity, and amateur records;
- exact and combined filters applied before output is charged;
- bounded download retry behavior and explicit failures;
- direct HTTP access with no browser or paid proxy;
- stable source archive and record links for verification;
- `maxItems` control from 1 to 10,000 records.

### Official FCC source

The source is the FCC complete amateur-license ULS archive:

```text
https://data.fcc.gov/download/pub/uls/complete/l_amat.zip
```

The Actor joins these official record types:

| FCC record | Purpose |
| --- | --- |
| `HD` | Call sign, status, service code, grant date, expiry date, cancellation date, and file identifiers |
| `EN` | Public licensee/entity name, FRN, address, city, state, and ZIP code |
| `AM` | Amateur operator class, previous call sign/class, and trustee information |

The complete archive is a snapshot. `retrievedAt` records when the Actor processed it; FCC dates describe the license itself.

### Getting started

1. Open the Actor input page.
2. Enter at least one call sign, licensee-name phrase, state, or city.
3. Keep `statuses` set to `active`, or select other FCC statuses.
4. Set `maxItems` to the maximum records you need.
5. Click **Start**.
6. Open the **FCC amateur licenses** dataset view.
7. Export the results or consume them through the API.

A useful first run verifies a well-known real call sign:

```json
{
  "callSigns": ["K1JT"],
  "statuses": ["active"],
  "maxItems": 1
}
```

### Input parameters

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `callSigns` | string array | `[]` | Exact amateur call signs; matching is case-insensitive |
| `licenseeName` | string | empty | Case-insensitive substring of the public FCC entity or person name |
| `states` | string array | `[]` | Exact two-letter state or territory codes from the public license address |
| `cities` | string array | `[]` | Exact public license city names; matching is case-insensitive |
| `statuses` | enum array | `["active"]` | `active`, `expired`, `cancelled`, and/or `terminated` |
| `maxItems` | integer | `10` | Maximum matching records to save, from 1 to 10,000 |

You must provide at least one call sign, licensee name, state, or city. Unfiltered nationwide exports are intentionally rejected so an accidental run does not create a very large dataset.

Different filter fields use AND logic. Values inside one array use OR logic. For example, `states: ["NJ", "PA"]` matches either state, while adding `licenseeName: "TAYLOR"` limits the result to matching names in those states.

### Search examples

#### Verify an exact FCC call sign

```json
{
  "callSigns": ["K1JT"],
  "statuses": ["active"],
  "maxItems": 1
}
```

#### Find active amateur licenses in New Jersey

```json
{
  "states": ["NJ"],
  "statuses": ["active"],
  "maxItems": 25
}
```

#### Refresh a public name-and-state roster

```json
{
  "licenseeName": "TAYLOR",
  "states": ["NJ"],
  "statuses": ["active"],
  "maxItems": 50
}
```

#### Search two cities

```json
{
  "cities": ["PRINCETON", "TRENTON"],
  "states": ["NJ"],
  "statuses": ["active"],
  "maxItems": 100
}
```

### Output fields

| Field | Meaning |
| --- | --- |
| `uniqueSystemIdentifier` | FCC identifier used to join ULS records |
| `ulsFileNumber` | FCC ULS file number when present |
| `callSign` | Current amateur-radio call sign |
| `licenseStatus`, `licenseStatusCode` | Human-readable and raw FCC status |
| `radioServiceCode` | FCC amateur radio service code |
| `licenseClass`, `licenseClassCode` | Human-readable and raw operator class |
| `grantDate`, `expiryDate`, `cancellationDate` | Dates exactly as FCC supplies them |
| `licenseeName` | Public entity or licensee display name |
| `firstName`, `middleInitial`, `lastName`, `suffix` | Public person-name components when applicable |
| `entityTypeCode` | Raw FCC entity type code |
| `frn` | Public FCC Registration Number when supplied |
| `streetAddress`, `city`, `state`, `zipCode` | Public FCC license address fields |
| `previousCallSign`, `previousLicenseClassCode` | Prior amateur values when present |
| `trusteeCallSign`, `trusteeName` | Public trustee fields when present |
| `sourceArchiveUrl`, `sourceRecordUrl` | Official archive and ULS detail provenance |
| `retrievedAt` | ISO 8601 retrieval timestamp |

Fields that FCC does not publish for a record are `null`.

### Example output

This abbreviated record reflects current real output from the official FCC archive:

```json
{
  "uniqueSystemIdentifier": "234055",
  "ulsFileNumber": "9711188707",
  "callSign": "K1JT",
  "licenseStatus": "Active",
  "licenseStatusCode": "A",
  "radioServiceCode": "HA",
  "licenseClass": "Amateur Extra",
  "licenseClassCode": "E",
  "grantDate": "08/24/2017",
  "expiryDate": "11/18/2027",
  "licenseeName": "TAYLOR JR, JOSEPH H",
  "frn": "0016699761",
  "city": "PRINCETON",
  "state": "NJ",
  "zipCode": "08540",
  "sourceRecordUrl": "https://wireless2.fcc.gov/UlsApp/UlsSearch/license.jsp?licKey=234055"
}
```

### How much does it cost to search FCC amateur radio licenses?

The Actor uses pay-per-event pricing:

- one `start` event is charged once per run;
- one `item` event is charged for each matching license saved;
- no item event is charged for rejected source rows, duplicates, empty results, or failed downloads.

At the BRONZE rate, a run starts at **$0.005** and each saved license is **$0.008932**. That makes one exact lookup about **$0.013932**, 25 records about **$0.2283**, and 100 records about **$0.8982**. Item rates decrease across the six Apify usage tiers, from **$0.010272** at FREE to **$0.002501** at DIAMOND.

Set `maxItems` to the records you actually need. The live Apify pricing panel is the source of truth and applies your account's usage tier.

### Scheduled roster and credential refreshes

Create an Apify schedule with an exact query to obtain a new source snapshot daily, weekly, or monthly.

A downstream workflow can:

1. run the Actor with stable filters;
2. fetch the newest dataset;
3. key records by `uniqueSystemIdentifier` or `callSign`;
4. compare status, class, expiry, name, or location with the prior dataset;
5. notify a reviewer when a value changes;
6. retain run and retrieval timestamps for an audit trail.

The Actor returns current snapshots. It does not store historical comparisons or send alerts itself.

### Spreadsheet and data-pipeline integration

Results can flow to Google Sheets, Zapier, Make, webhooks, cloud storage, or a database using standard Apify integrations.

Recommended stable key:

```text
uniqueSystemIdentifier
```

A call sign is useful for display and lookup, but FCC records can include previous call-sign information. Preserve the FCC identifier when building longitudinal data.

### Run with the Apify API using cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~fcc-amateur-radio-license-search/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "callSigns": ["K1JT"],
    "statuses": ["active"],
    "maxItems": 1
  }'
```

For synchronous dataset output, use the `run-sync-get-dataset-items` endpoint when your client timeout can accommodate downloading and scanning the official archive.

### Run with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/fcc-amateur-radio-license-search').call({
    states: ['NJ'],
    statuses: ['active'],
    maxItems: 25,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Run with Python

```python
from apify_client import ApifyClient

client = ApifyClient(token="YOUR_APIFY_TOKEN")
run = client.actor("automation-lab/fcc-amateur-radio-license-search").call(run_input={
    "licenseeName": "TAYLOR",
    "states": ["NJ"],
    "statuses": ["active"],
    "maxItems": 50,
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with MCP and AI agents

Add the Actor to Claude Code through the Apify MCP server:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/fcc-amateur-radio-license-search"
```

#### Claude Desktop

Add this remote server in Claude Desktop's MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/fcc-amateur-radio-license-search"
    }
  }
}
```

#### Cursor

Open **Settings → Tools & MCP → Add custom MCP** in Cursor and use the same `https://mcp.apify.com?tools=automation-lab/fcc-amateur-radio-license-search` URL.

#### VS Code

Add the remote MCP URL to your VS Code MCP configuration, then enable the `automation-lab/fcc-amateur-radio-license-search` tool for your agent session.

Example prompts:

- “Verify K1JT in the FCC amateur-license records and summarize the class and expiry.”
- “Find 25 active New Jersey amateur licenses and return call sign, class, city, and expiry.”
- “Run the Taylor/New Jersey roster input and compare it with the dataset from last month.”

Your agent needs access to your Apify account and is subject to the Actor's input and pricing controls.

### Performance, limits, and failure behavior

- The official complete archive is about 200 MB compressed and changes over time.
- A typical lookup spends most of its runtime downloading and streaming that archive.
- Broad state filters use more memory than an exact call-sign or name lookup.
- The Actor retries one transient archive-download failure, then fails clearly.
- A valid query with no current matches succeeds with an empty dataset.
- Invalid filters fail before downloading the archive.
- `maxItems` limits saved matches, not source rows inspected.
- The Actor uses no browser, proxy, account, CAPTCHA service, or private FCC endpoint.

For large scheduled jobs, allow several minutes of timeout even when the output limit is small.

### Troubleshooting

#### Why did I get no results?

Check spelling and filter combinations. Call signs are exact. Cities and states are exact but case-insensitive. Licensee names use substring matching. A record may also be excluded by the default `active` status filter.

Try removing one filter at a time, or include the relevant non-active status.

#### Why does an exact lookup still take time?

The Actor uses the complete official FCC archive so all supported filter modes share the same authoritative source. It must download and scan the archive even for one call sign.

#### Why is a field null?

FCC record layouts are sparse. `null` means the selected archive record did not include that field; it is not replaced with a guess.

#### Does this search FCC IDs for electronic devices?

No. “FCC ID” device authorization searches are a different FCC system. This Actor searches ULS amateur-radio licenses and their public FRN/ULS identifiers.

### Responsible use and legality

The Actor accesses public FCC ULS bulk data without authentication. It is unofficial and is not affiliated with or endorsed by the Federal Communications Commission.

Public availability does not remove your obligations. Use records for lawful verification, research, and operational purposes. Apply appropriate retention, access controls, data-minimization, and review procedures when processing personal information. Do not use the output for harassment, discrimination, unlawful profiling, or unsolicited abuse.

FCC remains the authoritative source. Verify consequential decisions against the linked source record and applicable regulations.

### FAQ

#### Does it include every FCC wireless license?

No. It intentionally searches the FCC amateur-license archive only.

#### Can I search several call signs at once?

Yes. Add up to 1,000 values to `callSigns`; `maxItems` still controls saved output.

#### Can I search by county or coordinates?

Not currently. The supported public location filters are exact city and two-letter state/territory code.

#### Is the data real-time?

No. Results reflect the complete archive served by FCC at run time. They are current to that source snapshot, not a transactional event feed.

#### Does it expose private FCC information?

No. It emits fields present in the public ULS archive. Users remain responsible for lawful handling.

#### Can it monitor changes automatically?

Apify can schedule recurring runs. A downstream workflow must compare datasets and send notifications; the Actor itself returns a snapshot.

#### What happens when FCC is unavailable?

The download is retried once. If the official archive remains unavailable or malformed, the run fails rather than returning stale or fabricated data.

### Related automation-lab Actors

For broader public-registry and verification workflows, explore these automation-lab Actors:

- [Texas Pharmacy License Lookup](https://apify.com/automation-lab/texas-pharmacy-license-lookup) for official Texas pharmacy and practitioner records.
- [Texas Insurance License Lookup](https://apify.com/automation-lab/texas-insurance-license-lookup) for Texas producer and adjuster credentials.
- [Domain Registration & RDAP Lookup](https://apify.com/automation-lab/domain-rdap-lookup) for authoritative domain registration records.

These are separate sources and record types. They are not merged into FCC output or charged by this Actor.

# Actor input Schema

## `callSigns` (type: `array`):

Exact FCC amateur-radio call signs, such as K1JT or W1AW. Combine with other filters to narrow results.

## `licenseeName` (type: `string`):

Case-insensitive substring of the public FCC entity or person name.

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

Two-letter codes from the public FCC license address, such as NJ, CA, or PR.

## `cities` (type: `array`):

Exact city names from the public FCC license address. Matching is case-insensitive.

## `statuses` (type: `array`):

Return only licenses with the selected FCC status. Leave empty to include every status.

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

Maximum matching FCC amateur-radio license records to save.

## Actor input object example

```json
{
  "callSigns": [
    "K1JT"
  ],
  "statuses": [
    "active"
  ],
  "maxItems": 10
}
```

# Actor output Schema

## `dataset` (type: `string`):

Matched FCC amateur-radio licenses in the default dataset.

# 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 = {
    "callSigns": [
        "K1JT"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/fcc-amateur-radio-license-search").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 = { "callSigns": ["K1JT"] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/fcc-amateur-radio-license-search").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 '{
  "callSigns": [
    "K1JT"
  ]
}' |
apify call automation-lab/fcc-amateur-radio-license-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/fcc-amateur-radio-license-search"
        }
    }
}

```

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/txRPVHopPswNJx5nI/builds/8Yd41wi5WoJUhytap/openapi.json
