# US Firearms License (FFL) & Gun Dealer Leads Scraper (`scrapesage/us-firearms-license-scraper`) Actor

Scrape the official ATF Federal Firearms Licensee (FFL) registry: 130k+ licensed gun dealers, gunsmiths, manufacturers, importers & pawnbrokers with business name, full address, phone, license type & lead score. Filter by state & type. B2B firearms-industry leads + new-license monitoring.

- **URL**: https://apify.com/scrapesage/us-firearms-license-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Agents, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.75 / 1,000 firearms licensee (ffl) records

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/actors/running/actors-in-store.md#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

## US Firearms License (FFL) & Gun Dealer Leads Scraper

> **Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by the U.S. Bureau of Alcohol, Tobacco, Firearms and Explosives (ATF) or any government body. All trademarks mentioned are the property of their respective owners. "ATF federal firearms licensee listings" is referenced only to describe the public data source this Actor collects from.

Turn the official **ATF Federal Firearms Licensee (FFL) registry** into a clean, structured B2B lead list. Pull **every active US firearms business — 77,000+ licensed dealers, gunsmiths, manufacturers, importers and pawnbrokers** — with business name, full premise & mailing address, phone, license type, region/district codes and a derived **lead score** — filtered by state, license type, name and more. No browser, no API key, no login.

### Why this FFL scraper?

- **The complete, official source.** Built directly on the ATF's monthly *Complete Listing of Federal Firearms Licensees* — the same authoritative file the firearms industry runs on — refreshed every month, fetched straight from atf.gov (no proxy needed).
- **Every license type, decoded.** Type 01 dealers/gunsmiths, 02 pawnbrokers, 06 ammunition manufacturers, 07 firearms manufacturers, 08 importers, and 09/10/11 destructive-device licensees — each mapped to a plain-English name and category.
- **Business-only by design.** The ATF business export already excludes Type 03 Curio & Relic collectors (individual hobbyists), so you get ~77K real firearms businesses, not hobbyists.
- **Real contact data.** Premise address, separate mailing address, and **voice phone** straight from the registry — not guessed, not enriched.
- **Lead scoring built in.** Every record carries a 0–100 `leadScore` and `leadSignals` (manufacturer, importer, has-phone, incorporated, separate storefront…) so the best prospects rise to the top.
- **Monitor mode.** Run on a schedule and emit **only newly licensed firearms businesses** since your last run — fresh purchase-intent leads, automatically.

### Use cases

- **Sell to gun stores & ranges** — POS / inventory / bound-book & compliance software, e-commerce platforms, payment processors, distributors and wholesalers.
- **Reach manufacturers & importers** — machinery, components, packaging, logistics, testing and regulatory-compliance vendors.
- **Insurance, finance & legal** — FFL insurance brokers, lenders and firearms-industry attorneys.
- **Market & competitive research** — count and map licensees by state, type, region or city.
- **Verification & enrichment** — match an existing list against the official registry and append license type, address and phone.

### How to use

1. Click **Try for free**.
2. Pick your filters — e.g. set **States** to `TX`, leave **Exclude collectors** on for a clean dealer list.
3. (Optional) Narrow by **License types** (e.g. `07` manufacturers), **Business name contains** (`pawn`, `tactical`), **With phone only**, etc.
4. Set **Max results** and run. Export to CSV, Excel, JSON or Google Sheets, or pull via API.

### Input

| Field | Type | Description |
|---|---|---|
| `states` | array | Premise state(s), two-letter USPS codes (e.g. `TX`, `FL`). Empty = all. |
| `cities` | array | Exact premise city names (case-insensitive). |
| `zipCodes` | array | Premise ZIP — full (`77002`) or prefix (`770`). |
| `licenseTypes` | array | ATF type codes: `01,02,03,06,07,08,09,10,11`. |
| `licenseCategories` | array | `Dealer`, `Pawnbroker`, `Manufacturer`, `Importer`, `Collector`. |
| `excludeCollectors` | boolean | Exclude Type 03 C\&R hobbyists (already absent from the ATF business export). Default **true**. |
| `businessOnly` | boolean | Only licensees with a business / trade name on file. |
| `withPhoneOnly` | boolean | Only licensees with a phone number. |
| `businessNameContains` | string | Substring match on the business / trade name. |
| `licenseeNameContains` | string | Substring match on the legal license name. |
| `nameContains` | string | Substring match on either name. |
| `regionCodes` / `countyCodes` | array | Advanced: ATF region / county codes from the FFL number. |
| `maxResults` | integer | Max records this run (ATF business export ≈ 77,000). |
| `sortBy` | string | `leadScore` (default), `businessName`, `state`, `source`. |
| `monitorMode` | boolean | Emit only FFLs new since the last run. |
| `monitorKey` | string | Names the monitor memory (one per saved watch). |
| `proxyConfiguration` | object | Optional. Direct download works; auto-falls back to Residential US if needed. |

