Firearms License Verification
Verify ATF Federal Firearms Licenses (FFL), validate license types and expiration, and screen holders against federal watchlists — all through the ComplianceGrid API.
Use Cases
Marketplace Verification
Verify FFL status before allowing firearms-related listings or transactions on your platform.
Distributor Onboarding
Validate dealer FFLs before establishing wholesale accounts.
Transfer Compliance
Ensure the receiving FFL is valid and authorized for the specific firearm type before shipping.
Periodic Monitoring
Monitor FFL expiration dates and re-verify quarterly to catch revocations.
FFL License Types
ATF issues several types of Federal Firearms Licenses. The license type determines what activities the holder is authorized to perform.
| Type | Description |
|---|---|
| 01 | Dealer in Firearms Other Than Destructive Devices (includes Gunsmith) |
| 02 | Pawnbroker in Firearms Other Than Destructive Devices |
| 03 | Collector of Curios and Relics |
| 06 | Manufacturer of Ammunition |
| 07 | Manufacturer of Firearms Other Than Destructive Devices |
| 08 | Importer of Firearms Other Than Destructive Devices |
| 09 | Dealer in Destructive Devices |
| 10 | Manufacturer of Destructive Devices |
| 11 | Importer of Destructive Devices |
Verification Workflow
Step 1: FFL License Search
Search ATF's Federal Firearms License database by state, city, license type, or business name. Verify the dealer or manufacturer holds a valid, active FFL.
Step 2: License Validation
Validate the specific FFL number, check expiration date, license type (01–11), and ensure the license covers the intended activity (dealing, manufacturing, importing).
Step 3: OFAC / Watchlist Screening
Screen the FFL holder and associated individuals against OFAC SDN, BIS Entity List, and other federal watchlists.
Step 4: Geographic Compliance
Verify the FFL's premise address matches the transaction location. ATF requires all firearms transactions to occur at the licensed premises.
Step 1: Search FFL Database
import ComplianceGrid from "@compliancegrid/sdk";
const cg = new ComplianceGrid({
apiKey: process.env.COMPLIANCEGRID_API_KEY,
});
// Search FFLs by state and city
const ffls = await cg.firearms.searchFFL({
state: "TX",
city: "Dallas",
licenseType: "01", // Dealers
limit: 10,
});
console.log(`Found ${ffls.data.totalResults} dealers in Dallas, TX`);
for (const ffl of ffls.data.results) {
console.log(` ${ffl.businessName}`);
console.log(` License: ${ffl.licenseNumber}`);
console.log(` Type: ${ffl.licenseType} — ${ffl.licenseTypeDescription}`);
console.log(` Expires: ${ffl.expirationDate}`);
console.log(` Address: ${ffl.premiseAddress}`);
}
// Search by business name
const specific = await cg.firearms.searchFFL({
businessName: "Acme Firearms",
state: "TX",
});Step 2: Validate Specific FFL
// Validate a specific FFL number
const validation = await cg.firearms.validateFFL({
licenseNumber: "5-75-XXX-XX-XX-XXXXX",
});
const ffl = validation.data;
console.log("Business:", ffl.businessName);
console.log("License #:", ffl.licenseNumber);
console.log("Type:", ffl.licenseType);
console.log("Status:", ffl.status); // "ACTIVE" | "EXPIRED" | "REVOKED"
console.log("Expiration:", ffl.expirationDate);
// Check if valid for the intended transaction
const isActive = ffl.status === "ACTIVE";
const isDealer = ["01", "02"].includes(ffl.licenseType);
const isNotExpired = new Date(ffl.expirationDate) > new Date();
if (isActive && isDealer && isNotExpired) {
console.log("FFL is valid for retail firearm transfers");
} else {
console.error("FFL validation FAILED:");
if (!isActive) console.error(" - License is not active");
if (!isDealer) console.error(" - License type does not allow dealing");
if (!isNotExpired) console.error(" - License has expired");
}Step 3: Watchlist Screening
// Screen the FFL holder against federal watchlists
const screening = await cg.compliance.screenParties([
{
name: ffl.businessName,
country: "US",
type: "COUNTERPARTY",
},
]);
if (screening.data.overallResult === "HIT") {
console.error("WATCHLIST HIT — do not proceed with transaction");
for (const match of screening.data.results[0].matches) {
console.log(` ${match.source}: ${match.name} (score: ${match.matchScore})`);
}
} else {
console.log("Watchlist screening CLEAR");
}Complete Verification Function
async function verifyFFL(licenseNumber: string) {
// Step 1: Validate the FFL
const ffl = await cg.firearms.validateFFL({ licenseNumber });
if (ffl.data.status !== "ACTIVE") {
return {
valid: false,
reason: `FFL status is ${ffl.data.status}`,
ffl: ffl.data,
};
}
if (new Date(ffl.data.expirationDate) <= new Date()) {
return {
valid: false,
reason: "FFL has expired",
ffl: ffl.data,
};
}
// Step 2: Screen against watchlists
const screening = await cg.compliance.screenParties([
{ name: ffl.data.businessName, country: "US", type: "COUNTERPARTY" },
]);
if (screening.data.overallResult === "HIT") {
return {
valid: false,
reason: "Watchlist match found",
ffl: ffl.data,
screeningResults: screening.data,
};
}
return {
valid: true,
ffl: ffl.data,
screeningResults: screening.data,
verifiedAt: new Date().toISOString(),
};
}
// Usage
const result = await verifyFFL("5-75-XXX-XX-XX-XXXXX");
if (result.valid) {
console.log("FFL VERIFIED — safe to proceed");
} else {
console.error("FFL REJECTED:", result.reason);
}Regulatory Notes
- • ATF regulations require all interstate firearm transfers to go through an FFL holder.
- • FFL verification should be performed before every transaction, not just at onboarding.
- • FFL data is sourced from ATF's public FFL listing (updated monthly).
- • This API does not replace the requirement to maintain a bound book (Form 4473) or conduct NICS checks.
- • Always consult ATF regulations and your compliance team for specific requirements.
Party screening through AES filing
Full endpoint documentation