# UCC Lien Filing Scraper — CT + CO State Portals (`devilscrapes/ucc-lien-filing-scraper`) Actor

Bulk-export UCC (Uniform Commercial Code) financing-statement lien filings from Connecticut and Colorado state open-data portals — debtor, secured party, filing date, status, one normalized row per filing across both states in a single run. No API key, no login.

- **URL**: https://apify.com/devilscrapes/ucc-lien-filing-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

<div align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />

## UCC Lien Filing Scraper — CT + CO State Portals

**💰 $5.20 / 1 000 results**  ·  pay only for results  ·  no credit card to try

*We do the dirty work so your dataset stays clean.* 😈

Bulk-export UCC (Uniform Commercial Code) financing-statement lien filings from Connecticut and Colorado's official state open-data portals — debtor, secured party, filing date, lapse date, and status, normalized into one row per **filing–debtor pair** across both states in a single run. A filing with 3 debtors on it ships as 3 rows, one per debtor — see Output below and the pricing note under Pricing. No API key, no login.

</div>

***

### 🎯 What this scrapes

Connecticut and Colorado both publish their UCC financing-statement filings as public Socrata open-data datasets — but each state ships its own field names, its own join shape, and its own quirks (Colorado alone splits filings, debtors, and secured parties across three linked datasets). This Actor queries both states' official portals directly, joins Colorado's three-way split in memory, and maps everything — CT and CO alike — onto one common `ResultRow` shape, so you get a single normalized dataset instead of hand-reconciling two government schemas.

**Row granularity**: a lien filing that lists multiple debtors ships as multiple rows — one per debtor — not collapsed into one row with a debtor list. This is the source data's own shape (Connecticut's dataset already ships one record per debtor per filing) and it's the more useful shape for lead-gen: every debtor gets its own row with its own name/address, ready to import as a contact. Rows sharing the same `filing_id` are the same underlying lien.

A new UCC filing against a business is a buy-intent / expansion signal — the business just took on secured financing — which is why commercial lenders, credit teams, and lead-gen shops watch this data on a recurring basis.

### 🔥 What we handle for you

- 🛡️ **Browser fingerprint rotation** — every request goes through `curl-cffi` with real Chrome/Firefox TLS impersonation, as defense-in-depth even against a plain public API.
- 🔁 **Retries with exponential backoff** on `408 / 429 / 5xx` — up to 5 attempts per page, `Retry-After` honoured.
- 🧱 **Rate-limit-aware pacing** — if a state portal pushes back, we back off instead of hammering it and losing the run.
- 🧊 **Clean, typed dataset rows** — Pydantic-validated, ISO-8601 timestamps, stable filing IDs, one schema across two states' worth of source-format differences.
- 🧩 **Per-filing fault isolation** — if one Colorado filing's debtor/secured-party join comes back empty, that row still ships (with the missing fields set to null) instead of the whole run failing over one bad record.
- 💰 **Pay-Per-Event pricing** — you only pay for filings that land in your dataset. No data, no charge.

### 💡 Use cases

- Commercial lenders and credit-risk teams watching for new secured financing against target debtors.
- Skip tracers and collections shops tracking lien activity on a name or business.
- B2B lead-gen operators re-running the search on a cadence to catch newly filed liens — a fresh UCC filing is a signal the business just took on capital.
- Due-diligence checks on a counterparty's existing secured-financing exposure in CT or CO.

### ⚙️ How to use it

1. Click **Try for free** at the top of the page.
2. Pick the states to query — `CT`, `CO`, or both (default: both).
3. Set a date window — `daysBack`, or explicit `dateFrom`/`dateTo`.
4. Optionally narrow with `debtorNameContains`.
5. Click **Start**. Results stream into the run's dataset as they're found.
6. Export from **Storage → Dataset** as JSON, CSV, or Excel — or fetch via the API.

### 📥 Input

