---
title: "Search Permits"
method: GET
path: "/permits/search"
tags: ["Permits", "Permits"]
---

# Search Permits

`GET /permits/search`

Returns a list of matching permits records. Permits should meet ALL of the parameter filters. Multiple parameters are treated as AND queries. Use contractor_classification_derived to filter by contractor's derived classifications (ALL specified values required).

## Query parameters

- `permit_from` string, date, required — Return permits that started on or after the specified date.This includes all permits with the earliest date (file, issue, or start date) that falls on or after this date. Date format: `YYYY-MM-DD`
- `permit_to` string, date, required — Return permits that started on or before the specified date.This includes all permits with the latest date (file, issue, or end date) that falls on or before this date. Date format: `YYYY-MM-DD`
- `permit_tags` string[], nullable — Filter by one or more tags. Use '-' prefix to exclude tags. Example: ?permit_tags=solar&permit_tags=-roofing (has solar, not roofing).
- `geo_id` string, required — Filter results by geographic area. Accepts: - US state code (e.g. `CA`) - ZIP code (e.g. `90210` or `90210-1234`) - Shovels geolocation ID for an address, city, county, or jurisdiction (e.g. `a4xysKbZwqg`) Resolve addresses and places to geolocation IDs via: - [Search Addresses](/api-reference/addresses/search-addresses) - [Search Cities](/api-reference/cities/search-cities) - [Search Counties](/api-reference/counties/search-counties) - [Search Jurisdictions](/api-reference/jurisdictions/search-jurisdictions) Free-form text such as `"123 Main St"` is not accepted.
- `permit_has_contractor` boolean, nullable — Filter by contractor presence: `true` returns only permits with a contractor, `false` only permits without one. Omit to apply no filter.
- `cursor` string, nullable — Cursor for pagination
- `size` integer
- `include_count` boolean — When true and on the first page (no cursor), include total_count in the response. The count is exact up to 10,000; above that, relation is 'gte'.
- `permit_q` string, nullable — Substring to search for in permit description (case-insensitive). Matches anywhere in the text, including partial words.
- `permit_status` string[], nullable — Filter by one or more statuses: final, in_review, inactive, active.
- `permit_min_approval_duration` integer, nullable — Filter by the minimum permit approval duration in days.
- `permit_min_construction_duration` integer, nullable — Filter by the minimum project construction duration in days.
- `permit_min_inspection_pr` integer, nullable — Filter by the minimum inspection pass rate.
- `permit_min_job_value` integer, nullable — Filter by the minimum job value, in cents (e.g. 5000000 = $50,000).
- `permit_min_fees` integer, nullable — Filter by minimum permit fees, in cents (e.g. 5000000 = $50,000).
- `property_type` string[], nullable — Filter by property type: residential, commercial, industrial, agricultural, vacant land, exempt, miscellaneous, office, recreational. Repeat the key to match any of several types (e.g. `?property_type=residential&property_type=commercial`).
- `property_min_market_value` integer, nullable — Minimum assessed market value of the property, in cents (e.g. 5000000 = $50,000).
- `property_min_building_area` integer, nullable — Minimum total building area in sq ft.
- `property_min_lot_size` integer, nullable — Minimum size of the property lot in sq ft.
- `property_min_story_count` integer, nullable — Minimum number of property stories.
- `property_min_unit_count` integer, nullable — Minimum number of property units
- `contractor_classification_derived` string[], nullable — Filter by derived contractor classifications. Use '-' prefix to exclude. Example: ?classification_derived=electrical&classification_derived=-hvac. Returns results containing ALL specified classifications. Possible values: concrete_and_paving, demolition_and_excavation, electrical, fencing_and_glazing, framing_and_carpentry, general_building_contractor, general_engineering_contractor, hvac, landscaping_and_outdoor_work, other, plumbing, roofing, specialty_trades.
- `contractor_name` string, nullable — Filter by contractor's name or business name (partial match supported). Must be at least 3 characters — shorter patterns cannot use the trigram index and would force a sequential scan.
- `contractor_website` string, nullable — Filter by contractor's website. Don't include the http(s):// prefix.
- `contractor_min_total_job_value` integer, nullable — Minimum lifetime job value of the contractor, in cents (e.g. 5000000 = $50,000).
- `contractor_min_total_permits_count` integer, nullable — Minimum lifetime permits count.
- `contractor_min_inspection_pr` integer, nullable — Minimum lifetime inspection pass rate. The value must be an integer between 0 and 100, inclusive.
- `contractor_license` string, nullable — Filter by the contractor's license

## Response `200`

A list of permits.

