ContractorRoster API

REST API v1

Authenticated lookup of licensed contractors across 28 states and 17 trades. Prepaid balance, $0.10/record default ($0.07 for CRM partners), $50 minimum top-up. Email [email protected] to request an API key.

Raw OpenAPI 3.1: /api/v1/openapi.yaml

Public endpoints

No authentication. Rate-limited per IP. Use for partner prospecting, AI-agent discovery, and to qualify queries before committing balance.

GET /api/v1/coverage

Total contractor count + redacted sample for a state × trade. Free preflight before a paid call. Rate-limited per IP.

/api/v1/coverage?state=CA&trade=GC

Try it →

GET /api/v1/states

Catalog of supported states with their geo types and per-trade availability. Use this to build dropdowns / validate inputs.

/api/v1/states

Try it →

GET /api/v1/trades

Catalog of trade codes with display names and URL slugs.

/api/v1/trades

Try it →

Authenticated endpoints

Require an API key issued by ContractorRoster. Authorization: Bearer cr_live_... or X-API-Key: cr_live_....

POST /api/v1/contractorsAPI key

Search + deliver enriched contractor records. Debits balance at price_per_record_cents × records_delivered. Send dry_run: true to preview cost without debit. Returns 402 with shortfall on insufficient balance.

curl -X POST -H "Authorization: Bearer cr_live_..." -H "Content-Type: application/json" \ -d '{"state":"CA","trade":"HVAC","geo_type":"zip","geo_value":"90210","dry_run":true}' \ https://contractorroster.com/api/v1/contractors
POST /api/v1/topupAPI key

Create a Stripe Checkout Session to credit the partner balance. $50 min, $10k max per session. Returns checkout_url.

curl -X POST -H "Authorization: Bearer cr_live_..." -H "Content-Type: application/json" \ -d '{"amount_cents":5000}' \ https://contractorroster.com/api/v1/topup
GET /api/v1/usageAPI key

Current balance, pricing, and the 20 most recent transactions (top-ups + API calls).

curl -H "Authorization: Bearer cr_live_..." https://contractorroster.com/api/v1/usage

MCP server

Model Context Protocol server for AI agents. Same data, same balance, tool-call interface. Live at /api/mcp. Tools: list_states, list_trades, count_contractors, search_contractors, get_usage. Auth is the same Authorization: Bearer cr_live_… header.

Minimal client setup (TypeScript):

import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; const transport = new StreamableHTTPClientTransport( new URL("https://contractorroster.com/api/mcp"), { requestInit: { headers: { Authorization: "Bearer cr_live_..." } } } ); const client = new Client({ name: "my-agent", version: "1.0.0" }); await client.connect(transport); const result = await client.callTool({ name: "search_contractors", arguments: { state: "CA", trade: "HVAC", geo_type: "city", geo_value: "Los Angeles", dry_run: true, }, });

Spec + status: docs/MCP_SPEC.md →

Ready to integrate? Tell us about your use case.

[email protected]