An HTTP status code sets the scene. It says a request failed and roughly which family of failure occurred, and clients can branch on that alone: refresh a token on 403, retry on 500, back off on 429 (Speakeasy's error design guide). That is enough for a hand-written client whose author reads the docs once. It is not enough for an agent that meets your tool for the first time and has to decide, in one step, whether to call again, change the request, or hand the problem to a person.
The difference is that a human reads the surrounding context (the ticket, the logs, the docs tab that is already open). An agent reads only what the tool returns, plus whatever schema it was given. If you return 500 with a stack trace, the agent can see that something broke and nothing about what to do next. If you return 429 with no timing, the agent guesses a sleep interval and either hammers you or gives up too early.
RFC 9457 (Problem Details for HTTP APIs) gives a standard envelope: type, title, status, detail and instance, plus extension members for validation details (Zuplo's API error handling guide). It is a good base, and you should adopt it rather than inventing a fifth ad-hoc shape. But five fields chosen for human troubleshooting do not tell a program which action to take. That is the gap the hint fills.
A concrete measure of the cost: in a 2026 study of 33,596 pull requests opened by coding agents, failing CI or tests was the most common code-level reason for rejection, at 17.6% of rejected PRs analyzed (SpecStory's definition of done guide). Some of that waste is agents retrying things that could not succeed, or escalating things they could have fixed.



