Case Study

CourtList.com.au

Custom Objects · HubSpot CMS · HubSpot CRM · Serverless Functions
Contents

CourtList answers a deceptively hard question: what’s on the public record about a court case in Australia? The information is public, but it’s scattered across jurisdictions, formats, and feeds — useless until someone consolidates it into one searchable place. I built that place, and built the entire thing on HubSpot.

The brief

Build a searchable, consolidated database of publicly available information about court cases across Australia — ingesting messy data from multiple sources, normalising it, relating cases to the people and entities involved, and putting a fast public search application on top. The constraint that shaped every decision: do it 100% on HubSpot — CRM, CMS, custom objects, serverless functions, workflows — no separate application server, no bolt-on database.

One platform, end to end

Most teams would reach for a standalone app and a SQL database here. I didn’t. The CRM is the datastore, custom objects are the schema, the CMS is the front end, serverless functions are the API layer, and workflows are the processing pipeline. Keeping it all in one platform means one source of truth, one security model, and no integration glue to maintain between a database and an app that drift apart over time.

The data model: custom objects and associations

Court records aren’t flat. A case relates to courts, parties, listings, and dates — so I modelled it that way with HubSpot custom objects and associations. Each entity is its own object; associations wire them together so a single case carries its full context, and one party can be followed across every case they appear in. Getting the association model right is what turns a pile of imported rows into something you can actually query and navigate.

The hard part was never the search box. It was making thousands of inconsistent public records relate to each other correctly, automatically, as they land.

Ingest, transform, associate — with workflows

Public court data arrives inconsistent: different jurisdictions, different shapes, duplicate and partial records. As data is imported, HubSpot workflows and custom-coded workflow actions transform it on the way in — normalising fields, deduping, deriving values, and creating the right associations between cases, parties, and courts so each record is correctly linked the moment it exists. The custom-coded actions handle the logic that branching workflow steps can’t express, all running inside HubSpot rather than in some external ETL job nobody can see.

Serverless functions as the API layer

The application talks to the data through HubSpot serverless functions. They route incoming data to the right objects on import, and on the front end they handle the search queries — taking a user’s search, querying the consolidated object database server-side, and returning only what’s needed. The function does the work close to the data instead of shipping records to the browser, which is what keeps a search across a large, consolidated dataset fast.

The search application

On top of that stack sits the public product: a search application on HubSpot CMS that lets anyone query the consolidated database of Australian court case information. Search, retrieve, drill into a case and its associated parties and courts — a real application experience, served entirely from HubSpot, with the CMS handling the pages and the serverless layer handling the data.

Why it worked

No separate app server, no external database, no integration layer to rot. HubSpot custom objects for the schema, associations for the relationships, workflows and custom-coded actions for the transform-on-import pipeline, serverless functions for routing and search, and the CMS for the application itself. One platform, one senior developer owning the whole stack — which is why a problem most people solve with a full custom application got solved on HubSpot instead.

← Back to all work