</>Oriol Martí
← Blog

Backend in the age of AI agents

· 5 min read

For years we’ve designed backends with two kinds of client in mind: a frontend we control and, sometimes, an outside developer who reads the docs carefully, writes an integration and leaves it running for months.

A third kind of client is showing up that looks like neither: an AI agent that discovers your API on the fly, decides what to call based on a goal, and does it on behalf of a person who isn’t watching.

Thesis

My thesis is simple: if a growing share of your users arrive through agents, your API stops being an implementation detail and becomes your product. The interface that matters is no longer the screen, it’s the contract.

That doesn’t mean rewriting anything. It means many things that were always “good practice” become requirements. And some assumptions, like there being a human on the other side reading the error messages, stop being true.

APIs designed for machines that reason

An agent isn’t a script. A script always does the same thing; an agent interprets. It reads an endpoint’s description, decides whether it fits and builds the call. That changes what makes an API good.

Documentation is part of the interface

For an agent, the description of an endpoint and its parameters is literally what it uses to decide what to do. An ambiguous name or an unexplained parameter isn’t an annoyance: it’s a wrong call.

What used to be documentation for humans becomes an executable contract: precise schemas, descriptions that say what each operation is for and when not to use it, and real examples.

Errors have to teach

A bare 400 Bad Request is useless to an agent. An error that says which field is wrong, why, and which values are valid lets it fix itself on the next attempt without help.

  Bad:   400 { "error": "invalid request" }

  Good:  400 { "error": "invalid_date_range",
               "message": "'to' must be after 'from'",
               "field": "to",
               "hint": "Maximum range: 90 days" }

This was always good practice. With agents, it’s the difference between a task that gets done and one that’s abandoned after ten wasted calls.

Operations with intent, not just CRUD

An agent that has to chain five generic calls to “book an appointment” gets five chances to get it wrong. An operation that expresses the whole intent, with its validation built in, cuts errors and makes it easier to understand what happened.

I’m not arguing for dropping resource APIs, but for adding a layer of business operations for the things an agent will actually want to do.

Idempotency and confirmation

Agents retry, sometimes without anyone explicitly deciding to. Any operation that changes something should accept an idempotency key, so repeating it doesn’t duplicate an order or a payment.

And for anything irreversible, a two-step pattern makes sense: the agent proposes the action, the system returns what’s going to happen, and execution needs an explicit confirmation, ideally from the person.

Limits, cost and abuse

A human clicks a few times a minute. An agent can make hundreds of calls to solve a single task, especially when it gets something wrong and tries again.

That changes how I think about limits:

Before With agents
Limit per IP or per user Limit per agent and per person it acts for
Requests per minute Requests and cost per task (not every call weighs the same)
Block abuse Tell abuse apart from a clumsy agent retrying in a loop
Generic 429s 429 with Retry-After and a reason, so the agent waits instead of insisting

Authentication changes too. An agent shouldn’t use a person’s full credentials, but delegated, scoped, revocable permissions: it can read the calendar but not delete events; it can prepare an order but not pay for it. Fine-grained OAuth scopes, which many APIs already have, become the norm rather than the exception.

And there’s a new risk classic clients didn’t have: the agent can be manipulated by the content it reads. If your API returns text that comes from other users, that text may contain instructions aimed at the agent. The backend can’t solve that alone, but it can limit the damage: least privilege, confirmation for anything irreversible, and no dangerous actions by default.

Observability when the client isn’t human

Today, when something breaks, you can usually reconstruct what the user did: a session, some clicks, a reasonable sequence. With an agent, the sequence can be long, odd and perfectly valid all at once.

What I think is essential:

  • Identify the agent and the person on every request, separately. Knowing it was “assistant X acting for user Y” is the foundation for everything else.
  • Group calls by task. An identifier the agent carries across every call for the same goal turns a hundred loose requests into a story you can read.
  • Measure success per task, not per request. 99% of requests returning 200 means nothing if half the tasks are abandoned halfway.
  • Watch for repeated errors. If many agents fail the same way on the same endpoint, the problem probably isn’t the agents, it’s your contract.
  task "book appointment" (task_id=abc)
   ├─ GET  /availability        200
   ├─ POST /bookings            400 invalid_date_range   ◀─ contract problem?
   ├─ POST /bookings            200  (idempotency-key=k1)
   └─ POST /bookings/confirm    200

What I’d do today

I don’t think you need to wait for this to go mainstream to get ready. Almost everything here makes the API better for humans too:

  1. Review the errors on your most-used endpoints so they say what’s wrong and how to fix it.
  2. Complete your API schemas and descriptions as if they were code, because they are.
  3. Add idempotency keys to every operation that creates or changes something.
  4. Split permissions into small scopes, designing for delegated credentials from the start.
  5. Add client and task identifiers to your logs, even if at first only your own frontend uses them.
  6. Design a couple of business operations for the most common flows, instead of forcing CRUD chains.

None of this is new. What’s new is that it stops being optional. For years, a poorly documented API with confusing errors was compensated for by a patient human on the other side. That human will be around less and less, and the quality of the contract will become the quality of the product.