tradesapi
Start free

Home › Guides › Response fields

Contractor license verification · API reference

What a contractor license verification API returns

Every verification comes back in one shape, whichever of the 51 state jurisdictions or 16 city boards you ask about. Here is each field, what it means, and which ones to rely on when a decision depends on the answer.

The fields

FieldTypeWhat it means
validbooleanTrue when the board shows a current, valid license for this number and trade.
namestring or nullThe licensee name exactly as the board records it.
license_numberstringThe license number that was checked.
tradestringThe trade you asked about, such as general, electrical, plumbing, or hvac.
statusstring or nullThe board's own status wording, kept word for word (for example Active, Expired, or Suspended).
status_normalizedstring or nullThe same status mapped to one shared set: active, expired, suspended, revoked, probation, inactive, or unknown. Null when a state's wording isn't mapped yet; status still has the raw value.
expirationstring or nullExpiration date as the board publishes it.
statestringTwo-letter state code of the jurisdiction that was checked.
disciplinary_actionslistBoard enforcement actions on record, where the board publishes them.
disciplinary_data_availablebooleanTells you whether an empty disciplinary_actions list means a clean record. When false, the board's disciplinary data isn't collected for that jurisdiction, so an empty list means no data, not no discipline.
has_disciplinary_actionbooleanShortcut that is true when disciplinary_actions is not empty.
classificationslist or nullLicense classes or endorsements the board lists, when it lists them.
bond_info / insurance_infoobject or nullBond and insurance details for boards that publish them. Null elsewhere.
verification_typestring or nulllicense for a competency license, registration for a paperwork-only registration that does not certify trade skill. Null means license.
source_urlstring or nullThe official board portal the answer came from, for your audit trail.
sourcestring or nullWhich layer answered: scrape (live board portal), cache, or db (bulk board data).
checked_attimestampWhen this response was produced.
last_verified_at / staleness_secondstimestamp / integerWhen the underlying record was last observed, and how old it is. Zero staleness means a live check.
cachedbooleanTrue when the answer came from the 24 hour cache of active licenses.

Three fields people get wrong

An empty disciplinary list is not always a clean record. Some boards publish enforcement actions and some don't. Read disciplinary_data_available before treating an empty disciplinary_actions list as good news.

A valid registration is not a competency license. In some states a contractor only registers with the state, and nobody tests their trade skills. verification_type tells you which kind of credential you are looking at.

Use status_normalized for rules, status for display. Boards use dozens of status phrases. Write your logic against the normalized value and show the raw one to people.

Where the answer came from

Every result carries source_url (the official board portal), source (live portal, cache, or bulk board data), and checked_at. Keep them with the result and you can show an auditor exactly where an answer came from and when.

See a full example request and response in how to verify a contractor license via API, or the whole contract in the API docs. Machine-readable facts: /facts.json.

Try it on your own licenses

Every new API key includes 50 free verifications across all 50 states plus DC, with hosted MCP access for AI agents. No credit card to start.

Frequently asked questions

What does a contractor license verification API return?
At minimum: whether the license is valid, the licensee name, the license number, its status, and its expiration date. A good one also returns disciplinary actions, the official source URL, and when the record was checked, so you can show where an answer came from.
Does an empty disciplinary list mean the contractor has a clean record?
Only if the API tells you the board's disciplinary data was collected. TradesAPI returns disciplinary_data_available alongside the list. When it is false, an empty list means the data isn't collected for that jurisdiction, not that the contractor has no discipline.
Why are there two status fields?
Every board words status differently. status keeps the board's exact wording, and status_normalized maps it to one shared set (active, expired, suspended, revoked, probation, inactive, unknown) so you can write one rule for every state.
How do I know whether a result is live or cached?
Check source and staleness_seconds. source is scrape for a live board check, cache for the 24 hour cache, or db for bulk board data. Only active licenses are cached; expired and not-found results are always checked again.
Is the response shape the same for every state?
Yes. The same fields come back for all 51 state jurisdictions and 16 city boards. Fields a board doesn't publish come back null.