TradeProof API

Verify contractor licenses, monitor subcontractor credentials, and track insurance compliance across all 50 states — checked against government records nightly.

2.5M+ License Records
50 States Covered
Nightly Data Refresh
99.9% Uptime

Getting Started

Start making API calls in under a minute. Sign up, grab your key, and query any contractor license in the country.

1
Create an account

Sign up at tradeproof.net/signup. Free tier includes 25 lookups/month.

2
Get your API key

Go to Settings → API Keys in the app. Your key starts with tp_ and is shown once at creation.

3
Make your first call

Send a GET request with your key in the X-API-Key header.

Quick Start

# Look up a California contractor license
curl -X GET "https://tradeproof.net/v1/licenses/CA/1234567" \
  -H "X-API-Key: tp_your_api_key_here"
import requests

API_KEY = "tp_your_api_key_here"
BASE_URL = "https://tradeproof.net"

response = requests.get(
    f"{BASE_URL}/v1/licenses/CA/1234567",
    headers={"X-API-Key": API_KEY},
)
data = response.json()
print(data["business_name"], data["status"])
const API_KEY = "tp_your_api_key_here";
const BASE_URL = "https://tradeproof.net";

const response = await fetch(
  `${BASE_URL}/v1/licenses/CA/1234567`,
  { headers: { "X-API-Key": API_KEY } }
);
const data = await response.json();
console.log(data.business_name, data.status);
200 Response
{
  "license_number": "1234567",
  "state": "CA",
  "business_name": "Acme Construction Inc.",
  "dba_name": "Acme Builders",
  "status": "CLEAR",
  "license_type": "General Building",
  "classifications": ["B", "C-10"],
  "issue_date": "2018-03-15",
  "expiration_date": "2026-03-15",
  "city": "Los Angeles",
  "state_code": "CA",
  "zip_code": "90001",
  "entity_type": "Corporation",
  "bond_amount": 25000,
  "workers_comp": true,
  "has_disciplinary_action": false,
  "last_updated": "2026-03-10T03:00:00Z"
}

Authentication

All API endpoints require authentication except /health, /v1/stats, and /v1/coverage. TradeProof supports two authentication methods:

MethodHeaderFormatBest For
API Key X-API-Key tp_abc123... Server-to-server integrations, scripts, CI/CD pipelines
JWT Bearer Authorization Bearer eyJ... Browser apps, user sessions (obtained via POST /v1/auth/login)

API Key Scopes

Control what each API key can access with granular scopes. Professional tier and above can assign custom scopes per key.

