# Austin Building Permits API — Daily, Normalized JSON (`curative_blanket/austin-permits-api`) Actor

Daily Austin, TX building permit data as clean, normalized JSON. New construction, roofing, solar, HVAC, electrical & plumbing permits with contractor, address, valuation & geo. Deduplicated, pay-per-result. Official open data for lead gen, proptech & AI agents.

- **URL**: https://apify.com/curative\_blanket/austin-permits-api.md
- **Developed by:** [Salim](https://apify.com/curative_blanket) (community)
- **Categories:** Real estate, Lead generation, AI
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 permit records

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Austin Building Permits API — Daily, Normalized JSON (Construction, Solar, Roofing, HVAC Leads)

**Get fresh Austin, TX building permits every day as clean, normalized JSON.**
New residential and commercial construction, roofing, solar, HVAC, electrical,
and plumbing permits — each record carries the contractor, address, permit type,
work class, status, valuation, and (where available) geo-coordinates. Built for
**lead generation, proptech, and AI agents**, deduplicated so you never pay twice
for the same permit.

This Actor reads the **City of Austin's official open-data API** (Socrata dataset
`3syk-w9eu`, "Issued Construction Permits"), which the city refreshes daily. No
scraping, no stale snapshots — just the authoritative source, normalized.

***

### Who this is for

#### 🌞 Solar, roofing & HVAC lead generation

A new roofing, solar, mechanical, or plumbing permit is a high-intent buying
signal. Pull **newly issued permits by work class every morning**, filter to your
trade, and feed your sales pipeline addresses that just committed to a project —
often with the **contractor name and phone** already attached. Set it on a daily
schedule and you get a continuous, deduplicated stream of fresh jobs in your
service area.

#### 🏠 Proptech & real estate

Permits are a leading indicator of property activity — renovations, additions,
new builds, and valuations before they show up anywhere else. Use this feed to
**enrich property records, score neighborhoods, track construction velocity, and
flag value-add events** by parcel (`parcel_id` / TCAD ID) and address.

#### 🤖 AI agents & MCP / automation users

Stable schema, one record per permit, JSON-native, pay-per-result. Drop it into
an **agent workflow, MCP tool, or scheduled pipeline** and get deterministic,
well-typed permit data without writing a Socrata client or babysitting field-name
changes. The full original record is preserved under `_raw` for power users.

***

### Why not just call the city API directly?

The raw Socrata endpoint is workable but rough: inconsistent and occasionally
**mislabeled field names**, nested objects (the source URL is buried in a nested
`link.url`), fields that appear on some records and not others, and **no
deduplication** for daily pulls. This Actor gives you:

- **One stable output schema** — the same keys on every record, forever. Missing
  source data is `null`-filled, never dropped.
- **Daily fresh** — schedule it; the city updates daily and this Actor pulls only
  what's new in your chosen window.
- **Deduplicated across runs** — keyed on permit ID and persisted between runs, so
  daily schedules don't re-deliver or **re-charge** for permits you already have.
- **Pay only for results** — empty runs cost nothing.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | enum | `delta` | `delta` = permits issued in the last N days (best for daily schedules). `backfill` = a fixed `issued_date` range. |
| `days_back` | int | `7` | Delta mode: how many days back from today to pull. |
| `start_date` | string | — | Backfill mode: inclusive lower bound on issued date (`YYYY-MM-DD`). |
| `end_date` | string | today | Backfill mode: inclusive upper bound (`YYYY-MM-DD`). |
| `max_results` | int | `5000` | Safety cap on **new** records pushed (and charged) per run. |
| `app_token` | string (secret) | — | Optional Socrata app token for higher rate limits. Not required. |
| `reset_dedup` | bool | `false` | Clears the seen-ID memory before the run. Testing / deliberate re-pull only. |

#### Example — daily lead-gen schedule

```json
{ "mode": "delta", "days_back": 2, "max_results": 5000 }
```

#### Example — one-time historical backfill

```json
{ "mode": "backfill", "start_date": "2026-01-01", "end_date": "2026-03-31" }
```

***

### Output

Every record has **exactly these keys**. Missing source data is `null`-filled. The
full untouched source record is preserved under `_raw`.