#### Example input

```json
{
  "states": ["TX"],
  "licenseCategories": ["Manufacturer", "Importer"],
  "withPhoneOnly": true,
  "maxResults": 500,
  "sortBy": "leadScore"
}
```

### Output

Each record is one Federal Firearms Licensee. Example (abridged):

```json
{
  "fflNumber": "5-76-201-07-1A-04321",
  "licenseType": "07",
  "licenseTypeName": "Manufacturer of Firearms",
  "licenseCategory": "Manufacturer",
  "licenseeName": "ACME FIREARMS MFG INC",
  "businessName": "ACME DEFENSE",
  "displayName": "ACME DEFENSE",
  "entityType": "Corporation",
  "isBusiness": true,
  "isManufacturer": true,
  "premiseStreet": "9 FACTORY RD",
  "premiseCity": "Round Rock",
  "premiseState": "TX",
  "premiseZip": "78664",
  "premiseFullAddress": "9 FACTORY RD, Round Rock, TX 78664",
  "mailStreet": "PO BOX 5",
  "mailFullAddress": "PO BOX 5, Round Rock, TX 78680",
  "mailingSameAsPremise": false,
  "voicePhone": "(512) 555-0199",
  "phoneAreaCode": "512",
  "licenseRegionCode": "5",
  "licenseCountyCode": "201",
  "leadScore": 96,
  "leadSignals": ["manufacturer", "hasPhone", "hasBusinessName", "incorporated", "separateMailing"],
  "dataSourceMonth": "2026-06",
  "source": "ATF Federal Firearms Licensee registry"
}
```

Switch between the **FFL overview**, **Business leads**, and **Manufacturers & importers** dataset views to focus the columns you need.

### How much does it cost to scrape ATF federal firearms licensee listings?

This Actor uses Apify's **pay-per-event** pricing: you are charged only for the results it delivers, with no monthly rental and no start fee. The events it can charge are:

- **Firearms licensee (FFL) record** - One Federal Firearms Licensee record from the official ATF FFL registry: formatted FFL license number, license type (dealer, gunsmith, manufacturer, importer, pawnbroker, collector), licensee legal name, business/trade name, full premise and mailing address, voice phone, region/district/county codes, plus derived entity type, business classification, lead score and lead signals.

