Skip to content

County and court
portal scraping,
delivered daily.

The records are public. Getting them out, every day, without a person clicking through a clerk’s site, is the hard part. We build the scraper, skip trace it if you want, check it before it reaches you, and fix it when the portal changes. Judgments, probate, mortgage and divorce records, plus foreclosure and UCC wherever a portal publishes them.

We reply within 24 hours. Free pilots go to businesses we select, based on the data you need and your business needs, and the sheet arrives within 7 days. No call required, no contract, you keep the data either way. One pilot per company.

One portal in. A checked file out.

  1. Portal

    One form-gated public portal. Usually a platform we already know.

    • Identify the vendor platform behind it
    • Session, disclaimer and login flow
    • Decide scrapeable, hard, or no, and say which
  2. Extraction

    The hard part. Caps, captchas and session state, handled per portal.

    • Date-range chunking under result caps
    • Captcha and bot-protection handling
    • Polite throttling, resumable runs
  3. Filter & dedupe

    Record type, date window, entity filtering, and dedupe against what you already have.

    • Drop corporate and government parties
    • Plaintiff / defendant split
    • Dedupe by case id and party
  4. Skip trace, enrich, validate

    Optional. A raw name becomes a validated phone, or it gets dropped.

    • Address, phone and age lookup
    • Line type, activity score, output ready for your DNC scrub
    • Property-owner match where it applies
  5. Delivery

    Into the thing you already use. Checked before it lands, not after.

    • Google Sheets, CSV, XLSX
    • Job API, or a search app
    • Validation gate blocks a bad month

On the biggest pipeline, every month runs ten named checks before anything uploads: every record has its full party list, every name got looked up, every match row has an address. A month that fails its checks is not delivered. It is fixed, then delivered.

Examples of the work.

Each entry names the county, the portal, the thing that made it hard, and what came out. Open one for the full record to see the counts, how they are known, and the field names actually captured.