```json
{
  "permit_id": "2026-066944 PP",
  "jurisdiction": "Austin, TX",
  "source_dataset": "3syk-w9eu",
  "permit_type": "Plumbing Permit",
  "permit_class": "Residential",
  "work_class": "Repair",
  "status": "Active",
  "applied_date": "2026-05-27T00:00:00.000",
  "issued_date": "2026-06-02T00:00:00.000",
  "expiration_date": "2026-11-29T00:00:00.000",
  "address": "5418 FAIRMONT CIR",
  "city": "AUSTIN",
  "state": "TX",
  "zip": "78745",
  "latitude": 30.21829231,
  "longitude": -97.79863071,
  "valuation": null,
  "work_description": "Gas test",
  "contractor_name": "Sal's Plumbing",
  "contractor_full_name": "Salomon Garcia",
  "contractor_trade": "Plumbing Contractor",
  "contractor_phone": "5127487537",
  "contractor_city": "Austin",
  "contractor_zip": "78745",
  "owner_or_applicant_name": null,
  "parcel_id": "0412131402",
  "source_url": "https://abc.austintexas.gov/web/permit/public-search-other?...",
  "pulled_at": "2026-06-04T09:12:25.338Z",
  "_raw": { "...": "full original source record" }
}
```

When a run finds **no new permits**, it pushes a single informational item
(`{"info": "no_new_results", ...}`) and **does not charge you**.

***

### Coverage & honest limitations (please read before buying)

We'd rather you buy with clear expectations than leave a bad review.

- **City:** **Austin, TX only** in v1. For multi-city coverage (Chicago, New York, Los Angeles, Seattle, San Francisco), see [US Building Permits — Multi-City](https://console.apify.com/actors/YqUBDgQB34l1BKfMc) — same schema, 6 cities, one Actor.
- **Freshness:** The City of Austin refreshes the source dataset daily. Schedule
  this Actor daily to stay current. We do not control the city's update timing.
- **Geo is partial.** `latitude` / `longitude` are present on **most but not all**
  records. Keys are always present; `null` when the city didn't publish
  coordinates for that permit. Don't assume 100% geocoding.
- **Valuation is partial.** `valuation` is frequently **absent on trade permits**
  (electrical, plumbing, mechanical) and null-filled there. Each run logs how
  often it was missing.
- **No owner / applicant data.** The Austin dataset does **not** include property
  owner or applicant names. `owner_or_applicant_name` is always `null`. If you
  need owner data, this source can't provide it.
- **Contractor phone is raw and dirty.** Source phone/zip values are inconsistent
  and sometimes junk. We pass them through **unmodified** — no cleaning or
  validation. Validate on your side before dialing.
- **Deduplication** is keyed on `permit_id`, so daily runs won't re-deliver or
  re-charge permits you've already received.

***

### Pricing

**Pay per result:** **$2.50 per 1,000 permit records** ($0.0025 each). You are
charged only for **new, delivered** records. Deduplicated records and empty runs
are **not** charged.

***

### Legal

This Actor delivers **public open-government data** published by the City of
Austin. It is **NOT an FCRA consumer report** and **must not** be used for credit,
employment, tenant screening, insurance eligibility, or any other FCRA-regulated
decision. Use it for market research, lead generation, analytics, and similar
permitted purposes. You are responsible for your own compliance, including any
applicable do-not-call obligations when contacting contractors.

***

Source: [City of Austin Open Data — Issued Construction Permits (3syk-w9eu)](https://data.austintexas.gov/Building-and-Development/Issued-Construction-Permits/3syk-w9eu)

# Actor input Schema

## `mode` (type: `string`):

delta = pull permits issued in the last N days (best for daily scheduled runs). backfill = pull a fixed issued\_date range.

## `days_back` (type: `integer`):

In delta mode, pull permits with issued\_date within the last N days (relative to today, UTC). Default is 30 so a normal daily run reliably returns a healthy batch of Austin permits (keeps the Store health-check non-empty).

## `start_date` (type: `string`):

Backfill only. Inclusive lower bound on issued\_date. Format: YYYY-MM-DD.

## `end_date` (type: `string`):

Backfill only. Inclusive upper bound on issued\_date. Format: YYYY-MM-DD. Defaults to today if omitted.

## `max_results` (type: `integer`):

Hard cap on the number of NEW (non-duplicate) records pushed this run. Protects against runaway pulls and unexpected charges.

## `app_token` (type: `string`):

Optional Socrata app token for higher rate limits. Get a free one at https://data.austintexas.gov/profile/edit/developer\_settings. Works fine without it for small runs.

## `reset_dedup` (type: `boolean`):

If true, clears the set of previously-seen permit IDs before this run. Use only for testing or a deliberate re-pull (will re-charge for records seen before).

## Actor input object example

```json
{
  "mode": "delta",
  "days_back": 30,
  "start_date": "2026-01-01",
  "end_date": "2026-01-31",
  "max_results": 200,
  "reset_dedup": false
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("curative_blanket/austin-permits-api").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("curative_blanket/austin-permits-api").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 '{}' |
apify call curative_blanket/austin-permits-api --silent --output-dataset

```

## MCP server setup

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

```

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/ep14IZeCbUhnQri5X/builds/SQ7n2WEp2NTaGuL2b/openapi.json
