API docs
The licenscheck API
Contractor license records as reported by the state licensing boards, with each contractor's licenses linked across states. One base URL, JSON everywhere, no SDK needed.
https://api.licenscheck.com
Using Postman or generating a client? Download the OpenAPI spec, which describes every endpoint and field on this page.
Authentication
Search and license records need no key. The verdict and linked licenses need one, sent as a Bearer token:
Authorization: Bearer lc_live_…
Keys are shown once when issued, and we store only a hash of each, so keep yours somewhere safe. Get a key on the pricing page. To see the full verdict while browsing licenscheck.com, choose Have a key? Use it here on any locked section: the key is checked, then saved in that browser only (Sign out in the header forgets it), and each license you open counts as a verification, as it would through the API. A wrong or revoked key is refused with a 401 on every endpoint, even the free ones, so you notice a problem right away.
Rate limits
| Caller | Limit |
|---|---|
| With an API key | 300 requests a minute and 50,000 a day (UTC), per key. |
| Without a key | Limited per visitor: plenty for looking contractors up by hand. For anything automated, use an API key. |
Over a limit, the API answers 429 with a Retry-After header saying how many seconds to wait. Refused requests don't count against you, so a client that waits and retries gets straight back in.
Errors
Errors are JSON with a detail field saying what went wrong.
| Status | Meaning |
|---|---|
401 | The endpoint needs a key, or the key sent is wrong or revoked. |
404 | No license has that id. |
422 | A parameter is invalid, e.g. a search term under 3 characters, one without 3 letters or digits in a row, or an unknown state; detail says which. |
429 | Rate limit reached; retry after Retry-After seconds. |
Search licenses
GET/licensesFree · no key
Find licenses by contractor name, business name (DBA) or license number. A term is required: a state only narrows a search, so the API can't list a whole state. Results are ordered by name, and an exact license number is matched directly.
| Name | Type | Description |
|---|---|---|
q | string, required | Name, DBA or license number, 3-100 characters, with at least 3 letters or digits in a row. |
state | string | FL, CA, WA or VA, to search one state. |
limit | integer | Results per page, 1-100. Default 20. |
offset | integer | Results to skip, for paging. Default 0. |
Request
curl "https://api.licenscheck.com/licenses?q=southern%20folger&state=CA"
Response
{
"results": [
{
"id": "3a5cdcae-1af7-5c92-89d2-46fc2e0722af",
"contractor_name": "SOUTHERN FOLGER CONTRACTING INC",
"business_name": null,
"license_number": "1066907",
"license_type": "specialty_contractor",
"state": "CA",
"status": "active",
"issue_date": "2020-07-13",
"expiration_date": "2028-07-31",
"bond_number": "100504856",
"bond_amount": 25000.0,
"address": "PO BOX 58, NEWCASTLE, CA, 95658",
"phone": "9169006593",
"state_business_id": null,
"principal_name": null,
"last_verified_at": "2026-09-27T10:37:45.112910Z",
"delisted_at": null,
"created_at": "2026-09-15T00:00:26.940784Z"
}
],
"total": 1,
"total_is_exact": true
}
total is capped at 10,000; total_is_exact is false when there are more.
Get a license
GET/licenses/{id}Free · no key
One license's board record: its status, dates, bond, address, phone and principal as the board reports them.
| Name | Type | Description |
|---|---|---|
id | path, UUID | The license's id, from a search result. |
Request
curl https://api.licenscheck.com/licenses/3a5cdcae-1af7-5c92-89d2-46fc2e0722af
Response
{
"id": "3a5cdcae-1af7-5c92-89d2-46fc2e0722af",
"contractor_name": "SOUTHERN FOLGER CONTRACTING INC",
"business_name": null,
"license_number": "1066907",
"license_type": "specialty_contractor",
"state": "CA",
"status": "active",
"issue_date": "2020-07-13",
"expiration_date": "2028-07-31",
"bond_number": "100504856",
"bond_amount": 25000.0,
"address": "PO BOX 58, NEWCASTLE, CA, 95658",
"phone": "9169006593",
"state_business_id": null,
"principal_name": null,
"last_verified_at": "2026-09-27T10:37:45.112910Z",
"delisted_at": null,
"created_at": "2026-09-15T00:00:26.940784Z"
}
delisted_at is set when the board stops listing a license; status is then the last one it reported. last_verified_at is when we last saw the license in the board's data.
Classifications
GET/licenses/{id}/classificationsFree · no key
Every trade classification held under a license, primary first. Some boards list several per license.
| Name | Type | Description |
|---|---|---|
id | path, UUID | The license's id, from a search result. |
Request
curl https://api.licenscheck.com/licenses/3a7580f5-6ec6-569a-b302-b3b937c673fe/classifications
Response
{
"license_id": "3a7580f5-6ec6-569a-b302-b3b937c673fe",
"classifications": [
{
"id": "4b335aed-69c6-5642-901b-cfe6fa27d063",
"classification_code": "B",
"license_type": "building_contractor",
"is_primary": true,
"delisted_at": null
},
{
"id": "5a294f8d-763c-5237-bb75-2229304af229",
"classification_code": "C39",
"license_type": "roofing_contractor",
"is_primary": false,
"delisted_at": null
}
]
}
Continuing education
GET/licenses/{id}/continuing-educationFree · no key
Continuing-education courses completed under a license, most recent first, where the board publishes them.
| Name | Type | Description |
|---|---|---|
id | path, UUID | The license's id, from a search result. |
Request
curl https://api.licenscheck.com/licenses/67d66956-e16e-4bfb-85f1-02d10a9e58d6/continuing-education
Response
{
"license_id": "67d66956-e16e-4bfb-85f1-02d10a9e58d6",
"records": [
{
"id": "471de7a2-f968-574c-8fef-bcc82019d5b2",
"course_number": "0614919",
"course_name": "DRYWALL REPAIR AND REPLACEMENT",
"hours": 1.0,
"completed_date": "2026-09-04",
"delisted_at": null
},
{
"id": "ec464044-c82a-596a-a00e-cbe2fa3f0bc0",
"course_number": "0615028",
"course_name": "OPTION FOR JOINING MATERIALS",
"hours": 1.0,
"completed_date": "2026-09-04",
"delisted_at": null
},
…
]
}
Link summary
GET/licenses/{id}/link-summaryFree · no key
How many other licenses, in how many states, are linked to the same contractor. Counts only: which licenses, and why, are in linked licenses.
| Name | Type | Description |
|---|---|---|
id | path, UUID | The license's id, from a search result. |
Request
curl https://api.licenscheck.com/licenses/3a5cdcae-1af7-5c92-89d2-46fc2e0722af/link-summary
Response
{
"license_id": "3a5cdcae-1af7-5c92-89d2-46fc2e0722af",
"linked_licenses": 1,
"linked_states": 1
}
Verdict
GET/licenses/{id}/verdictAPI key
Verify a license: Clear, Review or Risk found, weighing its own status, expiration and bond, every license linked to the same contractor, and its licensing history.
| Name | Type | Description |
|---|---|---|
id | path, UUID | The license's id, from a search result. |
Request
curl -H "Authorization: Bearer $LICENSCHECK_KEY" \
https://api.licenscheck.com/licenses/3a5cdcae-1af7-5c92-89d2-46fc2e0722af/verdict
Response
{
"license_id": "3a5cdcae-1af7-5c92-89d2-46fc2e0722af",
"level": "risk",
"word": "Risk found",
"summary": "Active in California, but a linked Washington license is suspended.",
"checks": [
{
"label": "Board status",
"outcome": "pass",
"text": "Active as reported by the CA board.",
"segments": [
{ "text": "Active", "strong": true },
{ "text": " as reported by the CA board.", "strong": false }
]
},
{ "label": "Expiration", "outcome": "pass",
"text": "Valid through Jul 31, 2028 (in 1.8 yr).", "segments": […] },
{ "label": "Surety bond", "outcome": "pass",
"text": "$25,000 bond on file (#100504856).", "segments": […] },
{ "label": "Linked licenses", "outcome": "fail",
"text": "Suspended in Washington: SOUTHERN FOLGER CONTRNG INC.
1 linked license in WA.", "segments": […] },
{ "label": "Licensing history", "outcome": "info",
"text": "First issued Jul 13, 2020 (6.2 yr ago).", "segments": […] }
]
}
level is clear, review or risk: any failed check makes it Risk, otherwise any warning makes it Review. Each check's outcome is pass, warn, fail or info. text is plain text; segments is the same text with the words to emphasize marked, for your own UI.
Linked licenses
GET/licenses/{id}/graphAPI key
Every other license linked to the same contractor, with how strong each link is and the evidence behind it.
| Name | Type | Description |
|---|---|---|
id | path, UUID | The license's id, from a search result. |
Request
curl -H "Authorization: Bearer $LICENSCHECK_KEY" \
https://api.licenscheck.com/licenses/3a5cdcae-1af7-5c92-89d2-46fc2e0722af/graph
Response
{
"license_id": "3a5cdcae-1af7-5c92-89d2-46fc2e0722af",
"linked_licenses": [
{
"license": {
"id": "78f68a42-ef6d-52c9-9680-5b024a87e26c",
"contractor_name": "SOUTHERN FOLGER CONTRNG INC",
"license_number": "SOUTHFC804L5",
"state": "WA",
"status": "suspended",
…
},
"confidence": 0.99,
"direct_edge_score": 0.99,
"evidence": [
"same_phone",
"same_name"
]
}
],
"possible_matches": [],
"possible_match_count": 0
}
confidence: the license's strongest link into the group;direct_edge_score: its direct match with the queried license, ornullwhen it's linked only through other licenses.evidence:same_address,same_phone,same_business_id,same_principal,same_name.possible_matches: up to 10 weaker matches that aren't treated as the same contractor, each with ascore,evidence, andworth_review.possible_match_countis how many there are in all.
Stats
GET/statsFree · no key
How many licenses are on file. licenses_is_exact is false when the count is the database's fast estimate.
Request
curl https://api.licenscheck.com/stats
Response
{
"licenses": 541624,
"licenses_is_exact": false
}
About the data
- Straight from the boards, every day. Each record comes from the state board's own published data, refreshed daily (continuing education weekly), and
last_verified_atshows exactly when we last checked it. Status is exactly what the board reports. - Every link shows its evidence. We link a contractor's licenses on shared names, addresses, phones and business ids, and the
evidenceon each link says which, so you can see why. - A license's
iddoesn't change when the board data refreshes, so it's safe to store. - For the businesses you hire or work with. Don't use the API to decide whether a person gets credit, insurance, a job or housing: our results aren't consumer reports (see the Terms and Acceptable use).