# Austin Commercial Permit Evidence (`jj_toolworks/austin-commercial-permit-evidence`) Actor

Export Austin-issued permits with the city's Commercial class, date filters, and traceable roof, envelope, HVAC, or renovation keyword evidence. A bounded, source-linked pilot.

- **URL**: https://apify.com/jj_toolworks/austin-commercial-permit-evidence.md
- **Developed by:** [JJ Toolworks](https://apify.com/jj_toolworks) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 returned permit evidences

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

## Austin Commercial Permit Evidence

Review permit records issued by the City of Austin, selected by the city's published Commercial class, calendar dates, and traceable trade keywords. Each result links back to the source and shows the exact text behind its roof, envelope, HVAC, or renovation classification.

This is an Austin-only research pilot. A permit is evidence of a dated source record. It does not establish that a job is available, that work was completed, that a property currently needs work, or the age of a roof.

### Example

```json
{
  "trades": ["roof"],
  "dateField": "issue_date",
  "lookbackDays": 30,
  "maxRecords": 100
}
```

Choose one or more `trades`: `roof`, `envelope`, `hvac`, or `renovation`. The selection uses OR matching. `dateField` can be `issue_date` or `applieddate`. The default window is the 30 calendar days through the run's UTC date. Optional `startDate` and `endDate` accept `YYYY-MM-DD`, inclusive, for a maximum 366-day window. An explicit start date overrides `lookbackDays`.

The underlying source contains issued permits. Selecting original application dates does not expand it into a database of all submitted or still-pending applications. Source calendar dates are retained as provided; the Actor does not invent their time zone.

### Output and buyer workflows

Filter `recordType=permit` for paid records. Outputs include source permit/project ID, permit number, location, original permit link, original published class, work/permit type, description, selected trade evidence, raw application/issue/status dates, and the current source permit status. Coordinates are included when valid source values exist. Applicant and contractor personal columns are not requested or exported.

`tradeEvidence` identifies the exact source field, matched text, offsets, and nearby excerpt. Presets use deterministic words, not a model-generated lead score. Roof mentions can refer to rooftop equipment. Renovation mentions can include work outside your niche. Review the source description and permit before qualifying a commercial opportunity.

Three text columns make that evidence easier to review in a CSV export:

| Column | What it shows |
|---|---|
| `matchedTradesText` | Matched trades in a simple text cell, such as `roof, envelope` |
| `tradeEvidenceBasis` | Source fields supporting each trade, such as `roof: description` or `hvac: permit type only` |
| `tradeEvidenceText` | Exact matched phrases grouped by trade and source field |

The original `tradeEvidence` entries and offsets remain available. `permit type only` tells you that an HVAC label is supported by the published Mechanical permit type without a matching description phrase. It is not a confidence score or proof of the particular equipment involved. The text columns add no source requests or event fees.

Useful workflows include weekly supplier territory research, contractor project qualification, and source-backed property work-history research. Save task inputs and use Apify's scheduling/export features for recurring refreshes. Repeated exports use stable source IDs, but a physical project can have several distinct permits.

`recordType=query_status` and the `SUMMARY` key-value-store record report exact date/preset scope, source query URL, metadata freshness, filtering, invalid rows, and truncation. `complete` applies only to this bounded source query. The city's data can change between runs; preserve snapshot/fetch timestamps for comparisons.

### Reusable contractor and supplier workflows

Use these input settings to reuse one source adapter across several buyers. Each row uses `dateField: "issue_date"`; leave explicit start/end dates blank for a rolling window. The cadence is a suggested review frequency, not an already-created schedule.

| Workflow | `trades` | `lookbackDays` | `maxRecords` |
|---|---|---:|---:|
| Weekly roofing supplier review | `["roof"]` | 14 | 100 |
| Monthly envelope supplier review | `["envelope"]` | 45 | 100 |
| Weekly HVAC distributor review | `["hvac"]` | 14 | 100 |
| Weekly renovation contractor review | `["renovation"]` | 14 | 100 |
| Monthly roof and envelope supplier review | `["roof", "envelope"]` | 45 | 200 |
| Weekly contractor review across four trades | `["roof", "envelope", "hvac", "renovation"]` | 14 | 200 |

Overlapping windows let a reviewer revisit recently issued records as the source updates. They do not guarantee recovery of every delayed or backfilled record. Deduplicate separate exports using `recordId` in your destination; this Actor does not keep automatic history across runs. A permit returned again in another run is another returned-record event. Within one combined run, a permit matching several trades creates one event.

Start by checking `query_status`. If it is `truncated`, shorten the date window or increase the cap within the 500-record limit; a shorter window provides narrower coverage. Review the original class, description, and current permit status before deciding whether a project is relevant. These inputs create source-evidence review queues, not lists of verified open jobs or contractor contact details.

### Source scope and maintenance

The source is the City's [Issued Construction Permits dataset](https://data.austintexas.gov/Building-and-Development/Issued-Construction-Permits/3syk-w9eu/about_data), via its [public API](https://data.austintexas.gov/resource/3syk-w9eu.json). It advertises daily updates. Dataset metadata's reported update time is included when available; its absence is marked unknown rather than replaced with the Actor's fetch time. The City describes its data as informational and subject to change.

The exact `permit_class_mapped=Commercial` filter preserves the City's mapping, whose metadata describes non-R permit classes as commercial. This is not independently verified building occupancy and can include multifamily or other source classes. Austin's permitting dataset also includes some extraterritorial areas; not every source location is necessarily inside city limits. The original permit class and jurisdiction are included for your review.

### Bounds and charging

One event per distinct valid permit record emitted in the run. Duplicates, rejected source rows, keyword-filter exclusions, failed requests, and status/summary rows are unbilled. Valid capped output remains usable and is labeled `truncated`.

Maximum 500 output records per run. One data request asks for the requested candidate limit plus one sentinel; precise word matching can return fewer results than the broad server substring predicate. A sentinel flags the source candidate cap even when some candidates are filtered out. No pagination or automatic retries create hidden extra work. One independent bounded metadata request supplies freshness context. Limits are 5 MiB for data, 2 MiB for metadata, and 30/20-second request timeouts.

Use the supplied original sources and [City data terms](https://data.austintexas.gov/stories/s/ranj-cccq) when evaluating reuse. No private lead database, inferred decision maker, automatic contact discovery, outreach, or other-city source is included.

### Price and run controls

The launch price is **$2 per 1,000 completed units** ($0.002 per event), as defined above. Check the current Pricing tab before running. Status and duplicate rows do not add this custom event. Set a maximum charge appropriate for your batch; a run stops when its event budget is exhausted. `RUN-SUMMARY` records actual accepted events and execution totals.

Automatic replay of an interrupted run is disabled to prevent duplicate charges. Keep the available output, then start a new run for a new execution. A later run is a new billable execution. Completed dataset rows and individually saved files remain available when a budget stops a run. Combined exports, manifests, and snapshots assembled at the end may be absent after a budget stop or interruption; use a sufficient run budget when you need those aggregate files. The initial release uses documented input limits and public source access; external source changes can require maintenance.

# Actor input Schema

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

OR selection of traceable keyword presets. Matches describe source text/type evidence and still require project qualification.

## `dateField` (type: `string`):

Both filters apply within the City's Issued Construction Permits dataset. Applied date does not add applications absent from that source.

## `lookbackDays` (type: `integer`):

Used when startDate is blank. End date defaults to the run's current UTC date; source records keep their original calendar dates.

## `startDate` (type: `string`):

YYYY-MM-DD inclusive. Overrides lookbackDays. Maximum 366 inclusive calendar days.

## `endDate` (type: `string`):

YYYY-MM-DD inclusive. Defaults to the run's current UTC date.

## `maxRecords` (type: `integer`):

One bounded source request asks for this many candidate rows plus a truncation sentinel. Precise matching can return fewer records. No automatic pagination.

## Actor input object example

```json
{
  "trades": [
    "roof"
  ],
  "dateField": "issue_date",
  "lookbackDays": 30,
  "maxRecords": 5
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "trades": [
        "roof"
    ],
    "dateField": "issue_date",
    "lookbackDays": 30,
    "maxRecords": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("jj_toolworks/austin-commercial-permit-evidence").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 = {
    "trades": ["roof"],
    "dateField": "issue_date",
    "lookbackDays": 30,
    "maxRecords": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("jj_toolworks/austin-commercial-permit-evidence").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 '{
  "trades": [
    "roof"
  ],
  "dateField": "issue_date",
  "lookbackDays": 30,
  "maxRecords": 5
}' |
apify call jj_toolworks/austin-commercial-permit-evidence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jj_toolworks/austin-commercial-permit-evidence"
        }
    }
}
```

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/JDrTaNsN7aCt1FfSc/builds/qfIKqCWiE4V18PuZc/openapi.json