ScopeGrants Access To
license:readLicense lookups and search (GET /v1/licenses/*)
license:batchBatch verification (POST /v1/verify/batch)
watchlist:readView monitored licenses (GET /v1/watchlist/*)
watchlist:writeAdd/remove monitored licenses (POST/DELETE /v1/watchlist/*)
insurance:readView insurance certificates (GET /v1/insurance/*)
insurance:writeManage insurance records (POST/PUT /v1/insurance/*)
webhook:manageCreate and manage webhooks (/v1/webhooks/*)
report:generateGenerate compliance reports (/v1/reports/*)
*Full access (all scopes). Default for Free and Starter tiers.

IP Allowlisting

Business and Enterprise tiers can restrict API key access to specific IP addresses or CIDR ranges. Configure at the org level (Business: up to 20 IPs) or per-key level (Enterprise: up to 100 IPs).

Core Endpoints

The base URL for all API calls is https://tradeproof.net. All responses are JSON. Timestamps are in UTC (ISO 8601).

License Lookup

GET /v1/licenses/{state}/{license_number}

Look up a specific contractor license by state code and license number.

state required
Two-letter state code (e.g., CA, OH, TX)
license_number required
The license number as issued by the state board

Scope: license:read   Returns: LicenseResponse

GET /v1/licenses

Search licenses with filters. Returns paginated results.

state optional
State code filter (default: CA)
license_number optional
Exact license number
business_name optional
Partial business name match (case-insensitive)
city optional
City name filter
classification optional
License classification code (e.g., B, C-10)
status optional
License status (e.g., CLEAR, Expired)
page / per_page optional
Pagination (default: page 1, 25 per page, max 100)

Scope: license:read

Batch Verification

POST /v1/verify/batch

Verify up to 100 licenses in a single request. Returns pass/fail status for each.

Request Body required
JSON object with a licenses array of {state, license_number} objects (max 100).

Scope: license:batch

curl -X POST "https://tradeproof.net/v1/verify/batch" \
  -H "X-API-Key: tp_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "licenses": [
      {"state": "CA", "license_number": "1234567"},
      {"state": "OH", "license_number": "2023009241"},
      {"state": "TX", "license_number": "9876543"}
    ]
  }'
[
  {
    "license_number": "1234567",
    "state": "CA",
    "valid": true,
    "status": "CLEAR",
    "business_name": "Acme Construction Inc.",
    "expiration_date": "2026-03-15"
  },
  {
    "license_number": "2023009241",
    "state": "OH",
    "valid": true,
    "status": "ACTIVE",
    "business_name": "Buckeye Builders LLC",
    "expiration_date": "2027-01-31"
  },
  {
    "license_number": "9876543",
    "state": "TX",
    "valid": false,
    "status": "NOT_FOUND",
    "business_name": null,
    "expiration_date": null
  }
]

Monitoring (Watchlist)

Add licenses to your watchlist for continuous monitoring. TradeProof checks every monitored license nightly against state records and alerts you when status changes or expirations approach.

POST /v1/watchlist

Add a license to your organization's watchlist.

Scope: watchlist:write   Limit: Based on tier (Free: 5, Starter: 50, Professional: 200, Business: 500)

POST /v1/watchlist/bulk

Add multiple licenses to your watchlist in a single request. Skips duplicates.

Scope: watchlist:write

GET /v1/watchlist

List all monitored licenses, enriched with current license details. Paginated.

Scope: watchlist:read

GET /v1/watchlist/summary

Get a traffic-light summary: counts of green (active), yellow (expiring soon), and red (expired/suspended) licenses.

Scope: watchlist:read

PATCH /v1/watchlist/{item_id}

Update a watchlist item (label, alert preferences).

Scope: watchlist:write

DELETE /v1/watchlist/{item_id}

Remove a license from your watchlist.

Scope: watchlist:write

Alerts

GET /v1/alerts

List recent status changes detected for licenses on your watchlist. Paginated, newest first.

Auth: JWT Bearer   Params: page, per_page (max 100)

Public Endpoints (No Auth Required)

GET /v1/stats

Get database statistics: total records, states covered, last data update timestamp.

GET /v1/coverage

List all supported states with license and workers' comp lookup availability.

GET /health

Liveness check. Returns {"status": "ok"}. Bypasses all middleware.

Webhooks

Subscribe to events and receive HMAC-signed HTTP callbacks when license statuses change, expirations approach, or insurance certificates lapse. Available on Professional tier and above (max 5 webhooks per org).

Events

Webhook Endpoints

POST /v1/webhooks

Register a new webhook URL. You'll receive a signing secret in the response — store it securely.

Scope: webhook:manage   Tier: Professional+

GET /v1/webhooks

List your registered webhooks (secrets are masked).

DELETE /v1/webhooks/{webhook_id}

Delete a webhook.

GET /v1/webhooks/{webhook_id}/deliveries

View delivery history for a webhook (last 100 deliveries with status codes and timestamps).

POST /v1/webhooks/{webhook_id}/test

Send a test ping event to verify your endpoint.

Verifying Signatures

Every webhook delivery includes an HMAC-SHA256 signature in the X-TradeProof-Signature header. Always verify this before processing the payload.

import hmac, hashlib

def verify_webhook(payload_bytes, signature, secret):
    expected = hmac.new(
        secret.encode(), payload_bytes, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
const crypto = require("crypto");

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(signature)
  );
}
Retry policy: Failed deliveries are retried up to 3 times with exponential backoff (5s, 30s, 120s). Your endpoint must return a 2xx status within 10 seconds.

Rate Limits

Rate limits are enforced per API key using a token-bucket algorithm. Check the response headers to monitor your usage.

Response Headers

HeaderDescription
X-RateLimit-LimitYour tier's requests-per-minute limit
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds to wait (only on 429 responses)

Limits by Tier

TierRequests/MinMonthly LookupsMonitored LicensesWebhooks
Free10255
Starter ($149/mo)3025050
Professional ($399/mo)602,5002005
Business ($899/mo)12010,0005005
Developer ($99/mo)601,000
Developer Scale ($349/mo)12010,0005
Enterprise300CustomUnlimitedUnlimited
Exceeding limits: When you hit the rate limit, the API returns 429 Too Many Requests with a JSON error body and Retry-After header. Implement exponential backoff in your client.

Error Handling

TradeProof uses standard HTTP status codes. Errors return a JSON object with a detail field describing the issue.

CodeMeaningExample
200 Success Request completed successfully
201 Created Resource created (watchlist item, webhook, API key)
400 Bad Request {"detail": "Maximum 5 active API keys per organization"}
401 Unauthorized Missing or invalid API key / JWT token
403 Forbidden {"detail": "Your starter plan allows 50 monitored licenses. Upgrade for more."}
404 Not Found {"detail": "License 0000000 not found in CA"}
409 Conflict {"detail": "License already on your watchlist"}
429 Rate Limited {"error": {"code": "rate_limit_exceeded", "retry_after": 7}}
503 Service Unavailable Database temporarily unavailable. Includes Retry-After header.
Data disclaimer: License data is sourced from public state licensing board records and refreshed nightly. This data is provided for informational purposes only and does not constitute legal advice. For critical decisions, confirm directly with the issuing state board.

API Key Management

Manage API keys programmatically. Keys start with tp_ and are shown in full only once at creation — they are stored as irreversible SHA-256 hashes.

POST /v1/account/api-keys

Create a new API key. Returns the full key once. Max 5 active keys per org.

name required
A label for this key (e.g., "Production", "CI/CD")
scopes optional
Array of scopes (default: ["*"]). Professional+ can set custom scopes.

GET /v1/account/api-keys

List all API keys for your organization. Keys are masked (first 8 chars + ****).

PATCH /v1/account/api-keys/{key_id}/scopes

Update scopes on an existing key. Professional tier and above only.

DELETE /v1/account/api-keys/{key_id}

Revoke an API key immediately. This cannot be undone.

Developer Pricing

TradeProof offers dedicated API plans for developers and platforms that want to integrate license verification into their own products.

Free

$0
  • 25 lookups/month
  • 5 monitored licenses
  • 10 requests/min
  • 1 API key
  • All 50 states
Get Started

Developer

$99 /mo
  • 1,000 lookups/month
  • 60 requests/min
  • 5 API keys
  • Batch verification
  • Email support

Enterprise

Custom
  • Unlimited lookups
  • 300 requests/min
  • Custom IP allowlisting
  • SSO (SAML)
  • Dedicated support
  • SLA guarantee

All plans include access to the full 50-state database. Annual billing saves ~15%. Need higher limits? Contact us.

Interactive API Reference

Explore every endpoint, try requests, and see response schemas. Powered by the auto-generated OpenAPI 3.1 specification.

Download OpenAPI Spec Import to Postman