| Field | Type | Required | Default | Notes |
|---|---|:--:|---|---|
| `states` | `array` | no | `["CT", "CO"]` | Which state UCC datasets to query. |
| `daysBack` | `integer` | no | `90` | Rolling window back from today, applied to CT's filing-acceptance date and CO's filing date. Ignored when `dateFrom` is set. |
| `dateFrom` | `string` | no | — | Explicit filing-date lower bound, ISO `YYYY-MM-DD`. Wins over `daysBack` when set. |
| `dateTo` | `string` | no | — | Explicit filing-date upper bound, ISO `YYYY-MM-DD`. Defaults to today when `dateFrom` is set and this is omitted. |
| `debtorNameContains` | `string` | no | — | Substring filter against the debtor name (business or individual). |
| `maxResults` | `integer` | no | `500` | Hard cap on total rows emitted across all requested states in one run. |
| `proxyConfiguration` | `object` | no | `{"useApifyProxy": false}` | Off by default — CT and CO's portals are public keyless APIs with no fingerprinting observed. Flip it on if you ever see a 403/429. |

#### Example input

```json
{
  "states": ["CT", "CO"],
  "daysBack": 14,
  "debtorNameContains": "",
  "maxResults": 25,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

### 📤 Output

One row per **filing–debtor pair**, joined across CT's and CO's differing native schemas into a single shape. A filing with multiple debtors emits multiple rows that share the same `filing_id` and differ on the `debtor_*` fields — use `filing_id` to group rows back into "all debtors on this lien" if that's what you need. A filing with a single debtor (the common case) emits exactly one row.

| Field | Type | Notes |
|---|---|---|
| `state` | `string` | `CT` or `CO` — which dataset matched. |
| `filing_id` | `string` | CT: the state's lien filing number. CO: the filing's `fileid`. |
| `filing_date` | `string` | ISO `YYYY-MM-DD`. |
| `lapse_date` | `string, null` | ISO `YYYY-MM-DD`. Null when the source record doesn't carry a lapse date. |
| `filing_type` | `string` | CT: the state's filing-type code (e.g. "ORIG FIN STMT"). CO: always `ucc` in v1. |
| `filing_description` | `string, null` | Free-text description where the source dataset provides one; frequently null. |
| `transaction_type` | `string, null` | Derived: `original` or `amendment`, when determinable. |
| `is_amendment` | `boolean` | Derived from `transaction_type`. |
| `debtor_name` | `string` | Business name, or `"last, first"` for individual debtors. |
| `debtor_address` | `string, null` | Street address on file. Null when the source record omits it. |
| `debtor_city` | `string, null` | |
| `debtor_state` | `string, null` | |
| `debtor_zip` | `string, null` | |
| `secured_party_name` | `string, null` | Null on the rare CO filing whose secured-party join returns no match — the row still ships. |
| `secured_party_address` | `string, null` | |
| `secured_party_city` | `string, null` | |
| `secured_party_state` | `string, null` | |
| `secured_party_zip` | `string, null` | |
| `status` | `string` | One of `active`, `lapsed`, `terminated`, `unknown` — derived from the source state's own status field. |
| `source_record_url` | `string` | Direct query against the source portal for this exact filing. |
| `registry_url` | `string` | Human-readable landing page for the source state dataset. |
| `scraped_at` | `string` | ISO-8601 UTC timestamp when this row was recorded. |

#### Example output

```json
{
  "state": "CT",
  "filing_id": "0002345678",
  "filing_date": "2026-05-21",
  "lapse_date": "2031-05-21",
  "filing_type": "ORIG FIN STMT",
  "filing_description": "All assets",
  "transaction_type": "original",
  "is_amendment": false,
  "debtor_name": "ACME WIDGETS LLC",
  "debtor_address": "12 Main St",
  "debtor_city": "Hartford",
  "debtor_state": "CT",
  "debtor_zip": "06103",
  "secured_party_name": "FIRST STATE BANK",
  "secured_party_address": "1 Finance Plaza",
  "secured_party_city": "Stamford",
  "secured_party_state": "CT",
  "secured_party_zip": "06901",
  "status": "active",
  "source_record_url": "https://data.ct.gov/resource/xfev-8smz.json?id_lien_flng_nbr=0002345678",
  "registry_url": "https://data.ct.gov/d/xfev-8smz",
  "scraped_at": "2026-09-22T14:03:11Z"
}
```

Individual (non-business) debtors and secured parties, and Colorado filings whose join comes back empty, will show `null` on the corresponding name/address fields rather than a fabricated value — that's the source data, not a bug.

### 💰 Pricing

**Billing unit is a row, and a row is a filing–debtor pair — not a filing.** A filing with 3 debtors bills as 3 `result-emitted` events, not 1. Most filings have exactly one debtor, but if you're budgeting off a count of *filings* rather than *debtors*, your actual charge can run higher than that count. Set `maxResults` accordingly.

Pay-Per-Event — you pay only when these events fire:

| Event | USD | What it is |
|---|---:|---|
| `actor-start` | $0.20 | One-off warm-up charge per run |
| `result-emitted` | $0.005 | Per filing–debtor-pair row written to the dataset |

Example: 1 000 rows at the rates above = **$5.20**. No subscription, no minimum, no card to start — Apify gives every new account free credit to try it.

### 🚧 Limitations

- **Coverage is Connecticut and Colorado only.** This is not a national UCC search — if the debtor you're checking only filed in a third state, this Actor will correctly return zero rows for it. Adding more states is on the roadmap, not shipped.
- Colorado's `lien_irs` and `lien_hosp` filing types are out of scope in v1 — UCC filings (`filingtype == "ucc"`) only.
- This is a point-in-time bulk export, not a monitoring/alerting service. Re-run on a schedule to catch newly filed liens.
- Full-text collateral/UCC-1 document images are not retrieved — this Actor emits structured index fields, not scanned filings.
- Individual (non-organization) debtors/secured parties on Colorado filings are handled defensively, but their field shape is less consistently populated than business filings — expect more nulls on that subset.

### ❓ FAQ

**Does this need an API key or login?**

No — both state portals are public, keyless open-data APIs.

**What if my search matches nothing?**

The run finishes successfully with zero rows and a status message describing what was searched — a genuinely empty result is a completed search, not a failure.

**Does this cover UCC filings nationwide?**

No — v1 is Connecticut and Colorado only. Don't rely on this Actor to clear a debtor across all 50 states.

**Can I search by debtor name?**

Yes — set `debtorNameContains` to filter both states' results to debtor names containing that substring.

### 💬 Your feedback

Spotted a bug, hit a weird edge case, or need a new state added? Open an
issue on the Actor's **Issues** tab on Apify Console — we ship
fixes weekly and we read every report.

***

<div align="center">

Built by **[Devil Scrapes](https://apify.com/DevilScrapes)** 😈 — a small fleet of
opinionated public-data Actors. Honest pricing, real engineering, zero fine print.

</div>

# Changelog

This Actor's version history is a separate document: https://apify.com/devilscrapes/ucc-lien-filing-scraper/changelog.md

# Actor input Schema

## `states` (type: `array`):

Which state UCC datasets to query (more states coming).

## `daysBack` (type: `integer`):

Rolling window back from today, applied to CT's filing-acceptance date and CO's filing date. Ignored when Date from is set.

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

Explicit filing-date lower bound, ISO YYYY-MM-DD (inclusive). Wins over Days back when set.

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

Explicit filing-date upper bound, ISO YYYY-MM-DD (inclusive). Defaults to today when Date from is set and this is omitted.

## `debtorNameContains` (type: `string`):

Substring filter against the debtor name (business or individual).

## `maxResults` (type: `integer`):

Hard cap on total rows emitted across all requested states in one run.

## `proxyConfiguration` (type: `object`):

Optional — these are public keyless SODA REST APIs, not known to fingerprint clients. Leave off unless you see 403/429.

## Actor input object example

```json
{
  "states": [
    "CT",
    "CO"
  ],
  "daysBack": 14,
  "maxResults": 25,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `output` (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 = {
    "states": [
        "CT",
        "CO"
    ],
    "daysBack": 14,
    "maxResults": 25,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/ucc-lien-filing-scraper").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 = {
    "states": [
        "CT",
        "CO",
    ],
    "daysBack": 14,
    "maxResults": 25,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/ucc-lien-filing-scraper").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 '{
  "states": [
    "CT",
    "CO"
  ],
  "daysBack": 14,
  "maxResults": 25,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call devilscrapes/ucc-lien-filing-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/ucc-lien-filing-scraper"
        }
    }
}
```

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/OV1emy7PdAnQsqbhl/builds/HOgTicSWEhYkZoU3q/openapi.json
