2026-09-01
What we record about every API call, and what we refuse to
The transaction ledger only knows about calls that moved money. That's fine for accounting and useless for the question a developer actually has after wiring up a key, which is "is my agent calling this at all, and is it working". So every request to the API now writes one row after the response has gone out, and I want to be specific about what's in it, because the choice of what to leave out was the interesting part.
What's in a row
The endpoint, with identifiers collapsed so /api/jobs/5b2f.../release groups with every other release. The method. Which organization and which key made the call, when it authenticated. The HTTP status. How long it took. The first 200 characters of the user agent, enough to tell the SDK from curl from a Python client. That's it.
You can see your own on the usage page, by day, by endpoint, by key, with the last fifty calls listed. I see the same thing across every organization on the admin side, plus which client libraries people are actually using.
What's deliberately missing
No request bodies. A body might contain a memo, a job description, a merchant name, and none of that belongs in a log that exists to answer "is it working". If we need to debug a specific payload we can reproduce it, we don't need to have stored yours.
No IP addresses. There's no question about API health that an IP answers.
Nothing that failed authentication gets attributed to anyone. If someone pastes a key wrong, the 401s are counted against the endpoint so we can see a burst of them, but they aren't tied to an org, because we don't actually know whose they are and guessing would be worse than not knowing.
The web side is stricter again
Page views on the site go through the same thinking. There's no cookie and no third-party script, just a small beacon on each route change to our own endpoint. The visitor identity is a hash of a salt, the date, the IP and the user agent, which means it counts a person once per day and is meaningless tomorrow. The IP goes into the hash and is thrown away. Referrers are stored as the host only, so news.ycombinator.com, never the full URL with whatever was in its query string.
I can tell you how many people came from Hacker News on Tuesday and which page they landed on. I cannot tell you who they were, and I've built it so that I can't be asked to.
Why bother saying any of this
Because the first time the usage log did its job, it did it against me. I ran a smoke test from a fresh project, filtered workers by skill, and got a 500. Before I'd finished reading the SDK output the admin page already showed three server errors against that route with the key and the timestamp. The fix took ten minutes and the log is why. That's the whole case for recording what an API does... and the fact that it can do that job without knowing anything about a person is the whole case for recording nothing else.