Public data is technically available, but rarely accessible in a developer-friendly way.
This is the story of how I turned a public but closed system into something usable—and how I built Courtbase to save lawyers time daily.
The Problem
Lawyers rely heavily on government court systems to track case hearing dates and updates. While there's an official mobile app, it doesn't expose any public APIs.
On the web, case data is available—but only behind CAPTCHAs.
At first, I thought this was a dead end. But then I noticed something interesting.
Mobile App Had No CAPTCHA
I opened the mobile app and realized that there was no CAPTCHA at all.
This suggested something important:
For backward compatibility, they were likely forced to keep an unprotected flow working for mobile traffic.
As I write this today, it's still unfixed.
Intercepting Mobile App Traffic
To dig deeper, I used a proxy tool to intercept the mobile app's traffic.
The request payloads were encrypted—just a stream of garbled characters. But I wasn't ready to give up.
Reverse Engineering the Mobile App
I decompiled the mobile app using standard Android tools and scanned through the source.
There it was—symmetric encryption with a hardcoded key. No certificate pinning. No fancy obfuscation.
I reverse-engineered the encryption logic and was soon able to replicate requests from my own scripts.
// Simplified version of the approach
const encrypt = (data) => {
const key = "found_in_source"; // Found in the decompiled source
return CryptoJS.AES.encrypt(JSON.stringify(data), key).toString();
};
const makeRequest = async (caseNumber) => {
const payload = encrypt({
caseNumber,
timestamp: Date.now(),
});
const response = await fetch('https://api.example.gov/mobile/case-status', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'User-Agent': 'Mobile App/1.0',
},
body: JSON.stringify({ data: payload }),
});
const encrypted = await response.json();
return decrypt(encrypted.data);
};
Why This Matters More in the AI Era
With AI being capable of generating highly convincing fake documents, digital signatures and verifiable data are more essential than ever.
Having a system that fetches case data directly from official sources—without human entry—builds trust. No tampering. No misreporting.
What I Built
I packaged this into a product for my legal tech project:
- Advocates can search by name or case number
- It auto-updates hearing dates using background jobs
- Built with Next.js + TypeScript + PostgreSQL
One customer saves over an hour daily using this.
The architecture looks like this:
// Background job that runs every morning
export const updateCaseStatuses = createScheduledJob(
{ cron: "0 6 * * *" }, // 6 AM daily
async () => {
const activeCases = await db
.selectFrom('cases')
.where('status', '=', 'active')
.selectAll()
.execute();
for (const case_ of activeCases) {
const latestData = await fetchFromCourtAPI(case_.case_number);
if (latestData.next_hearing !== case_.next_hearing) {
// Send notification to lawyer
await sendNotification(case_.lawyer_id, {
case_number: case_.case_number,
old_date: case_.next_hearing,
new_date: latestData.next_hearing,
});
}
await db
.updateTable('cases')
.set(latestData)
.where('id', '=', case_.id)
.execute();
}
}
);
The Technical Challenges
Rate Limiting: The mobile API wasn't designed for bulk requests. I had to implement smart queuing and backoff.
Data Consistency: Case numbers follow different formats across states. Lots of regex and normalization.
Reliability: Government APIs go down. A lot. I built retry logic and fallback mechanisms.
Legal Compliance: Even though the data is public, I was careful about terms of use and added proper attribution.
What I Learned
Mobile apps are often less secure: They prioritize user experience over security barriers.
Backward compatibility is a gift: Legacy endpoints often have fewer protections.
Public doesn't mean accessible: There's a huge difference between "publicly available" and "developer-friendly."
Small automations have big impact: Saving one hour daily adds up to 250+ hours per year per user.
Final Thoughts
What started as a hunch became a production-grade automation layer on top of public judiciary data.
If the official APIs don't exist—you find your own way in.
The real value isn't in the technical tricks. It's in solving a real problem that people face every day. Lawyers shouldn't have to manually check case updates when computers can do it better.
This project taught me that sometimes the best solutions come from looking at problems sideways. What closed systems are you dealing with that might have an unlocked back door?