Contractor License Expiration Monitor & Alerts (Notion) avatar

Contractor License Expiration Monitor & Alerts (Notion)

Pricing

$0.004 / licence checked

Go to Apify Store
Contractor License Expiration Monitor & Alerts (Notion)

Contractor License Expiration Monitor & Alerts (Notion)

Watch a book of contractors across 8 states and get expiry, lapse and revocation alerts written straight into your own Notion - the Actor never sees your Notion token.

Pricing

$0.004 / licence checked

Rating

0.0

(0)

Developer

ScrapeBench

ScrapeBench

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Pain points

  • You find out a subcontractor's license lapsed when a claim is denied or an inspector stops the job - not while there was still time to chase the renewal.
  • Re-checking a book of contractors means one manual lookup per name, per state board, forever.
  • Every state board looks different, so nobody actually re-checks after onboarding day.

What we solve

  • Give it a watchlist once, put it on a schedule, and it re-checks every contractor against the official state board on every run.
  • Flags three things that matter: expiring within your warning window, already expired, and adverse status changes (revoked, suspended, null and void).
  • Writes the alert digest and the full compliance table into your own Notion page - upserted in place, so repeated runs never duplicate rows.

Summary

A scheduled compliance watchdog for a book of contractors. Give it a watchlist of companies and license numbers across California, Connecticut, Florida, New Mexico, Oregon, South Carolina, Texas and Washington, and on every run it re-checks each one against that state's official licensing board, compares the result with what it saw last time, and delivers an alert digest plus a full compliance table into your own Notion workspace over an Apify MCP connector. The Actor authenticates to Apify's proxy with its own run token and never holds your Notion credentials. Built to be trusted rather than merely convenient: a state it does not cover is labelled 'unverifiable - state not covered' and never rendered as unlicensed, a registry miss is reported as 'not found' with an explicit note that this is not evidence the contractor is unlicensed, and any error, timeout or ambiguous name match becomes 'check failed - manual review' rather than a pass. A run with zero alerts still writes a heartbeat, so silence never gets confused with breakage.

Who it's for

  • Insurance agencies and underwriters tracking whether insured contractors stay licensed
  • General contractors managing a list of subcontractors across several states
  • Property managers and facilities teams with an approved-vendor list
  • Compliance and vendor-onboarding teams who need re-verification, not just onboarding checks

How to use

Set the input, run the actor, and collect results from the run's dataset (export to JSON/CSV/Excel, or pull via the Apify API). Example input:

{
"watchlist": [
{
"company": "RANSOME COMPANY",
"state": "CA",
"license_number": "22726"
},
{
"company": "ARETE CONSTRUCTION LLC",
"state": "CT",
"license_number": "631057"
}
],
"warnDays": 30
}

See Inputs below for every available field.

What you get

One row per record:

FieldDescription
requested_companyThe company name you put on the watchlist, echoed back
requested_stateThe state you put on the watchlist
requested_license_numberThe license number you put on the watchlist, echoed back
alertstatus_change
alert_reasonPlain-language reason for the tier, e.g. 'expires in 14 day(s) on 2026-08-20'
license_numberLicense number as published by the state board
business_nameLicensed business name as published by the state board
license_statusRaw status string from the board (e.g. ACTIVE, Null and Void, REVOKED)
license_typeLicense type or classification, where the board publishes it
expiration_dateExpiration date as published by the board
days_to_expiryDays until expiry; negative when already expired
previous_statusThe status recorded by the previous run, when there was one
authorityWhich board answered: CSLB, DBPR, L&I, CCB, TDLR, NM CID, SC LLR or CT DCP
checked_atUTC timestamp of this check
fetch_errorSet only when the check or the delivery failed. Rows with this set are never charged
source_urlWhere the answer came from

Sample:

{
"requested_company": "ARIZA, JOHN MARIO",
"requested_state": "FL",
"requested_license_number": "CGC1514724",
"alert": "status_change",
"alert_reason": "license status is 'Null and Void'",
"license_number": "CGC1514724",
"business_name": "ARIZA, JOHN MARIO",
"license_status": "Null and Void",
"license_type": "Certified General Contractor",
"expiration_date": "08/31/2020",
"days_to_expiry": -2166,
"previous_status": null,
"authority": "DBPR",
"checked_at": "2026-08-06T17:11:02+00:00",
"fetch_error": null,
"source_url": "https://www.myfloridalicense.com/wl11.asp"
}

Inputs