9 filed records.

  1. Broward County, Florida

    Recorded certified final judgments, joined to property ownership

    55,661
    Judgment rows

    A 124-day search cap, and an export that silently drops every co-defendant.

    124-day capCloudflareProperty match10 QA checks
    Open the record
    Portal
    Clerk of Courts Official Records (AcclaimWeb) → County Property Appraiser
    Delivered as
    Google Sheets, one county tab rebuilt per validated month, plus CSV on disk
    What made it hard

    The portal caps every search at 124 days, pages the grid at 1,000 rows, and its own CSV export carries only the first name on each side of a document, so co-defendants silently disappear from the file you get.

    How it was beaten

    Ranges chunked into month windows under the 124-day cap, then one extra call per judgment to the document-details endpoint to pull the complete party list. Cloudflare passed with Chrome TLS impersonation, no browser, with the per-document call throttled to 1.0s (0.4s drew 403s on long runs). After a block it cools down 60s, then 180s, and reopens a fresh session. Every defendant is then searched against the property appraiser under two name forms and the hits merged by folio.

    Judgment rows
    55,661
    Validated months
    104
    Debtor-with-property rows
    22,914
    QA checks per month
    10
    file-verified
    Fields captured
    • DirectName
    • IndirectName
    • RecordDate
    • DocTypeDescription
    • InstrumentNumber
    • BookType
    • BookPage
    • DocLegalDescription
    • Consideration
    • CaseNumber
    • AllDirectNames
    • AllIndirectNames
    • bcpa_match_type
    • bcpa_folios
    • bcpa_owners
    • bcpa_addresses

    Jan 2017 – Aug 2025, contiguous. Property matches are name-based, so multi-match rows are candidate properties, not confirmed ownership.

  2. Cook County IL · Kent County MI · DeKalb County GA

    Recorded mortgages and mortgage-related deeds

    57,501
    Raw rows, single runs

    A silent 1,000-result cap, so a month-long query quietly returns a third of the month.

    1,000-result cap7-day chunking3 counties
    Open the record
    Portal
    Three county recorder platforms: Clerk CRS, Tyler self-service deeds, LandmarkWeb
    Delivered as
    CSV, filtered and delivered in batches
    What made it hard

    Cook's recorder silently caps each search at 1,000 results. A month-long query looks like it worked and quietly returns a third of the month.

    How it was beaten

    Every month split into 7-day windows to stay under the cap, with an anti-forgery token pulled per session. DeKalb needs a disclaimer-acceptance POST and session continuity before it will answer; Kent needs a form submit then paged results. One shared scraper base class carries the range helpers, the corporate-entity filter and resumable runs across all three.

    Raw rows, single runs
    57,501
    Cook County IL
    33,696
    Kent County MI
    16,117
    DeKalb County GA
    7,688
    file-verified
    Fields captured
    • county
    • state
    • doc_number
    • recording_date
    • amount
    • grantor_1
    • grantor_2
    • grantor_3
    • grantee_1
    • grantee_2
    • property_address
    • legal

    Raw rows from single runs. Filtering to individual grantors inside an amount band cuts these substantially before anything is enriched.

  3. Shelby County, Tennessee

    Tax sales with excess proceeds and redemption deadlines

    10,494
    Parcel rows

    A decade of sale books as PDFs, with the layout changed four times across them.

    PDF parsing5 parsersExcess proceeds
    Open the record
    Portal
    County tax-sale Sale Book PDFs
    Delivered as
    Styled XLSX workbook
    What made it hard

    A decade of sale books published only as PDFs, and the county changed the page layout four times across them. One parser reads 2015 and returns nothing for 2020.

    How it was beaten

    Five separate layout parsers, auto-detected per document, over 38 hard-coded sale-book URLs spanning sale numbers TS 1301 to TS 2201. Header dates parsed per book and redemption deadlines resolved from them.

    Parcel rows
    10,494
    Sale books parsed
    37
    Rows with excess proceeds
    2,259
    Layout parsers
    5
    file-verified
    Fields captured
    • Parcel ID
    • Taxpayer Name
    • Property Address
    • Sale Amount
    • County Tax Owed
    • City Tax Owed
    • Total Tax Owed
    • Excess Proceeds
    • Redemption Period
    • Redemption Deadline
    • Sale Dates
    • Order Confirming Date
    • Tax Year
    • Sale Number
    • Purchaser

    Tax years 2015–2024. The optional Chancery Court status cross-check did not run on this export, so that column is empty.

  4. Georgia, statewide probate portal

    Probate estate filings with their court-document PDF links

    625
    Input cases

    A grid that only moves by postback, and estates needing 227 document-link columns.

    ViewStateTelerik gridParallel runs
    Open the record
    Portal
    ASP.NET WebForms with Telerik RadGrid, with viewstate and postbacks
    Delivered as
    CSV with PDF URLs
    What made it hard

    A grid that only moves by postback, a case match that has to be verified rather than trusted, and estates carrying so many documents the output needed 227 separate link columns.

    How it was beaten

    Browser-driven form search with grid pagination, each result verified against the case id before its detail page is scraped for PDF links. Several browsers run in parallel and append to one CSV safely using file locks, with resumable runs and a not-found extractor.

    Input cases
    625
    Result rows
    608
    Columns per row
    257
    Rows with a document link
    595
    file-verified
    Fields captured
    • the client's own input columns, preserved
    • filing detail columns
    • 227 court-document PDF link columns

    The number of distinct Georgia counties in that run was not computed.

  5. 27 states + DC

    Judgment and case-search modules, one per jurisdiction

    125
    Modules built

    Every county is a different portal, and the ones that matter are gated.

    125 modules53 shared helpers49 solvers
    Open the record
    Portal
    Tyler SmartSearch, CaseLook, CivilPublic, BenchmarkWeb, CountySuite, CTrack and others
    Delivered as
    Async job API returning one unified record schema across every jurisdiction
    What made it hard

    Every county is a different portal, and the ones that matter are gated: BotDetect image captchas, Cloudflare Turnstile, hCaptcha with a second captcha fired mid-flow, AWS WAF, JSF, Apache Wicket, an arithmetic captcha behind a real login.

    How it was beaten

    A module per jurisdiction over one shared async session pool, all request-based with no browser anywhere in the tree. 53 modules share a vendor helper, so a new county on a known platform inherits a working client instead of starting over.

    Modules built
    125
    States + DC
    27 + DC
    Sharing a vendor helper
    53
    With a solver wired in
    49
    code-verified
    Fields captured
    • party_name
    • case_name
    • case_number
    • case_type
    • party_type
    • date_filed
    • case_detail_id
    • case_detail_link

    Code-verified only. These are modules built, not counties running today, and no record counts are claimed for any of them without a fresh run.

  6. National

    Skip trace, then validation. A raw name becomes a reachable phone or it is dropped

    11
    Enrichment sources wired

    A phone number that dials is not the same as a phone number that exists.

    Line typeActivity scoreAddress match
    Open the record
    Portal
    Licensed identity APIs and people-search sources, plus phone validation
    Delivered as
    Merged and deduped CSV, normalized against the client's existing list
    What made it hard

    A phone number that dials is not the same as a phone number that exists. Raw skip-trace output is full of voicemail boxes, non-fixed VoIP, and addresses that do not match the property the record came from.

    How it was beaten

    Lookup for current address, phone and age, then a validation gate: line type and activity score per number, voicemail and non-fixed VoIP marked invalid, phone numbers put in one standard format, a second validator as a cross-check, ZIP and area-code allow-lists, an age filter, and a yes/no flag on whether the found address matches the recorded property address. Runs resume by skipping leads already enriched, and failed lookups are refunded rather than billed.

    Enrichment sources wired
    11
    Cook County: raw → filtered
    33,696 → 14,800
    → delivered batches
    2,160
    → final deduped
    616
    code-verified
    Fields captured
    • current address
    • phone
    • age
    • line_type
    • activity_score
    • phone_verified
    • address_match_flag
    • identity_score
    • last_reported_date

    That funnel is one county's absolute counts, not a published pass rate. Yours depends on the record type and how clean the names are.

  7. Franklin County, Ohio

    Civil court party records, searched by business name

    360,650
    Data rows

    Volume, until the delivery destination becomes the constraint, not the scraper.

    360k rowsSheets delivery10M-cell guard
    Open the record
    Portal
    County Common Pleas clerk portal
    Delivered as
    Google Sheets, one tab per court per month, with a 10,000,000-cell guard
    What made it hard

    Volume. A run across roughly 1,870 search terms against one county produces a file large enough that the delivery destination, not the scraper, becomes the constraint.

    How it was beaten

    Unattended resumable runs with failed-term retry files, then a cleaning stage that splits plaintiff from defendant and drops corporate and government parties to leave individuals. Delivery checks the destination workbook's total cell count before writing and stops cleanly rather than failing mid-upload.

    Data rows
    360,650
    Unique case numbers
    218,348
    file-verified
    Fields captured
    • search_term
    • case_number
    • case_type_category
    • party_name
    • party_type
    • case_title
    • filing_date
    • status

    Party-per-case rows, not deduplicated unique cases. The unique-case-number figure is the one to compare against.

  8. Missouri, statewide judgment index

    Recorded judgments by party name, and a lesson about trusting row counts

    682
    Delivered after dedupe

    A 2.2 GB file with 9.8 million rows in it, and every row looked legitimate.

    DedupeQA catchPagination loop
    Open the record
    Portal
    State case-management judgment index
    Delivered as
    Deduped CSV: the 682, not the 9.8 million
    What made it hard

    The run produced a 2.2 GB file with 9,797,294 rows in it. It was not 9.8 million judgments. It was a pagination loop returning the same records over and over, and every row looked completely legitimate.

    How it was beaten

    An audit that counts distinct case ids rather than rows. 9,797,294 rows held 739 distinct case ids and two distinct search terms. Deduped properly, the real deliverable was 682 rows. This is why the delivered number and the scraped number are never the same number, and why a file that looks big is not evidence of anything.

    Raw rows produced
    9,797,294
    Distinct case ids in them
    739
    Delivered after dedupe
    682
    file-verified
    Fields captured
    • search_term
    • party_name
    • first_name
    • middle_name
    • last_name
    • case_id
    • filing_date
    • judgment_date
    • judgment_desc
    • judgment_amount
    • style_of_case
    • case_type
    • county
    • circuit
    • scraped_at

    Included because it is the failure that teaches the most. The raw figure is never quoted as volume.

  9. Shelby County, Tennessee

    A delivered search tool, not a file drop

    2
    Search modes

    A portal that repeats its last page forever, so a naive pager never stops.

    Next.js appPassword gateCSV + XLSX
    Open the record
    Portal
    Sheriff's warrants portal, productized
    Delivered as
    Deployed password-gated web app with CSV and XLSX export
    What made it hard

    The portal repeats its last page forever instead of returning an empty one, so a naive pager never stops. And the client did not want a CSV. They wanted to search it.

    How it was beaten

    Pagination terminates when a page's warrant-number set matches the previous page. Desktop view first, mobile view as fallback, with a session warm-up to collect cookies before the POST. The scrape was then reimplemented in TypeScript inside a Next.js route so it runs serverless, behind a shared-password cookie gate, with CSV and Excel export in the browser.

    Search modes
    2
    Parallel implementations
    2
    Export formats in-browser
    2
    code-verified
    Fields captured
    • warrant_number
    • issue_date
    • name
    • age
    • sex
    • address
    • city
    • state
    • zip
    • charge
    • bond

    Live query volumes are not claimed. Only a small sample export exists on disk.

