HomeClay

Clay enrichment

Verify any contractor’s license, right in Clay

Clay finds the company. We tell you if its license is real and active. Number, trade, status, and expiration, straight from the state board. One enrichment, run per row across 28 states. You only pay for the rows we match.

The licensing layer Clay doesn’t have

Build a contractor list however you already do, whether from Google Maps, Apollo, your CRM, or a partner list. Clay’s sources get you names, phones, and firmographics. None of them answer the one question that qualifies a contractor: is the license real, and is it active right now?

Skip that check and you’re pitching operators who can’t legally take the work, or onboarding one whose license lapsed last quarter. That data lives only at the state licensing boards. This enrichment puts it in your table, so you filter to active licenses before you spend a dollar or take on the risk. It’s built for teams that vet contractors: insurers, lenders, suppliers, and marketplaces.

Every match also returns any contact info on file: phone, email, and address. A verified lead is a usable one.

1. Get an API key

Emailed in under a minute. The same key works on the REST API and the MCP server. No card, no call.

2. Add the enrichment column

In your Clay table, add an HTTP API enrichment (Add column → Enrich → HTTP API). Point it at the verify endpoint and map your columns into the body.

Method & endpoint

POST https://contractorroster.com/api/v1/verify

Headers

X-API-Key:    cr_live_YOUR_KEY
Content-Type: application/json

Body: map your columns

{
  "name":  "{{ company name }}",
  "state": "{{ state }}",
  "city":  "{{ city }}"
}

Pass name for a fuzzy match, or license_no for an exact one. city is optional, and disambiguates businesses that share a name.

Three things that trip people up

  • The header key is literally X-API-Key. Your key goes in the value box, not the name.
  • Keep the " " quotes around each inserted column in the body, or Clay sends invalid JSON.
  • “Try on N rows” only previews. Click Save to actually create the column.

3. What comes back

Each call returns the matched license plus a confidence score. Use the fields you need from the response: record.license_no, record.status, match_confidence, and the rest.

{
  "matched": true,
  "match_confidence": 1,
  "match_method": "exact",
  "record": {
    "license_no":      "1000002",
    "business_name":   "RANDALL MARK DOCKERY",
    "status":          "CLEAR",
    "trade":           "C57",
    "issue_date":      "2015-01-10",
    "expiration_date": "2027-01-31",
    "city":            "LODI",
    "zip":             "95242",
    "phone":           "(925) 383-0487",
    "email":           null,
    "website":         null
  }
}

No confident match returns { "matched": false } with any near candidates, and never charges you. Gate your flow on match_confidence to set your own bar.

Coverage & pricing

10¢ per match, from a prepaid balance. A miss costs nothing, so you only pay for hits. Top up from $50 via Stripe.

Coverage spans 28 stateswith 17 trades, sourced directly from each state’s licensing board. A contractor in a state we don’t cover yet returns matched: false. New states are added regularly.

Prefer to pull whole lists instead of verifying one at a time? The same key works on the MCP server and the HTTP API.