API documentation
A free, read-only REST API for published FFL transfer listings. No key required.
Overview
The API exposes dealers who have claimed and published their listing (verified transfer details only). Responses are JSON. The base URL is:
https://approvedffltransfers.com/api/v1/
No authentication is needed to read data. Sending an API key (see Rate limits) simply raises your request quota.
Endpoints
GET /api/v1/listings/
GET /api/v1/listings/<id>/
Filtering & search
Pass any of these as query parameters on /api/v1/listings/:
| Parameter | Type | Description |
|---|---|---|
state | string | Two-letter state code, e.g. MO |
city | string | Exact city match (case-insensitive) |
zip (+ radius) | string | ZIP-radius search — published dealers nearest the ZIP first. Default radius 10 mi; add radius (miles) to expand, e.g. ?zip=63090&radius=50 |
license | string | FFL number — full (5-43-219-01-8A-17323) or short region-district-sequence (5-43-17323) |
name | string | Business name contains (case-insensitive) |
accepts_transfers | boolean | true or false |
license_type | string | ATF license type, e.g. 01, 07 |
lat, lng, radius | number | Geographic radius search (radius in miles around lat/lng) |
page | integer | Page number (25 results per page) |
Example request
curl "https://approvedffltransfers.com/api/v1/listings/?state=MO&accepts_transfers=true"
Example response
{
"count": 42,
"next": "https://approvedffltransfers.com/api/v1/listings/?page=2&state=MO",
"previous": null,
"results": [
{
"id": 128,
"license_number": "5-43-021-01-2K-04417",
"business_name": "Example Gun Works",
"street": "100 Main St",
"city": "Saint Charles",
"state": "MO",
"zip": "63301",
"license_type": "01",
"accepts_transfers": true,
"public_phone": "636-555-0142",
"website": "https://example-gun-works.com",
"policies": "FFL transfers accepted Tue-Sat. Bring a photo ID.",
"nfa_kiosk": true,
"nfa_kiosk_fee": "30.00",
"fees": [
{ "category": "standard", "fee": "25.00", "notes": "" },
{ "category": "nfa", "fee": "75.00", "notes": "" }
],
"hours": [
{ "weekday": "Tuesday", "open_time": "10:00:00", "close_time": "18:00:00", "by_appointment": false }
],
"closures": [
{ "label": "Christmas Day", "start_date": "2026-12-25", "end_date": "2026-12-25",
"is_closed": true, "open_time": null, "close_time": null }
],
"excluded_carriers": ["USPS"],
"delivery_instructions": [
{ "carrier": "UPS", "instructions": "Ship to PO Box 123, Saint Charles MO 63301" }
],
"is_stale": false,
"last_verified_at": "2026-05-21T15:04:00Z"
}
]
}
Response fields
license_number | ATF license number (15-char dashed form) |
accepts_transfers | true / null (unknown) — dealers who explicitly do not accept transfers are excluded from results |
nfa_kiosk / nfa_kiosk_fee | eForm 4 fingerprint kiosk availability and optional fee |
fees[] | category (standard, nfa), fee, notes |
hours[] | weekday (day name, e.g. "Monday"), open_time, close_time, by_appointment |
closures[] | label (e.g. "Christmas Day"), start_date, end_date, is_closed, special open_time/close_time |
excluded_carriers[] | Carrier names the dealer cannot accept deliveries from |
delivery_instructions[] | carrier, instructions — carrier-specific shipping instructions (e.g. "USPS to our PO Box") |
is_stale | Listing flagged as possibly outdated |
last_verified_at | When the dealer last confirmed details (ISO 8601) |
Pagination
Results are paginated 25 per page. Use the next and
previous URLs in the response, or pass ?page=N.
Rate limits
Limits are enforced per client. Anonymous traffic is throttled; a valid
X-API-Key header raises your tier:
| Tier | Limit |
|---|---|
| Anonymous | 60 requests / minute, 1,000 / day |
| Key — Basic | 300 requests / minute |
| Key — Partner | 1,200 requests / minute |
curl -H "X-API-Key: YOUR_KEY" "https://approvedffltransfers.com/api/v1/listings/"
Need a key? Contact us — keys are issued for free to high-volume integrators.
Notes
- The API only returns verified, published listings — not the full ATF roster.
- Data is provided by dealers and may change; always confirm before shipping.
- Responses are cacheable; please cache on your side to stay within limits.