No client is named anywhere on this page, and no screenshot of real output exists on it. The datasets behind this work contain real people’s names and addresses, and those stay out of marketing material, including yours, when you become one of them.

What the hard portals need.

These are not features. They are the specific things that stand between a public record and a file on your desk, and each one has cost us time before.

Captcha handling
reCAPTCHA v2 and v3, hCaptcha, Cloudflare Turnstile, BotDetect distorted-text images, and audio challenges. Solved through commercial solver APIs with retry and fallback routing, and in one case through the protection vendor's own public challenge endpoint with no paid solver at all.
Bot protection on public portals
Cloudflare, Akamai, Imperva, DataDome, PerimeterX, AWS WAF and Dynatrace have all come up. Passed with Chrome TLS and HTTP fingerprint impersonation rather than a browser, with the exact header set and header ordering a real client sends. Some targets accept solved cookies replayed locally; others only answer through the solver's own forward path, so the replay route gets tested per site.
Proxies and session shaping
A rotating pool plus residential proxies with sticky sessions, rotated on a request count, with balance monitoring so a run does not die silently when credit runs out. Session expiry follows IP mismatch, and a blocked run cools down, reopens a fresh session and retries rather than hammering.
ViewState and session state
ASP.NET WebForms ViewState and EventValidation round-tripping across dozens of county sites, plus anti-forgery tokens, disclaimer-acceptance steps, Telerik RadGrid postbacks, JSF, Apache Wicket enumeration, ASP.NET AJAX envelope unwrapping, and scripted guest sessions on public portals that ask for one.
PDF parsing
Text extraction from published document sets, including multi-layout parsing where a county changed its format across years, and bulk collection of per-case document links. We do not do OCR. Scanned-image documents are outside what we have built, and we will tell you that before you pay for it.
Date-range chunking
The single most common reason a portal lies to you. A 124-day search cap chunked into months; a silent 1,000-result cap split into 7-day windows; 3-day chunks recursively halved when a chunk still hits the ceiling. A grid-versus-export row-count check catches the difference.
Scheduling and monitoring
Scheduled daily runs with a duplicate-send guard, timestamped run logs per month, progress files that let a half-finished run resume where it stopped, failed-term retry files, and per-source circuit breakers so one dead dependency does not take the whole pipeline with it.
QA before delivery
Why it matters over time. On the judgment pipeline every month runs 10 named checks before anything uploads: every record has its full party list, every name got looked up, every match row has an address. A month that fails its checks is not delivered. It is fixed.
What lands in the sheetSample, invented rows

