# Bend & Deschutes County Building Permits API – Contractor Leads (`implementable_antler/deschutes-permits`) Actor

Bend, Redmond, Sisters, La Pine & Deschutes County building permits API: new construction leads with contractor names, valuation, trade tags (roofing, solar, HVAC). Export permit data CSV/JSON.

- **URL**: https://apify.com/implementable_antler/deschutes-permits.md
- **Developed by:** [Blake Runckel](https://apify.com/implementable_antler) (community)
- **Categories:** Lead generation, Real estate, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bend & Deschutes County Building Permits API – Contractor Leads

Issued building permits for **Central Oregon**: unincorporated Deschutes County, Redmond, Sisters and La Pine from the Deschutes County Community Development (CDD) public permit export, plus the **City of Bend** from the City's own open data (a separate source; Bend is not in the CDD export). Every permit gets sub-trade tags with provenance (roofing, electrical, plumbing, HVAC, solar/PV, concrete, framing and more) and contractor names. No owner names. As far as we know, this is the only Deschutes/Bend permit Actor on the Store.

**Use it for:** contractor leads and construction leads (new jobs by trade), a building permits API for your CRM, or a permit data CSV/Excel export for market research. Runs on a schedule; export CSV, Excel, JSON or call the API.

### Sample rows (table)

| issueDate | address | workType | contractorName | valuation | trades |
|---|---|---|---|---|---|
| 2026-10-05 | 2793 NW GREENWOOD AVE REDMOND, OR 97756 | Alteration - Single Family Dwelling | SUMMIT CONTRACTORS GROUP LLC | $106,000 | roofing, general contracting |
| 2026-09-25 | 252 SW 33RD DR REDMOND, OR 97756 | Alteration - Single Family Dwelling | COMPLETE SOLAR INC | $12,690 | roofing, electrical, solar/PV, general c |
| 2026-09-23 | 832 SW 23RD CT REDMOND, OR 97756 | Alteration - Single Family Dwelling | NATIONAL SOLAR INC | $25,400 | roofing, solar/PV, general contracting |
| 2026-09-21 | 3664 SW 35TH PL REDMOND, OR 97756 | Alteration - Single Family Dwelling | SUNLIGHT SOLAR ENERGY INC | $3,000 | solar/PV, general contracting |
| 2026-10-08 | 62507 NW WOODSMAN LOOP, BEND, OR 97703 | Electrical | SUNLIGHT SOLAR ENERGY INC |  | electrical, solar/PV |

### Quick start

Example input (also prefilled in the input form):

```json
{
  "days": 30,
  "jurisdictions": [
    "Bend",
    "Redmond"
  ],
  "trades": [
    "roofing",
    "solar/PV"
  ],
  "maxItems": 100,
  "explicitTradesOnly": true
}
```

### Input

| Field | Description |
|---|---|
| `days` | How many days back from today to include, by permit issue date (1-366). |
| `trades` | Only return permits tagged with at least one of these trades. Leave empty for all trades. |
| `explicitTradesOnly` | When filtering by trade, match only trades stated by the permit type, a listed contractor role or the description, and ignore 'implied' tags (e.g. roofing implied by a new house). On by default for lead generation; turn off to include implied new-build trades. |
| `jurisdictions` | Limit to these jurisdictions. Bend comes from City of Bend open data; the others from the Deschutes County CDD export. Empty = all. |
| `dateFrom` | Earliest issue date, YYYY-MM-DD. When set, overrides 'Days back'. |
| `dateTo` | Latest issue date, YYYY-MM-DD. Defaults to today. |
| `minValuation` | Only permits with a declared valuation at or above this amount. Rows with no or zero valuation are dropped when this is set. |
| `excludeNonBuilding` | Skip administrative and non-building records: right-of-way, special event, transportation-facilities memo, infrastructure, street-use, plus administrative/expired records. |
| `maxItems` | Maximum number of records to return (1-50,000). |

### Fields

Every Ledger permit Actor (Deschutes/Bend, Chicago, NYC) outputs the same fields:

| Field | Meaning |
|---|---|
| `recordId` | Unique row key. One job can produce several rows (NYC: one per work type; Bend: one per sub-permit such as building, electrical, plumbing, mechanical). Dedupe on `permitID` if you want one row per permit. Deschutes CDD rows are already one per `permitID`. |
| `permitID` | The agency's permit/application number. |
| `jurisdiction` | City or county that issued the permit. |
| `address` | Site address as published. |
| `parcel` | Tax lot / PIN / BBL (see completeness). |
| `latitude`, `longitude` | WGS84 coordinates where the source publishes them (Chicago, NYC); null for Deschutes/Bend. |
| `workType` | The agency's work/permit-type label (e.g. Plumbing, Electrical, New - Single Family Dwelling). |
| `permitType`, `permitSubtype` | The agency's broader permit category and subtype (see "Source mapping"). |
| `filingReason`, `isRenewal` | Filing reason where the source publishes one (Chicago, NYC; always null for Deschutes/Bend); `isRenewal` is `true` for renewals/reinstatements (always `false` for Deschutes/Bend). |
| `description` | Free-text scope of work. |
| `status` | Permit status as published. A value ending in "(inferred: …)" means the source left it blank and we derived it. |
| `contractorName` | The agency's main contractor field (general contractor where known). Never a record the agency labels as owner. |
| `contractors` | All contractor roles listed on the permit, `[{role, name}]`. |
| `contractorLicense` | `{type, number}` where published (NYC only; always null for Deschutes/Bend). |
| `valuation` | Declared job value in USD (null if not published). |
| `squareFeet` | Square footage where published. |
| `applicationDate`, `approvedDate`, `issueDate`, `expirationDate`, `finalDate` | ISO dates (YYYY-MM-DD); null when the source doesn't publish that date. |
| `trades` | All sub-trades the job likely needs, including implied ones. |
| `explicitTrades` | Only trades stated by the permit type, a listed contractor role, or the description. |
| `tradeDetails` | `[{trade, source, confidence}]`: source `permitType`/`contractorRole` (high), `keyword` (medium), `implied` (low, e.g. a new house implies roofing). |
| `sourceUrl` | Bend: the row in the City's ArcGIS layer. Deschutes CDD: not a record link; it re-downloads the official export for the run's date window, which contains the permit. |
| `source` | Publisher and dataset name. |

### Source mapping

| Source | Coverage | Mapping notes |
|---|---|---|
| Deschutes County CDD export (webapps.deschutes.org/CDDPermits) | County, Redmond, Sisters, La Pine | `workType` = workClass; `permitType` = buildingClass (Residential/Commercial); `permitSubtype` = buildingType. No public per-permit page, so `sourceUrl` re-downloads the official export for that date window. |
| City of Bend open data, "Permits and Contractors Table" (data.bendoregon.gov, ArcGIS) | Bend | `workType` = permit type (Building, Electrical, Plumbing, Mechanical…); `permitType` = application type; each sub-permit is its own row (`recordId` = application-PID). Right-of-way, special-event, transportation-memo and infrastructure records are excluded by default (`excludeNonBuilding`). `sourceUrl` opens the row in the ArcGIS viewer. The City updates the layer regularly; check the layer's edit date for the current refresh. |

### Completeness

Measured on all records issued 2026-09-20 to 2026-10-16 (default filters):

| Source | Records | Contractor name | Valuation > 0 | Parcel | Lat/lon |
|---|---|---|---|---|---|
| Deschutes CDD (County, Redmond, Sisters, La Pine) | 113 | 53% | 96% | 100% | 0% |
| City of Bend | 321 (309 permits) | 83% | 38% | 100% | 0% |

### Sample output

(Generated 2026-10-19 by the current version.)

```json
{
  "recordId": "247-26-002452-STR",
  "permitID": "247-26-002452-STR",
  "jurisdiction": "Deschutes County",
  "address": "16091 OLD JUNIPER RD SISTERS, OR 97759",
  "latitude": null,
  "longitude": null,
  "workType": "Addition - Single Family Dwelling",
  "permitType": "Residential",
  "isRenewal": false,
  "description": "ADDITION- 750 Sq/Ft off the north side of the house. Including a primary suite, laundry, bath and entry.",
  "status": "Permit Issued",
  "contractorName": null,
  "contractors": [],
  "valuation": 153050.4,
  "issueDate": "2026-10-06",
  "trades": [
    "plumbing",
    "framing"
  ],
  "explicitTrades": [
    "plumbing"
  ],
  "tradeDetails": [
    {
      "trade": "plumbing",
      "source": "keyword",
      "confidence": "medium"
    },
    {
      "trade": "framing",
      "source": "implied",
      "confidence": "low"
    }
  ],
  "sourceUrl": "https://webapps.deschutes.org/CDDPermits/Building/Export?startDate=10%2F6%2F2026&endDate=10%2F19%2F2026&fieldDelim=%2C&textDelim=%22&fileExt=csv"
}
```

```json
{
  "recordId": "PRNC202508465-192061",
  "permitID": "PRNC202508465",
  "jurisdiction": "Bend",
  "address": "1113 NE 5TH ST, BEND, OR 97701",
  "latitude": null,
  "longitude": null,
  "workType": "Building Permit",
  "permitType": "New Construction/Installation",
  "isRenewal": false,
  "description": "Townhome (Attached Single Family Dwelling) Two sets of duplexes/townhomes will be built on this lot and later divided into four separate lots/townhomes. **Middle Housing Land Division (PLLD20250332). Other duplex permit PRNC202506726 ***PRNC202506727 - ***Plans reviewed under this permit*** PRNC202508465 (clone) ***COB Water (meter added)*** SN ***Demo Permit Condition*** SN ***No Active SIMPs*** SN ***Needs Addressing*** SN",
  "status": "Permit(s) Issued",
  "contractorName": "Spring River Builders, LLC",
  "contractors": [
    {
      "role": "general",
      "name": "Spring River Builders, LLC"
    },
    {
      "role": "electrical",
      "name": "CRAWFORD ELECTRIC"
    },
    {
      "role": "mechanical",
      "name": "High Desert Heating & Cooling, LLC"
    },
    {
      "role": "plumbing",
      "name": "Durham Plumbing llc"
    }
  ],
  "valuation": 360363.68,
  "issueDate": "2026-10-12",
  "trades": [
    "electrical",
    "HVAC",
    "plumbing",
    "demolition",
    "general contracting",
    "concrete",
    "framing",
    "roofing"
  ],
  "explicitTrades": [
    "electrical",
    "HVAC",
    "plumbing",
    "demolition",
    "general contracting"
  ],
  "tradeDetails": [
    {
      "trade": "electrical",
      "source": "contractorRole",
      "confidence": "high"
    },
    {
      "trade": "HVAC",
      "source": "contractorRole",
      "confidence": "high"
    },
    {
      "trade": "plumbing",
      "source": "contractorRole",
      "confidence": "high"
    },
    {
      "trade": "demolition",
      "source": "keyword",
      "confidence": "medium"
    },
    {
      "trade": "general contracting",
      "source": "keyword",
      "confidence": "medium"
    },
    {
      "trade": "concrete",
      "source": "implied",
      "confidence": "low"
    },
    {
      "trade": "framing",
      "source": "implied",
      "confidence": "low"
    },
    {
      "trade": "roofing",
      "source": "implied",
      "confidence": "low"
    }
  ],
  "sourceUrl": "https://services5.arcgis.com/JisFYcK2mIVg9ueP/arcgis/rest/services/Permits_and_Contractors_Table/FeatureServer/0/query?where=OBJECTID%3D69363&outFields=*&f=html"
}
```

### Pricing

**Free: there is no Actor fee and no per-result charge.** Runs use your own Apify platform usage (compute) under your Apify plan, the same as any free Actor; a typical run fits in the default 512 MB and takes well under a minute. If this ever changes, it will be announced on this page before it takes effect.

### Privacy

Owner and homeowner records are not included: no field or contact role that the agency labels as owner is exported. Personal phone numbers and emails are not exported either. **Contractor names are the agency's contractor field as published. Most are businesses, but some are sole proprietors or individual licensees (on Redmond/County residential permits these can be owner-builders).** Treat contractor contact as B2B. Follow the TCPA, CAN-SPAM, do-not-call rules and the source's terms; contact at a permit address should be by mail only unless you have consent.

### Reliability

Each run reads the official feed live. Requests retry up to 3 times with backoff (2 s, 4 s, 8 s) on rate limits, server errors and timeouts. If a run finds 0 matching records it pushes nothing and sets a status message saying so. A change in the source's columns stops the run with a clear error.

### Limitations

- Trade tags are rules applied to permit types, contractor roles and descriptions, so they are not guaranteed. With a trade filter set, only explicit (stated) trades match by default; set `explicitTradesOnly` to false to include implied new-build trades.
- Not affiliated with or endorsed by the data publisher.

### Attribution and terms

Source attribution: Deschutes County Community Development; City of Bend. Both publish the data with warranty disclaimers only (no explicit reuse licence). Data is provided as-is.

# Actor input Schema

## `days` (type: `integer`):

How many days back from today to include, by permit issue date (1-366).

## `trades` (type: `array`):

Only return permits tagged with at least one of these trades. Leave empty for all trades.

## `explicitTradesOnly` (type: `boolean`):

When filtering by trade, match only trades stated by the permit type, a listed contractor role or the description, and ignore 'implied' tags (e.g. roofing implied by a new house). On by default for lead generation; turn off to include implied new-build trades.

## `jurisdictions` (type: `array`):

Limit to these jurisdictions. Bend comes from City of Bend open data; the others from the Deschutes County CDD export. Empty = all.

## `dateFrom` (type: `string`):

Earliest issue date, YYYY-MM-DD. When set, overrides 'Days back'.

## `dateTo` (type: `string`):

Latest issue date, YYYY-MM-DD. Defaults to today.

## `minValuation` (type: `integer`):

Only permits with a declared valuation at or above this amount. Rows with no or zero valuation are dropped when this is set.

## `excludeNonBuilding` (type: `boolean`):

Skip administrative and non-building records: right-of-way, special event, transportation-facilities memo, infrastructure, street-use, plus administrative/expired records.

## `maxItems` (type: `integer`):

Maximum number of records to return (1-50,000).

## Actor input object example

```json
{
  "days": 30,
  "trades": [
    "roofing",
    "solar/PV"
  ],
  "explicitTradesOnly": true,
  "jurisdictions": [
    "Bend",
    "Redmond"
  ],
  "excludeNonBuilding": true,
  "maxItems": 100
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "days": 30,
    "trades": [
        "roofing",
        "solar/PV"
    ],
    "explicitTradesOnly": true,
    "jurisdictions": [
        "Bend",
        "Redmond"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("implementable_antler/deschutes-permits").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "days": 30,
    "trades": [
        "roofing",
        "solar/PV",
    ],
    "explicitTradesOnly": True,
    "jurisdictions": [
        "Bend",
        "Redmond",
    ],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("implementable_antler/deschutes-permits").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "days": 30,
  "trades": [
    "roofing",
    "solar/PV"
  ],
  "explicitTradesOnly": true,
  "jurisdictions": [
    "Bend",
    "Redmond"
  ],
  "maxItems": 100
}' |
apify call implementable_antler/deschutes-permits --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,implementable_antler/deschutes-permits"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/WAYdNAndu5qu0nttd/builds/KhNheRNQDimmeWs9G/openapi.json