FieldRequiredTypeDefaultDescription
watchlistnoarray[{"company": "ABC Roofing", "state": "CA", "license_number": "1076169"}, {"company": "Example Builders", "state": "WA", "license_number": ""}]The contractors to watch. One object per contractor: {"company": "ABC Roofing LLC", "state": "CA", "license_number": "123456"}. Include the license number whenever you have it — it is the exact search axis, so a licence found by number is never a near-miss. A name-only row is matched on the full normalized business name (case, punctuation and LLC/Inc suffixes are ignored); if the name resolves to more than one licence the row comes back as 'check failed — manual review' rather than guessing. Covered states: CA, CT, FL, NM, OR, SC, TX, WA. Any other state is returned as 'unverifiable — state not covered', never as unlicensed.
connectornostringWhere to write the compliance table and the alert digest. This Actor never sees your Notion or Slack token — Apify injects your credentials server-side and only lets this Actor call the page search/create/update tools declared in its schema. Notion is the recommended target: Apify manages the OAuth, so authorizing it is a single click from this form. Slack works too, but Slack requires YOU to register your own Slack OAuth app first — that is Slack's requirement, not ours, and it takes about ten minutes. Leave this empty to run dataset-only with no delivery.
pageTitlenostring"Contractor License Compliance Monitor"The Actor upserts ONE page with this title: it searches for the page, updates it in place when it exists, and creates it otherwise — so repeated runs never duplicate rows. Change this if you monitor more than one book of contractors and want each in its own page.
warnDaysnointeger30A licence expiring within this many days is reported as EXPIRING. Renewal windows are typically 30-60 days, so 30 gives you time to chase a renewal before the licence actually lapses.
alertOnnoarray["expiring", "expired", "status_change"]Which tiers go in the alert digest. Valid values: 'expiring', 'expired', 'status_change'. Leave empty for all three. Note that 'check_failed' and 'unverifiable_state_not_covered' are ALWAYS reported no matter what you set here — they describe the check rather than the contractor, and hiding them would turn a broken check into a false all-clear.

Pricing (Pay Per Event)

You pay per result (license-checked) — no charge for empty runs. Example: 100 licences checked against a state board at $0.004/result$0.40.

Charged only for a licence this monitor actually resolved on a state board. Rows that come back not-found, uncovered-state or check-failed are free.

One more line on your bill. This monitor runs the per-state lookup Actors on your behalf, and those charge their own per-match fees to your account. The numbers below are from a real run, not an estimate.

Measured: a 93-contractor book, one run, 2026-08-06

LineDetailCost
Open-data boards (CA, CT, FL, OR, TX, WA)69 matches x $0.004$0.276
CAPTCHA boards (NM, SC)25 searches x $0.02 + 25 matches x $0.01$0.750
This monitor93 licences checked x $0.004$0.372
Total93 contractors, one run$1.398

That is $0.015 per contractor per check at this state mix. Note how lopsided it is: the 25 New Mexico and South Carolina contractors were 27% of the book but 73% of the lookup cost, because both boards CAPTCHA the search itself.

A 100-contractor book, checked weekly

Weekly is 4.33 runs a month, so 433 checks:

  • If your book avoids NM and SC: $0.004 lookup + $0.004 monitor = $0.008 per check, so about $3.46/month.
  • At the measured 27% NM/SC mix: $0.015 per check, so about $6.51/month.

Apify platform compute is not billed to you on a pay-per-event Actor - it comes out of our side. The whole run above cost us $0.025 of compute.

Use cases

  • Renewal chasing - catch a licence expiring inside your warning window while there is still time to act.
  • Lapse detection - find out that a licence expired without waiting for a claim or an inspection to reveal it.
  • Adverse-action monitoring - get alerted when a board marks a licence revoked, suspended or null and void.
  • Standing compliance record - keep a living Notion page showing every contractor's current status, refreshed on a schedule.

Why this actor

  • The Actor never holds your Notion token - Apify's MCP proxy injects your credentials server-side and only permits the page search, create and update tools this Actor declares.
  • Fails closed on purpose: an uncovered state, a registry miss and an ambiguous name match are three different, clearly-labelled outcomes, and none of them reads as 'unlicensed' or as a pass.
  • A run with zero alerts still writes a heartbeat, so a monitor that has broken never looks the same as a quiet week.
  • Upserts one page in place rather than appending, so a weekly schedule does not leave you with 52 copies of the table.

Limitations & updates

