How to Verify US Security Guard Licenses via API (Python, JavaScript, cURL)
Tags: api, python, javascript, security, webdev
Your company just onboarded a new security guard. Their license looks real. But is it?
Every US state runs its own licensing database through its own portal, in its own format, with its own search UX. Verifying a single license manually means visiting the right state website, entering data, and reading the result — then doing it again for every guard, every renewal, every hire. If your business hires or manages security personnel at any scale, this is a real problem.
The Security Guard License Verification API solves it: one endpoint, standardized JSON response, across California, Illinois, New York, and Oregon. California lookups hit a local copy of 541,000+ BSIS records for sub-100ms responses. Other states query official portals in real time.
In this post I'll show you how to verify a license in three lines of code.
Quickstart
The API is listed on RapidAPI. Subscribe for free (10 requests/month on the Basic tier), grab your key, and you're live.
Base URL (via RapidAPI):
https://security-guard-license-verification.p.rapidapi.com
Required headers:
X-RapidAPI-Key: YOUR_RAPIDAPI_KEY
X-RapidAPI-Host: security-guard-license-verification.p.rapidapi.com
Verify by License Number
This is the most common use case — you have a license number and want to confirm it's valid, active, and belongs to who you think it does.
cURL
curl -X GET \
"https://security-guard-license-verification.p.rapidapi.com/verify/license?state=CA&license_number=2623" \
-H "X-RapidAPI-Key: YOUR_RAPIDAPI_KEY" \
-H "X-RapidAPI-Host: security-guard-license-verification.p.rapidapi.com"
Python
import requests
url = "https://security-guard-license-verification.p.rapidapi.com/verify/license"
headers = {
"X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
"X-RapidAPI-Host": "security-guard-license-verification.p.rapidapi.com"
}
params = {
"state": "CA",
"license_number": "2623"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
if data.get("found") is False:
print(f"License not found: {data['message']}")
else:
print(f"Name: {data['name']}")
print(f"Status: {data['status']}")
print(f"License type: {data['license_type']}")
print(f"Expires: {data['expiry_date']}")
JavaScript (fetch)
const response = await fetch(
"https://security-guard-license-verification.p.rapidapi.com/verify/license?state=CA&license_number=2623",
{
headers: {
"X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
"X-RapidAPI-Host": "security-guard-license-verification.p.rapidapi.com",
},
}
);
const data = await response.json();
if (data.found === false) {
console.log("License not found:", data.message);
} else {
console.log(`${data.name} — ${data.status} (expires ${data.expiry_date})`);
}
Response Format
A found license returns:
{
"license_number": "2623",
"name": "JOHN SMITH",
"status": "Active",
"state": "CA",
"license_type": "Security Guard",
"expiry_date": "2026-12-31",
"issue_date": "2022-01-15",
"employer": null,
"source_url": "https://www.bsis.ca.gov/...",
"retrieved_at": "2026-07-26T18:00:00+00:00",
"cached": true
}
If the license isn't found:
{
"found": false,
"license_number": "9999999",
"state": "CA",
"message": "No license found matching the provided number.",
"retrieved_at": "2026-07-26T18:00:00+00:00",
"cached": false
}
The status field uses the official state value — Active, Inactive, Expired, Suspended — so you can gate logic on it directly.
Search by Name
If you only have a person's name, use the name search endpoint. It returns up to 50 matches and supports an optional license number to cross-reference.
import requests
url = "https://security-guard-license-verification.p.rapidapi.com/verify/name"
headers = {
"X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
"X-RapidAPI-Host": "security-guard-license-verification.p.rapidapi.com"
}
params = {
"state": "NY",
"last_name": "Smith",
"first_name": "John",
"limit": 10
}
response = requests.get(url, headers=headers, params=params)
results = response.json()
if isinstance(results, list):
for r in results:
print(f"{r['name']} | {r['license_number']} | {r['status']} | expires {r['expiry_date']}")
else:
print("Not found:", results["message"])
Supported States
| State | Source | Response time |
|---|---|---|
| CA | Local DB (541,000+ BSIS records, refreshed monthly) | ~50ms |
| IL | IDFPR live portal | ~1–2s |
| NY | NY DOS live portal | ~1–2s |
| OR | DPSST PS IRIS live portal | ~1–2s |
More states are in progress.
Use Cases
Security staffing agencies — Automate license verification as part of your onboarding workflow. Check every candidate's license before their first shift.
HR and background check platforms — Add security guard license verification alongside your existing criminal background check, employment verification, and credential checks.
Property management companies — Many security contracts require licensed personnel on-site. Verify the guards assigned to your properties automatically.
Hiring software — Surface a license validity badge on applicant profiles. Flag expired licenses before they become a liability.
Pricing
Available on RapidAPI:
| Plan | Price | Requests |
|---|---|---|
| Basic | Free | 10/month |
| Pro | $29.99/month | 25/month |
| Ultra | $99/month | 100/month |
| Mega | $299/month | 500/month + $0.50/overage |
Get Started
Search "Security Guard License Verification" on RapidAPI, or find it at:
https://rapidapi.com/operational-systems-llc-operational-systems-llc-default/api/security-guard-license-verification-api
The free tier gives you 10 requests a month to test your integration. Pro is designed for real workflows. If you need volume beyond Mega, reach out directly.
Questions or issues? The spec is public at https://api.operational-systems.com/sg/openapi.json.
Top comments (0)