Designing APIs for Agents: Why Defaults Are Bad and Errors Are Good

I used to design APIs for humans, prioritizing simplicity and defaults. Now, with agents consuming most code, I believe in explicitness over convenience. Agents can read entire documentation instantly, so we must provide precise definitions, avoid hidden logic, and treat errors as opportunities for clarity rather than obstacles to smooth onboarding.
Errors are one of the best surfaces an agent has for finding the happy path, but only if they're precise.
- simonw
I heard a neat tip recently about API design for agents: give them a way to send you feedback.
The example I heard was an MCP with a "feedback" tool which had a tool description saying that coding agents should call that any time they had trouble figuring out how to use the rest of the MCP.
I really like this. It's super cheap to implement and I expect you'd get a bunch of actionable signal in amongst the noise.
- ventana
I don't like the idea of making APIs effectively unusable for a human developer. We might not write a lot of code anymore, but getting rid of defaults and asking agents to pass all possible values explicitly makes it impossible to quickly debug the API call (e.g. with curl or something).
It's similar to HTTP/1: there are a lot of headers in the protocol, but you can still use nc or openssl s_client and type the request manually; you probably only need Host: and Content-Type:, maybe Content-Length:, and it will work. I don't normally write HTTP requests in the terminal, but I know I can do it if I need. It's better to keep it this way, I think.
Same with APIs.
- _pdp_
I had to deal with exactly this issue with one of my recent oss projects so I can share a few things on the topic.
1. Text is the default interface
i.e. the api must be text based first but it should allow to fallback to structured output by using the accept header.
That being said, it is not wrong to introduce other means to return json by using ?format=json etc.
2. Make it grepable
Basically surface as much useful information in a single line so that the agent can grep and slice.
3. Identifiers must be short
i.e. short enough to describe in 5 tokens but not too short to introduce collisions or confusion.
Otherwise you could be wasting a lot of token for nothing. However, adding prefixes helps like cus_abc123, token_xxx, etc. The prefix can help with lookup, error correction and deduplication.
4. Surface information that is likely to be used by the agent
i.e. if the agent is asking for a list of resources, don't just return the list but also some additional information that might help the agent understand better the context around the resource.
Without this a single task could take a lot more steps simply because the agent needs to run its own loop - it is slow and expensive.
5. Add bulk operations
It is a lot easier to insert 10 records in one request then performing 10 separate requests.
6. Error messages should be descriptive
Ensure that error message point to actual docs and manuals that can be read by the agent so that it can troubleshoot on its own. Also return hints. […]
- hankbond
Re: default values are bad
One of my recent projects has contributable code (via extensions) with a central settings management (json file). What I do is take all the defaults contributed by the extensions (namespaced by extension name) and materialize them to the settings file as the initial values to each setting. When an agent wants to edit the settings, it already knows the entirety of the setting surface area and thier values. It never has to go digging to find default values nested somewhere in the extension code or documentation. Also, the code that reads the extensions into the framework (for runtime execution) only reads the materialized values, it doesn't have a concept of a default value past the point of materialization. Defaults only exist in the extension registration/mounting part of the lifecycle (so they can materialize if missing from the settings file).
One upside of this is as new settings are created (from new features being developed) your configuration gets notified via the new fields being materialized into your settings upon startup.
AFAIK this is not at all a new practice. I used to see TOML files with default values in commented out lines all the time.
The downside is that the agent is not aware of which settings are being overridden from the default (like a sparse settings file would provide), but I don't know how much semantic value that offers in most cases (other than maybe debugging?).
I'm not even taking a side on this one this is just a […]
- cheekygeeky
Suggestion:
Save the article as an .md file.
Upload it to Fable 5 with the prompt: "Agree or disagree. Be verbose."
I learned a lot: Where he's right. Where he's wrong. A 'delicious bug in his own example" code (command injection vulnerability - in the code sample used to demonstrate why you don't need sandbox.git.clone). I also learned that, according to Fable 5: "A Typescript SDK is the strongest anti-hallucination device we currently have." And a lot more.