One of my AI agents writes short daily notes about player price changes for my fantasy football side project. Price changes are the kind of thing people check, so the numbers have to be right. If a post says a player rose overnight and he didn’t, someone notices fast.
The game has an official public API, and it already has a field that looks like it answers the question. My agent stopped trusting that field on its own. On 15 October the two answers disagreed completely.
The field that looks like “overnight” but isn’t
Every player in the API’s main JSON comes with a current price, now_cost, and a field called cost_change_event. It’s very tempting to read that second one as “price change since yesterday”. It isn’t. It’s the change since the current gameweek started, so a player who went up three days ago still shows +1 today.
The morning of 15 October made the difference obvious. Here’s what each method said:
- Players with a positive
cost_change_event: 13. - Players whose price actually went up since the previous morning: zero.
- Players whose price went down since the previous morning: five.
A note built from the field would have announced a batch of risers. The real overnight story was no risers at all and five fallers. Same API, same morning, opposite headline.
Keep yesterday’s file, then diff it
The fix is boring, which is why I like it. Every morning the agent saves the full API response to a dated file before it writes anything. The file name carries the date and the time it was fetched, so there’s never a question about which copy is which. The archive runs back to 5 October now, with a few extra midday and evening pulls on busier days.
“Overnight” then means one thing only: today’s now_cost minus the previous morning’s now_cost, player by player. A simplified version of the diff:
# Simplified. Compare two saved snapshots of the same public API.
import json
old = json.load(open("snapshots/bootstrap-2026-10-14-0915.json"))
new = json.load(open("snapshots/bootstrap-2026-10-15-0922.json"))
before = {p["id"]: p for p in old["elements"]}
risers, fallers = [], []
for p in new["elements"]:
prev = before.get(p["id"])
if not prev:
continue
delta = p["now_cost"] - prev["now_cost"]
if delta > 0:
risers.append((p["web_name"], prev["now_cost"], p["now_cost"]))
elif delta < 0:
fallers.append((p["web_name"], prev["now_cost"], p["now_cost"]))
print(len(risers), "risers,", len(fallers), "fallers")
Prices in that API are stored in tenths, so 54 means 5.4. That’s one more reason to do the maths in a script and not let a model eyeball it.
A facts file comes before any words
The agent doesn’t write a note straight from the API. It writes a plain-text facts file first. The first line says where the data came from and when it was fetched, in my time zone. The price section says exactly which two snapshot files it diffed. Only after that does it draft anything people will read, and every one-liner it suggests has to be traceable to a line in that facts file.
It also renders the day’s price card from a small script, and the top of that script records what it was built from. On 15 October that comment says 0 risers and 5 fallers, and lists the five names. If the card and the facts file ever disagree, one of them is wrong, and I can see which.
Where it nearly slipped anyway
This setup isn’t perfect, and the files show it. A quick midday check that same day listed some players as “event risers”. That’s the gameweek field again, accurate but easy to misread. Put that phrase into a post and it becomes “rose today” without anyone deciding it should.
So the evening facts file now defines its terms at the top. “GW price change” is spelled out as the change since the gameweek started, and it’s kept apart from the overnight diff. Two numbers, two names, no guessing which one a sentence is quoting.
Why this is an AI problem, not just a data problem
A person reading the API docs once would probably learn the difference and remember it. A language model reads a field name, decides what it most likely means, and writes a confident sentence. cost_change_event sounds like “what changed”, and that guess is wrong often enough to matter.
What works for me is giving the agent a job it can’t fudge. Fetch, save, diff, write the facts down, then write. The model is good at turning a facts file into a readable note. It shouldn’t be the thing deciding what the facts are. The snapshot archive costs nothing to keep on the always-on machine my agents run on, and it means I can answer “are you sure?” with two files and one script.
Ship checklist
- Read the API docs for any field you’re about to quote, and write down what its time window really is.
- Save the raw response to a dated, timestamped file before writing anything.
- Define “overnight” (or “today”, or “this week”) as a diff between two named snapshots.
- Do the maths in a script, including unit conversions like prices stored in tenths.
- Write a facts file first, with the source and fetch time on line one.
- Name the exact snapshot files a diff came from inside the facts file.
- Only let the agent draft from the facts file, never straight from the live API.
- Give similar-looking numbers different names, and define them at the top of the file.
- Record what a generated image was built from in its own script or metadata.
- If the built-in field and your diff disagree, publish the diff and say what it measures.
FAQ
Why not just trust the API’s own change field?
It’s correct, it just answers a different question: change since the gameweek started. If what you want to say is “overnight”, you need yesterday’s value, and the only reliable way to have it is to have saved it yourself.
Doesn’t saving the whole response every day get big?
It’s a single JSON file per pull, and plain files on a machine that’s already running anyway. I’d rather keep the full response than a trimmed one, because the next question is often about a field I didn’t think to keep.
Why a plain-text facts file and not a database?
Because I read it. A facts file with the source, the fetch time and the diff in plain sentences is easy to check by eye, easy for the agent to quote from, and easy to keep next to the snapshots it came from.
Where did the AI actually help?
It runs the routine every morning without me, turns a long facts file into short notes people want to read, and keeps the card and the facts in step. Where it doesn’t help is deciding what a field means. That part is now written down, so it doesn’t have to guess.
Closest related Builders notes?
My AI Agent Waited Three Days for One Real Alert Email is the same habit of only trusting real observations. My AI Agent Read the Terms Before Building a 24/7 Monitor is about checking what you’re allowed to fetch before you fetch it, and I Gave My AI Agents One Shared Changelog With a Rollback Line is how my agents keep a written record of what they did.
