UCC Workflows
Analyze UCC results at scale
Paginate public UCC search results, preserve nested fields, and produce a reviewable CSV dataset.
The public debtor and secured-party endpoints return up to 50 records per page. Use response metadata to collect a bounded result set for analysis, reconciliation, or import into another system.
Start with a narrow query
Define the population before downloading pages. This example finds recent active organizational filings and returns the latest filing per debtor.
{
"state_filing": ["TX", "OK"],
"date_filed": "90 days",
"debtor_type": "Organization",
"is_active_filing": true,
"one_filing_per_debtor": true,
"page": 1,
"per_page": 50
}Run the first page and inspect total_records and total_pages before collecting the entire search.
Write paginated results to CSV
The script below:
- Requests pages in order
- Stops at the server-provided
total_pages - Applies an optional page limit
- Selects stable analysis columns
- Serializes nested assets and amendments as JSON
import csv
import json
import os
import time
import requests
API_KEY = os.environ["LEADX_API_KEY"]
ENDPOINT = "https://api.leadx.com/v1/ucc/debtor"
OUTPUT_PATH = "ucc-analysis.csv"
MAX_PAGES = 100
payload = {
"state_filing": ["TX", "OK"],
"date_filed": "90 days",
"debtor_type": "Organization",
"is_active_filing": True,
"one_filing_per_debtor": True,
"per_page": 50,
}
columns = [
"ucc_id",
"ucc_number",
"company_id",
"company_name",
"base_url",
"state",
"state_db",
"date_filed",
"date_expired",
"filing_status",
"is_active_filing",
"secured_party",
"secured_party_base_url",
"industry",
"naics_code",
"collateral",
"assets",
"amendments",
]
def csv_value(value):
if isinstance(value, (dict, list)):
return json.dumps(value, separators=(",", ":"), ensure_ascii=False)
return value
with open(OUTPUT_PATH, "w", newline="", encoding="utf-8") as output:
writer = csv.DictWriter(output, fieldnames=columns)
writer.writeheader()
page = 1
while page <= MAX_PAGES:
payload["page"] = page
response = requests.post(
ENDPOINT,
headers={"X-API-KEY": API_KEY},
json=payload,
timeout=60,
)
response.raise_for_status()
body = response.json()
for record in body["records"]:
writer.writerow({
column: csv_value(record.get(column))
for column in columns
})
print(f'Wrote page {page} of {body["total_pages"]}')
if page >= body["total_pages"]:
break
page += 1
time.sleep(0.5)
print(f"Saved {OUTPUT_PATH}")To analyze a secured-party population, change ENDPOINT to https://api.leadx.com/v1/ucc/secured_party and use a secured-party request body.
Preserve analysis context
Save the following beside the output file:
- Endpoint and request body
- Exported page range
- Request timestamp and timezone
total_recordsreported on the first and final page- Whether
one_filing_per_debtorwas enabled - The field list used in the CSV
- Any retry or skipped-page information
This context makes the result reproducible and explains why a later run may differ.
Handle large searches
- Narrow by filing date, status, jurisdiction, company profile, collateral, or secured party before collecting pages.
- Set an application-level page or record ceiling.
- Retry
429and transient5xxresponses with backoff, but keep the same page number until it succeeds. - Write completed pages incrementally so a failed run can resume.
- Deduplicate by
ucc_idwhen combining multiple overlapping searches. - Use
company_idorbase_urlwhen producing a debtor-level rollup. - Keep all filings when analyzing volume or lifecycle history; use
one_filing_per_debtoronly for a latest-company view.
Do not assume total_records is a permanent snapshot. Filings and enrichment fields can change while a long pagination run is in progress.
Suggested derived metrics
After preserving the filing-level rows, you can calculate:
- Filings by jurisdiction and month
- Active, lapsed, and terminated counts
- Unique debtors and secured parties
- New filing trends
- Collateral and structured-asset distributions
- Upcoming expiration buckets
- Amendment and continuation rates
- Debtor industry, size, and geographic distributions
Keep derived metrics separate from the raw response columns so analysts can trace every calculation back to its source filing.