---
title: "Search contractors by permit activity"
method: GET
path: "/api/v1/deals/contractors"
tags: ["Deals"]
---

# Search contractors by permit activity

`GET /api/v1/deals/contractors`

## Request

- Base URL: `https://propraven.com`
- URL: `https://propraven.com/api/v1/deals/contractors`
- Auth: HTTP bearer

Returns contractor profiles aggregated from 45M+ building permits. Each profile includes permit count, jurisdictions worked, total declared permit value, and activity dates. Use to identify active contractors in a market or find a specific contractor by name.

## Query parameters

- `search` string
- `min_permits` integer
- `state` string
- `min_value` integer
- `limit` integer
- `offset` integer

## Response `200`

Contractor profiles returned.

- object
  - `data` Contractor[], required
    - `contractor_name_normalized` string, nullable, required
    - `contractor_license` string, nullable, required
    - `permit_count` integer, nullable, required
    - `jurisdiction_count` integer, nullable, required
    - `state_count` integer, nullable, required
    - `county_count` integer, nullable, required
    - `total_permit_value` integer, nullable, required
    - `avg_permit_value` number, nullable, required: total_permit_value / permit_count (#558); see avg_valued_permit_value for the mean over permits with a recorded cost.
    - `first_permit_date` string, date, nullable, required
    - `last_permit_date` string, date, nullable, required
    - `active_years` integer, nullable, required
    - `top_permit_types` string, nullable, required
    - `states_list` string, nullable, required: Comma-delimited 2-letter state codes.
    - `contractor_rank` integer, nullable, required: Contiguous position in this filtered, rank-ordered list (offset + position); contractor_rank_stored is the producer's national rank.
    - `contractor_name_raw` string: The stored name when stray leading/trailing punctuation was trimmed.
    - `contractor_rank_stored` integer, nullable: The producer's rank over its own universe (includes names this list filters out).
    - `avg_valued_permit_value` number, nullable: The producer's mean over permits with a recorded positive cost.
    - `valued_permit_count_implied` integer, nullable: total_permit_value / avg_valued_permit_value.
    - `avg_permit_value_basis` 'total_over_permit_count' | 'no_recorded_cost' | 'no_permit_count'
    - `county_count_raw` integer, nullable: The stored 0 when county_count is served null (no source permit carried a county).
    - `county_count_basis` 'stored' | 'county_fips_missing_on_permits' | 'unavailable'
    - `state_count_basis` 'geography_unavailable'
  - `total` integer, required
  - `limit` integer, required
  - `offset` integer, required
  - `source_quality` object, required
    - `geography_status` string, required
    - `profile_refresh_observed_at` string, required
    - `quality_checked_at` string, required
    - `scope` string, required
    - `reason` string, required
  - `field_notes` object: What each re-derived contractor field means (#558).

## Other responses

- `400`: A query or body parameter is invalid. Nothing was read or charged.
- `401`: Missing, malformed or invalid credential.
- `402`: Monthly call cap reached (free tier, or a paid tier with the hard cap enabled).
- `405`: The endpoint exists but does not support this method. `Allow` lists the methods it does.
- `429`: Rate limit exceeded.
- `500`: Unexpected server error. The body never carries database or driver text.
- `503`: The data behind this endpoint is temporarily unavailable. Honour `Retry-After` when present.

---

[API](https://skmtc.dev/propraven/apis/propraven-api.md) · [All operations](https://skmtc.dev/propraven/apis/propraven-api/llms.txt) · [OpenAPI document](https://skmtc.dev/propraven/apis/propraven-api/revisions/37f8158c4eda?raw)