The shape of a delivered file, with placeholder values. Real columns depend on what the portal exposes. The field list comes with the pilot, before you commit to anything.

Sample delivered file structure with invented placeholder values. No real records are shown.
recording_dateinstrument_noparty_nameamountphoneline_typeaddr_match
2026-03-04A-0000001SAMPLE, ALEX Q$184,000555-0100mobileYes
2026-03-04A-0000002EXAMPLE, BRETT$96,500555-0101landlineNo
2026-03-05A-0000003PLACEHOLDER, C$241,750n/an/an/a
2026-03-05A-0000004TESTCASE, DANA$133,200555-0103mobileYes

Every value above is made up. We do not put real records in marketing material, and we will not put yours in ours either.

One free pilot. Then pricing starts at $1,500.

The price depends on how often you need the data, how complex it is to get, how many portals are included, and how much support you will need. You should not have to book a call to find out where pricing starts.

Free pilot

Free
if selected

One portal, one record type, covering the most recent 7 days of records. We reply within 24 hours. If we select you, the sheet arrives within 7 days. Pilots go to businesses we want to work with, based on the data you need and your business needs. No call, no contract, you keep the data either way.

  • The sheet, and the field list
  • A one-page note on what the portal does and does not expose
  • What it would cost to run daily
  • One pilot per company

Ongoing feed

Starting at $1,500
scoped to your portals

Portals built and run on a schedule, with maintenance included, so a portal change gets fixed instead of silently breaking your data.

Price is based on
  • How often you need the data
  • How complex it is to get
  • How many portals are included
  • How much support you will need
  • Scheduled runs, delivered to Sheets, CSV, API or your CRM
  • Validation gate before delivery
  • Fixes when a portal changes

Skip tracing and phone validation can be added to any feed and are quoted with it.

