Skip to content

$ cat ~/blog/coding-for-the-cats.md

2026-06-25  · 4 min read ·  #wordpress #open-source #side-project #cats

Coding for the cats

I built a free WordPress plugin so CJ Paws' adoptable cats show up beautifully on any website — no API key, no server, no permission required. The web keeps locking its doors; this one walks through the front.

Most of what I build is for the people who produce the legal record. This one’s for cats.

It’s a little WordPress plugin called Purrfect Match, and it does one thing: it puts a rescue’s adoptable pets on their own website, in their own look — a clean, filterable grid instead of a gray box that belongs to someone else. I built it for CJ Paws, the cat rescue here in St. Pete. That’s Sushi up in the header, supervising. She supervised the build too, which mostly meant sitting on the keyboard.

The problem nobody asks you to solve

Every shelter wants their animals on their own site. Not a third-party widget bolted to the corner — their page, their colors, the cats front and center. The official way to do that is the Petfinder API: register an app, request a key, build against it.

Here’s the thing about API keys in 2026. An API is a promise, and the last few years have been a slow lesson in how easily promises get revoked. Reddit, Twitter, a dozen quieter ones — doors that were open to anyone who could write a little code, now locked, metered, or gone. Build your shelter’s adoption page on top of someone’s API and you’re one pricing email away from a blank page. For a volunteer-run rescue, “the cats stopped showing up and nobody knows why” is not a great Tuesday.

So I didn’t ask for a key.

What it actually does

If you’re not technical, here’s the whole story: Petfinder already publishes a small embeddable widget — the little scroller of a shelter’s pets you’ve seen on rescue sites. That data is already public. My plugin asks for that same public data, then draws it the way CJ Paws would want it drawn — their pink, a real grid, instant filters for breed, size, and age. Drop one line on a page and you’re done:

[purrfect_match organization="FL1629" brand="#e93396"]

FL1629 is CJ Paws’ Petfinder ID. #e93396 is their pink. That’s the entire setup.

The trick, for the folks who want it

For the engineers: the plugin reproduces Petfinder’s own public pet-scroller data layer, but client-side. When a visitor opens the page, their browser — not my server — calls Petfinder’s public widget endpoint: a GetOrganization query resolves the display ID to an org UUID, then SearchAnimal returns the adoptable animals. The browser sends Content-Type: application/json, which satisfies the endpoint’s CSRF check — the exact handshake the official embed relies on. And because the request comes from a real browser instead of a script on a server, it never trips the bot protection that blocks server-side calls. That’s the whole reason it lives in the browser.

The payoff: no API key to request, and nothing to schedule, cache, or have switched off. No secret sits on the server because there’s no secret. If Petfinder’s public widget works, this works — there’s no second system to fail.

I kept it honest about its limits, too. The filters run in the browser on whatever the public query returns — breed, size, age. Gender is a valid Petfinder filter input, but it isn’t returned per animal, so I left the gender filter out rather than ship one that quietly lies. Same rule I hold AI to: if it isn’t in the data, don’t pretend. Apparently I apply it to cats now.

Why CJ Paws gets the Saturday

CJ Paws is a volunteer-driven, donation-supported, 501(c)(3) cat rescue in St. Petersburg. It’s foster-based — the cats live in real homes, not cages — and it got started because of one resilient kitten named Zoe. They describe themselves as running on “purrs, passion, and a whole lot of love,” and after watching them work, that’s not marketing.

What I like most is that the adoption process is unapologetically human. You apply, you meet the cat in its foster’s living room, someone does a quick home visit, and then — this is the part that tells you everything — they stay in touch. These are people who want the match to actually stick. Plugin’s named after the good version of that.

Coding for the cats

This isn’t a product. There’s no roadmap, no pricing, no growth plan. It’s GPL and free, it ships with generic defaults so any rescue can drop in their own Petfinder ID, and the code is on GitHub. The entire reward is a cat getting seen by someone who’s idly scrolling — and then not being on the page next week, because they got adopted.

I open-source the unglamorous plumbing in my legal-tech work for the same reason I spent a Saturday on this: some things just shouldn’t require anyone’s permission. A 45-year-old firm shouldn’t have to beg a vendor to open its own recordings, and a cat rescue shouldn’t have to beg an API for the right to show its own cats. Obiwan would’ve supervised this one from the windowsill — the way he still does, in memory.

If you’re in Tampa Bay with a lap going spare, the cats are right here: cjpaws.org/adopt. If you run a rescue and want the plugin, it’s yours.

What’s the one good thing you’d build in a weekend if nobody had to say yes first?

Andrew Mayes — AI engineer & legal tech leader in St. Pete, FL. Writes between deploys. Supervised by Sushi, with Obiwan forever in memory. → more posts