Covers eight states: CA, CT, FL, NM, OR, SC, TX, WA. Anything else is returned as 'unverifiable - state not covered'. Two states are partial by source: Texas publishes no status field (expiry monitoring only, so a revocation is not detected) and South Carolina publishes no expiration date (status monitoring only). Name-only matching is deliberately strict - an exact normalized business-name match or nothing - so a watchlist is far more reliable with license numbers in it. Status-change detection compares against the previous run, so the first run for a contractor has no baseline to diff against; adverse statuses such as revoked, suspended and null-and-void are still flagged on that first run. New Mexico and South Carolina are CAPTCHA-gated at the source, which makes them materially slower and more expensive per licence. Delivery writes one page per run, upserted by title; it is not a per-row Notion database sync.

FAQ

Which states does it cover?

Eight: California (CSLB), Connecticut (DCP), Florida (DBPR), New Mexico (CID), Oregon (CCB), South Carolina (LLR), Texas (TDLR) and Washington (L&I). Any other state comes back as 'unverifiable - state not covered'. That row is never dropped and never reported as unlicensed - it means we did not check, not that the contractor has no licence.

Does 'not found' mean the contractor is unlicensed?

No, and this is the most important line here. It means the state registry returned no match for what you searched. A typo, a DBA that differs from the licensed entity name, or a licence held under a parent company will all produce 'not found'. Treat it as 'go and look', never as evidence that somebody is operating unlicensed.

Can it detect revocations in every covered state?

In six of the eight. Texas (TDLR) publishes an expiration date but no status field, so expiry monitoring works there and a revocation would not be seen. South Carolina (LLR) is the mirror image: it publishes a status but never an expiration date, so status monitoring works there and expiry does not. The other six support both.

Do I need my own Notion or Slack app?

Notion, no - Apify manages that OAuth, so you authorize it in one click from the input form. Slack, yes - Slack requires you to register your own Slack OAuth app first. That is Slack's requirement rather than ours. You can also leave the connector empty and just use the dataset.

How am I charged?

Per licence this monitor actually resolves on a state board. Rows that come back not-found, uncovered-state or check-failed are free. Separately, the per-state lookup Actors this monitor calls on your behalf charge their own per-match fees - the README has a measured worked example with both lines.

Why are New Mexico and South Carolina slower and more expensive?

Both boards put a CAPTCHA on the search itself, so each licence costs a solve. In a measured run on 2026-08-06, 12 South Carolina licences took 244 seconds against 10 seconds for 13 Washington licences, and the two CAPTCHA states accounted for 73% of the underlying lookup cost of a 93-contractor book. Keep that in mind when sizing a watchlist.

How does it avoid matching the wrong contractor?

A watchlist row with a license number is matched on that number exactly. A name-only row is matched on the full normalized business name (case, punctuation and LLC/Inc suffixes ignored) - a partial or near match is not accepted. If a name resolves to more than one licence the row is returned as 'check failed - manual review' rather than the Actor guessing, because billing you for a verdict about the wrong company is worse than returning nothing.

Is this personal data?

It is public professional-licence data as the state boards publish it. Some boards licence individuals rather than companies, so a licensed person's name can appear where the board publishes it that way. No personal or PII enrichment is added.

Which actor to choose

Built on the per-state license lookups - use one directly if you need a one-off check rather than ongoing monitoring:

  • California Contractor License Lookup & Verify (CSLB) — You need a one-off California check by license number, business, or owner/personnel name (CSLB).
  • Florida Contractor License Lookup & Verification (DBPR) — You're verifying a single Florida contractor - type, status, expiration, county (DBPR).
  • Washington Contractor License Lookup & Verify (L&I) — You need a one-off Washington check - type, status, expiration, principal (L&I).
  • Oregon Contractor License Lookup & Verify (CCB) — You're verifying an Oregon contractor - status, bond, insurance & RMI (CCB).
  • Texas Contractor & Trade License Lookup (TDLR) — You're verifying a Texas electrician, HVAC or trade license - type, expiration, county (TDLR).
  • New Mexico Contractor License Lookup & Verify (NM CID) — You're verifying a single New Mexico contractor - license #, status, city/ZIP, expiry (NM CID).
  • South Carolina Contractor License Lookup & Verify (SC LLR) — You're searching or verifying South Carolina contractors by name, license, city or classification (SC LLR).
  • Multi-State Contractor & Trade License Lookup — You don't know the state, or want one contractor checked across WA, OR, TX & CT in one run.

Guides & use cases

Written up on scrapebench.dev — the bench that runs and verifies this actor against the live source every night:

More actors, coverage and nightly verification results: scrapebench.dev