DEV Community

0xGollum
0xGollum

Posted on

I added a new feature to a live paid actor — the data was already there, I just wasn't reading it

Horse Racing Pulse has been running for a few weeks now, tracking live PMU odds and flagging steamers/drifters as money moves the market. It found a real paying user early on, which made me nervous about touching it — the classic "don't fix what isn't broken" problem.

But a user having a working tool doesn't mean the tool can't get more useful without breaking what already works. Here's what I did.

The realization

The actor calls one PMU endpoint per race to get live odds. I was only reading a handful of fields off each participant: name, number, jockey, odds. Out of curiosity I dumped the full raw response for one horse, and it turned out I'd been ignoring most of the payload the whole time — career starts, wins, places, this-year vs last-year earnings, whether the jockey changed for today's race, whether this is the horse's debut. All of it was already coming back on every single call I was already making. Zero extra requests.

Turning raw fields into something worth reading

Raw numbers aren't a feature. "12 starts, 0 wins" only means something if 12 is enough starts for that to be a real pattern and not noise. I picked a minimum sample size (10+ starts) before flagging a winless streak, and a minimum swing (50%+) before flagging a year-over-year earnings change, specifically to keep the signal-to-noise ratio honest.

The bug that would have shipped wrong

While testing against live races, the earnings numbers looked absurd — a modest PMU trotter apparently earning several million euros a year. Turns out PMU returns these amounts in centimes, not euros. A silent off-by-100 that would have made every earnings message wrong, caught only because I ran it against real live data instead of trusting the field name.

Lesson I keep re-learning: field names lie, or at least don't tell you the unit. Test against production data before you ship.

Not touching what works

The new patterns live behind one boolean input, off by default. The existing paying user sees zero change unless they opt in. Old tests still pass unmodified — I added new ones for the new behavior, didn't touch the old ones.

If you're sitting on a scraper or API integration that's "done," it might be worth checking what you're actually parsing out of the response versus what's available in it. Sometimes the next feature isn't a new source — it's a field you never read.

Actor: apify.com/0xgollum/horse-racing-pulse

Top comments (0)