- PaginatedPermitsResponse — Schema for paginated permits details response.
  - `items` PermitsRead[], required — The list of items returned in the response following given criteria.
    - `property_census_tract` string, nullable, required — The census tract identifier.
    - `property_congressional_district` string, nullable, required — The congressional district identifier.
    - `property_type` string, nullable, required — The type of property.
    - `property_type_detail` string, nullable, required — The detail type of property.
    - `property_legal_owner` string, nullable, required — The legal owner of the property.
    - `property_owner_type` string, nullable, required — The type of property owner.
    - `property_lot_size` integer, nullable, required — The lot size of the property.
    - `property_building_area` integer, nullable, required — The building area of the property.
    - `property_story_count` integer, nullable, required — The number of stories in the property.
    - `property_unit_count` integer, nullable, required — The number of units in the property.
    - `property_year_built` integer, nullable, required — The year the property was built.
    - `property_assess_market_value` integer, nullable, required — The assessed market value of the property in cents (integer value representing dollars × 100).
    - `id` string, required — The permit identifier.
    - `number` string, required — The permit number provided by the jurisdiction.
    - `description` string, nullable — The description on the permit. This is a free-form text field that can contain any information about the permit.
    - `description_derived` string, nullable — A normalized description inferred from the permit's free-form description, giving a consistent summary of the permitted work.
    - `jurisdiction` string, required — The jurisdiction where permit was filled.
    - `job_value` integer, nullable — The reported job value on the permit in cents (integer value representing dollars × 100).
    - `type` string, nullable — The type of permit.
    - `subtype` string, nullable — The subtype of permit.
    - `fees` integer, nullable — The fees charged by the jurisdiction in cents (integer value representing dollars × 100).
    - `status` string, nullable — The status of the permit.
    - `file_date` string, date, nullable — The date the permit was filed.
    - `issue_date` string, date, nullable — The date the permit was issued.
    - `final_date` string, date, nullable — The date the permit was finalized.
    - `start_date` string, date, nullable — The earliest date out of `file_date`, `issue_date` and `final_date` that's found on the permit.
    - `end_date` string, date, nullable — The latest date out of `file_date`, `issue_date` and `final_date` that's found on the permit.
    - `total_duration` integer, nullable — The number of days it took from `start_date` to `end_date`.
    - `construction_duration` integer, nullable — The number of days it took to complete the project.
    - `approval_duration` integer, nullable — The number of days it took to approve the permit.
    - `inspection_pass_rate` integer, nullable — The inspection pass rate as a percentage (0-100)
    - `contractor_id` string, nullable — The contractor identifier.
    - `tags` string[], nullable — The tags associated with the permit.
    - `address` ApiAppModelsPermitsAddressesRead, required — Schema for embedded address object with coordinates.
      - `street_no` string, nullable — The number of the street of the address.
      - `street` string, nullable — The name of the street of the address.
      - `city` string, nullable — The city of the address.
      - `county` string, nullable — The county of the address.
      - `zip_code` string, nullable — The ZIP code of the address.
      - `zip_code_ext` string, nullable — The extension of the ZIP code of the address.
      - `state` string, nullable — The state of the address.
      - `jurisdiction` string, nullable — The jurisdiction the address belongs to.
      - `latlng` number[], nullable — The latitude and longitude of the property.
    - `geo_ids` GeoIdsRead, required — Base64 encoded geographic identifiers embedded in response.
      - `address_id` string, nullable — The address identifier.
      - `city_id` string, nullable — The city ID for the address.
      - `county_id` string, nullable — The county ID for the address.
      - `jurisdiction_id` string, nullable — The jurisdiction ID for the address.
  - `size` integer, required — The number of items returned in the response.
  - `next_cursor` string, nullable, required — The cursor for retrieving the next page of results.
  - `total_count` TotalCount — Capped result count with Elasticsearch-style {value, relation} shape. When the exact count is known and within the cap, relation is "eq" and value is that exact count. When the count exceeds the cap, relation is "gte" and value is the cap the count was probed against, meaning "the actual count is at least value". The cap is COUNT_CAP for every wire-facing endpoint; internal guard paths probe against their own cap, so value carries whatever cap produced it.
    - `value` integer, required — The count value; capped at the probe's cap (10,000 on the wire).
    - `relation` 'eq' | 'gte', required — "eq" means value is the exact count. "gte" means the actual count is at least value (the cap).

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/shovels/apis/the-shovels-api-v2.md) · [All operations](https://skmtc.net/shovels/apis/the-shovels-api-v2/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/shovels/the-shovels-api-v2/versions/d3f0e1f3afa8/schema)