The current price of each event is shown on the **Pricing** tab of this page. Set a maximum total charge on the run if you want a hard cap on spend, and use the input limits to control how much the Actor fetches.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it monthly to capture newly licensed firearms businesses as fresh leads; perfect for CRM pipelines.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

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

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/us-firearms-license-scraper').call({
    states: ['TX'],
    licenseCategories: ['Manufacturer', 'Importer'],
    withPhoneOnly: true,
    maxResults: 500,
    sortBy: 'leadScore',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} FFL leads`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new FFL leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored state gets new licensees.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "find firearms manufacturers in Texas with a phone number" and let it run this scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **US B2B lead-gen stack** from official registries:

- **[FAA Aircraft Registry Scraper](https://apify.com/scrapesage/faa-aircraft-registry-scraper)** — aircraft owners (LLCs, corporations, individuals) with mailing address.
- **[FMCSA Trucking Scraper](https://apify.com/scrapesage/fmcsa-trucking-scraper)** — motor carriers, brokers & new authorities with contacts.
- **[FinCEN MSB Scraper](https://apify.com/scrapesage/fincen-msb-scraper)** — registered money services businesses.
- **[US Business Formation Scraper](https://apify.com/scrapesage/us-business-formation-scraper)** — newly registered LLCs & corporations.
- **[US Auto Dealer Scraper](https://apify.com/scrapesage/us-auto-dealer-scraper)** — licensed dealers, repair & body shops.
- **[US Contractor License Scraper](https://apify.com/scrapesage/us-contractor-license-scraper)** — licensed contractors by state.
- **[SBA Loan Leads Scraper](https://apify.com/scrapesage/sba-loan-leads-scraper)** — SBA 7(a)/504-financed small businesses.
- **[EPA ECHO Scraper](https://apify.com/scrapesage/epa-echo-scraper)** — regulated facilities, violations & penalties.

### Tips

- **Premium prospects**: filter **License categories** to `Manufacturer` + `Importer`, or sort by **Lead score**.
- **Recurring monitoring**: turn on **Monitor mode** and create a monthly [Schedule](https://docs.apify.com/platform/schedules) to capture only new licensees.
- **Proxies**: leave proxy **off** — the actor downloads the official ATF CSV directly. It only falls back to Residential (US) automatically if a direct download ever fails.
- **Collectors**: the ATF business export already omits Type 03 Curio & Relic hobbyists, so every record is a real firearms business.

### FAQ

**Where does the data come from?** The official ATF *Complete Listing of Federal Firearms Licensees*, published monthly by the U.S. Bureau of Alcohol, Tobacco, Firearms and Explosives. The actor always uses the most recent available month.

**Is this legal / public data?** Yes. The FFL listing is public data the ATF publishes specifically for industry and public use. You are responsible for using it in compliance with applicable laws and the ATF's terms.

**Does it include emails?** No — the ATF registry does not publish email addresses. It does include the licensee's **voice phone** and full mailing & premise addresses. Pair this with a website/email enrichment actor if you need emails.

**What's the difference between licensee name and business name?** `licenseeName` is the legal license holder (a person or company); `businessName` is the trade name / DBA when one is on file. `displayName` picks the best of the two.

**Can I export to Google Sheets, CSV, or Excel?** Yes — one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**How do I get only new licensees?** Turn on **Monitor mode** and run on a [Schedule](https://docs.apify.com/platform/schedules). The actor remembers which FFLs it has already returned and emits only new ones, tagged `monitorEvent: "new"`. This works alongside Apify Schedules — the schedule starts the run; monitoring decides what's new.

**A field is empty — why?** Fields are empty only when the ATF registry doesn't carry that value (e.g. no separate trade name, or no phone on file), never because the scraper skipped them.

### Data & lawful use

The source is an official public register, published so that anyone can consult it. Records can name individuals (individual licence holders), so the output may contain personal data even though it is public. If you are in the EU or UK you are the data controller for what you do with it: have a lawful basis, honour access and deletion requests, and respect the register's own reuse conditions, which can restrict marketing or commercial use.

Under [Apify's Standard Actor Contract](https://docs.apify.com/legal/standard-actor-contract), which governs your use of this Actor, you are the controller of any personal data in your input and output and scrapesage acts only as your processor: that data is processed solely to run your job, written only to your own Apify storage, never used for any other purpose and never shared onward. If you need help with a data-subject request that involves this Actor's output, open an issue on the Issues tab.

### Disclaimer

**This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by the U.S. Bureau of Alcohol, Tobacco, Firearms and Explosives (ATF) or any government body. All trademarks mentioned are the property of their respective owners.**

"ATF federal firearms licensee listings" is referenced only in a descriptive, nominative sense - to identify the public data source this Actor collects from. This Actor is not an official product or service of the U.S. Bureau of Alcohol, Tobacco, Firearms and Explosives (ATF) and is not authorised or certified by it. It collects only publicly available records; you are responsible for ensuring your use of that data complies with applicable laws, regulations and the source's own terms of use or reuse conditions.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

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

Filter by the licensee's premise (business) state — two-letter USPS codes, e.g. <code>TX</code>, <code>FL</code>, <code>CA</code>, <code>PA</code>. Leave empty for all 50 states + territories.

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

Filter by the premise city (case-insensitive, exact city name), e.g. <code>Houston</code>, <code>Miami</code>, <code>Phoenix</code>.

## `zipCodes` (type: `array`):

Filter by premise ZIP — full ZIP (<code>77002</code>) or a prefix (<code>770</code> matches all 770xx).

## `licenseTypes` (type: `array`):

Filter by ATF license type. Leave empty for all (collectors excluded by default — see below). Type 01 (dealers/gunsmiths) is by far the most common.

## `licenseCategories` (type: `array`):

Higher-level grouping of license types. <b>Dealer</b> = 01/09, <b>Pawnbroker</b> = 02, <b>Manufacturer</b> = 06/07/10, <b>Importer</b> = 08/11, <b>Collector</b> = 03. Combine with or instead of specific license types.

## `excludeCollectors` (type: `boolean`):

Type 03 (Collector of Curios & Relics) licenses are held by individual hobbyists, not businesses. Excluding them gives a clean B2B list of dealers, gunsmiths, manufacturers and importers. Turn off to include collectors.

## `businessOnly` (type: `boolean`):

Only return licensees that have a business / trade name (DBA) on file — a strong signal of an established, contactable business rather than a home-based individual.

## `withPhoneOnly` (type: `boolean`):

Only return licensees that have a voice phone number on file.

## `businessNameContains` (type: `string`):

Only return licensees whose business / trade name contains this text (case-insensitive), e.g. <code>pawn</code>, <code>guns</code>, <code>tactical</code>, <code>armory</code>, <code>sporting</code>.

## `licenseeNameContains` (type: `string`):

Only return licensees whose legal license name contains this text (case-insensitive) — e.g. an individual or company name.

## `nameContains` (type: `string`):

Match against EITHER the licensee legal name OR the business / trade name (case-insensitive). Use this for a broad keyword sweep.

## `regionCodes` (type: `array`):

Advanced: filter by the first digit of the FFL number — the ATF licensing region code. Most users should filter by state instead.

## `countyCodes` (type: `array`):

Advanced: filter by the ATF 3-digit county code as it appears in the FFL number. Most users should filter by state / city / ZIP instead.

## `maxResults` (type: `integer`):

Maximum number of FFL records to return in this run. The official ATF business export holds ~77,000 active licensees (dealers, gunsmiths, manufacturers, importers and pawnbrokers).

## `sortBy` (type: `string`):

<b>Lead score</b> = highest-value B2B licensees first (recommended). <b>Business name / State</b> = alphabetical. <b>Source order</b> = fastest on very large limits (file order).

## `monitorMode` (type: `boolean`):

Remember which FFLs were already returned (in a named key-value store) and emit ONLY licensees that are new since the last run — each tagged <code>monitorEvent: "new"</code>. The ATF refreshes the registry monthly; run this on a Schedule to capture newly-licensed firearms businesses as fresh leads. Works alongside Apify Schedules (the schedule starts the run; monitoring decides what's new).

## `monitorKey` (type: `string`):

Names the memory used by monitoring mode. Use a distinct key per saved watch (e.g. per state or license type) so different monitors don't share state.

## `proxyConfiguration` (type: `object`):

The actor downloads the official ATF CSV directly and needs no proxy in almost all cases — leave this off for the fastest, free download. If a direct download ever fails, the actor automatically retries through Apify Residential (US) proxy as a fallback. Enable a proxy here only if you specifically need to route traffic.

## Actor input object example

```json
{
  "states": [
    "TX"
  ],
  "excludeCollectors": true,
  "businessOnly": false,
  "withPhoneOnly": false,
  "maxResults": 1000,
  "sortBy": "leadScore",
  "monitorMode": false,
  "monitorKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All scraped Federal Firearms Licensee records in the default dataset, each with license type, licensee & business name, full address, phone and lead score.

# 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 = {
    "states": [
        "TX"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/us-firearms-license-scraper").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 = {
    "states": ["TX"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/us-firearms-license-scraper").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 '{
  "states": [
    "TX"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call scrapesage/us-firearms-license-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapesage/us-firearms-license-scraper"
        }
    }
}

```

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/9Fr3GAVUZrKRW0sIs/builds/KSKCr2zXBPlavik2g/openapi.json