The questions worth asking first.

Including the ones most vendors would rather you asked after signing.

Can you do my county?

Send the link. We will look at what it is built on and reply within 24 hours with whether it is doable: yes and it is straightforward, yes but it is hard, or no and why. It costs nothing to ask.

Most county portals run on one of a handful of vendor platforms, and we have already built against Tyler Odyssey and SmartSearch, AcclaimWeb, LandmarkWeb, Fidlar Ava, BenchmarkWeb, CaseLook, CountySuite, CTrack, OSCN, CaseNet, MiCOURT and more. If yours is one of those, a build usually takes days. Our judgment and case-search work alone spans 27 states and DC.

Is this legal?

The records are public records from public portals. You are paying for collection and delivery, not for access to anything restricted.

We rate-limit politely and we do not create fake accounts. We do not break into anything that is meant to restrict access. Some public portals put a captcha or a bot check in front of public records, and getting past those is part of the build. Each portal has its own terms. If one forbids automated collection, we tell you that instead of quietly doing it, and we price a manual or licensed alternative.

What can the contact data be used for?

Your own marketing and business-development outreach. That is the line, and it goes in writing in every proposal.

It cannot be used for credit, insurance, employment, tenant-screening or any other FCRA-regulated decision. We are not a consumer reporting agency and this is not a consumer report. We do not collect motor-vehicle records, which is where the DPPA applies.

On phones: we deliver numbers with line type and an activity score so you can drop the dead ones. Checking numbers against the national and state do-not-call lists, honoring revocations, and consent for any automated dialing stay on your side. That is TCPA, and it is your call to make, not ours.

What types of documents and records can you collect?

UCC filings, probate, mortgage, divorce, foreclosure and judgment records, among others. It comes down to two things: whether a portal for that record type exists, and whether the data you want is actually published there.

We have built against judgments, probate, recorded mortgages and divorce (domestic-relations) cases. UCC and foreclosure portals we would scope as new work and tell you so before you commit. If a portal does not publish it, we cannot collect it.

Will you work with everyone?

No, and we may not work together. We are looking to work with specific businesses: ones that already know which counties and record types they need and would put a daily feed to work.

Free pilots go to the businesses we select, based on the data you need and your business needs. If we are not the right fit, we will tell you so instead of taking on work we would not do well.

Who owns the data?

You do. The output is yours, including from a free pilot, whether or not we work together afterward.

If we stop working together, you keep every record we have already delivered.

What happens when the portal changes?

It will. Keeping a feed working through those changes is what maintenance covers, and it is the real reason in-house setups fail. The scrape is not the hard part. The hard part is noticing when it quietly stops being complete.

Every delivery goes through a validation step that runs named checks and blocks a month that fails them. A broken month arrives as a fix, not as a clean-looking file missing half its records.

What can't you do?

If the data is not in the portal, we cannot collect it. We only extract what a portal actually publishes. A court judgment search shows the case number, the parties, the filing date and the amount. It will not show the debtor's bank balance. We cannot collect it, and no skip trace will find it either. A phone number is different: the court does not publish it, but a skip trace can often find it from other sources.

No OCR. If the documents you need are scanned images rather than text, that is not a capability we have built, and we will say so before you pay for it.

No guaranteed uptime and no claim that any specific portal is live today without a fresh run. For record types we have not built against yet, such as UCC and foreclosure portals, the first build is new work and we say so up front.

No data on anyone for a decision about their credit, housing, insurance or job. If that is the use case, we are the wrong vendor and we will say so in our first reply.

How fast?

A pilot county within 7 days of being selected. We say that only because single-county runs genuinely are that size. A single run of one recorder portal in this portfolio produced between 7,688 and 33,696 raw rows, and that is a day or two of work.

A full build with history backfilled is longer, and the portal decides how much longer. A JSON API is hours. A captcha-gated WebForms site with result caps is days.

Tell us the county that wastes the most of your week.

We reply within 24 hours. If we are a fit, we’ll pull the most recent 7 days of records from it and send you the sheet, free, within 7 days, based on the data you need and your business needs. No call, no contract. If it is useful we talk. If it is not, you keep the data.

You will be writing to
The June Labs team
June Labs LLC | Data Collection & Automation Services
Tell us what you need

You get the people who wrote the code, with nobody between you and a fix.

June Labs LLC.
Data collection & automation services

Data is supplied for marketing and business-development outreach only. It may not be used for credit, insurance, employment, tenant-screening or any other FCRA-regulated decision.

Privacy, terms and cookies