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_records reported on the first and final page
  • Whether one_filing_per_debtor was 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 429 and transient 5xx responses with backoff, but keep the same page number until it succeeds.
  • Write completed pages incrementally so a failed run can resume.
  • Deduplicate by ucc_id when combining multiple overlapping searches.
  • Use company_id or base_url when producing a debtor-level rollup.
  • Keep all filings when analyzing volume or lifecycle history; use one_filing_per_debtor only 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.