Skip to main content

Design Considerations and Profile for HTTP APIs Consumed by AI Agents
draft-gaikwad-agent-friendly-http-api-profile-01

Document Type Active Internet-Draft (individual)
Author Madhava Gaikwad
Last updated 2026-06-29
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-gaikwad-agent-friendly-http-api-profile-01
Network Working Group                                         M. Gaikwad
Internet-Draft                                               Independent
Intended status: Informational                              30 June 2026
Expires: 1 January 2027

 Design Considerations and Profile for HTTP APIs Consumed by AI Agents
            draft-gaikwad-agent-friendly-http-api-profile-01

Abstract

   AI agents are a fast-growing kind of HTTP API client.  A human
   developer reads an API's documentation once and then writes code that
   calls it.  An AI agent works from the machine-readable description
   each time it plans a step.  It works within a limited amount of text
   it can hold at once.  It retries often.  It picks operations by
   matching their descriptions to a goal.  An API built mainly for human
   developers can lead an agent into failures that are easy to avoid,
   such as repeating a write, running out of room for the task, or
   getting stuck on an error it cannot recover from.

   This document lists the properties that make an HTTP API easy for AI
   agents to use, including APIs reached through tool-calling layers
   such as the Model Context Protocol.  It gathers these properties into
   a profile of existing HTTP and API-description mechanisms, with a
   checklist at the end.  It covers the API and its description.  It
   does not define new ways to identify, authenticate, or authorize an
   agent.  That work is happening elsewhere and is referenced here for
   context.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at https://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on 1 January 2027.

Gaikwad                  Expires 1 January 2027                 [Page 1]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

Copyright Notice

   Copyright (c) 2026 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents (https://trustee.ietf.org/
   license-info) in effect on the date of publication of this document.
   Please review these documents carefully, as they describe your rights
   and restrictions with respect to this document.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   3
     1.1.  Two Layers  . . . . . . . . . . . . . . . . . . . . . . .   3
     1.2.  API Styles  . . . . . . . . . . . . . . . . . . . . . . .   3
     1.3.  Scope and Non-Goals . . . . . . . . . . . . . . . . . . .   3
     1.4.  Requirements Language . . . . . . . . . . . . . . . . . .   4
   2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   4
   3.  How an Agent Uses an API  . . . . . . . . . . . . . . . . . .   4
   4.  Prefer Signals the Agent Can Act On . . . . . . . . . . . . .   5
   5.  The API Description Is the Contract . . . . . . . . . . . . .   6
   6.  Be Consistent and Predictable . . . . . . . . . . . . . . . .   7
   7.  The Set of Operations You Expose  . . . . . . . . . . . . . .   7
   8.  Keep Responses Small  . . . . . . . . . . . . . . . . . . . .   8
   9.  Make Errors Recoverable . . . . . . . . . . . . . . . . . . .   9
   10. Make Writes Safe to Repeat, Preview, and Undo . . . . . . . .  10
   11. Signal When to Slow Down  . . . . . . . . . . . . . . . . . .  11
   12. Long-Running Operations . . . . . . . . . . . . . . . . . . .  12
   13. Changing the API Over Time  . . . . . . . . . . . . . . . . .  12
   14. Making the API Easy to Discover . . . . . . . . . . . . . . .  13
   15. Observability . . . . . . . . . . . . . . . . . . . . . . . .  13
   16. How This Relates to Identity and Authorization  . . . . . . .  13
   17. Security Considerations . . . . . . . . . . . . . . . . . . .  14
   18. Agent-Friendly Profile Summary  . . . . . . . . . . . . . . .  15
   19. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  16
   20. References  . . . . . . . . . . . . . . . . . . . . . . . . .  16
     20.1.  Normative References . . . . . . . . . . . . . . . . . .  16
     20.2.  Informative References . . . . . . . . . . . . . . . . .  16
   Appendix A.  Example: MCP Tools for a Project Management
           System  . . . . . . . . . . . . . . . . . . . . . . . . .  17
   Appendix B.  Example: A Weak and a Strong Operation
           Description . . . . . . . . . . . . . . . . . . . . . . .  23
   Appendix C.  Example: A Small Response with Field Selection . . .  23
   Appendix D.  Example: Previewing a Destructive Write  . . . . . .  24
   Appendix E.  Example: Common Description Anti-Patterns  . . . . .  25
   Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . .  26
   Author's Address  . . . . . . . . . . . . . . . . . . . . . . . .  26

Gaikwad                  Expires 1 January 2027                 [Page 2]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

1.  Introduction

   Autonomous software agents built on large language models are
   starting to call HTTP APIs.  Sometimes the agent forms the HTTP
   request itself.  More often it goes through a tool-calling layer that
   presents each API operation as a callable "tool".  The Model Context
   Protocol [MCP] is one common example of such a layer.  Many of its
   servers are generated automatically from an existing API description
   such as an OpenAPI document [OPENAPI].

   One property matters most.  The description of the API, and the data
   the API returns, both become input to the agent's own reasoning.
   Several single points in this document are also ordinary good API
   practice: stable operation names, bounded pages, structured errors,
   idempotency.  This document explains why each one matters more when
   the client is an agent.  It adds the guidance that is specific to
   agents.  It collects the result as a profile that a provider can
   apply and check against.  This document does not assume that an agent
   is reliable or well-behaved.  It treats the agent as a client whose
   behavior is shaped by the shape of the API.

1.1.  Two Layers

   There are two layers to keep separate.  The API layer is the HTTP API
   and its machine-readable description.  The tool layer is the surface
   that a tool-calling protocol or generator builds from that
   description.  This document is about the API layer.  A good API layer
   is the most reusable way to get a good tool layer.  The tool layer is
   increasingly handled by its own protocols.

1.2.  API Styles

   The advice here is written for resource-oriented HTTP APIs, where
   each operation acts on an identified resource.  Most of it also
   applies to query-based APIs such as GraphQL and to remote-procedure-
   call styles such as gRPC.  A few points change.  A query-based API
   lets the client ask for exactly the fields it needs, which handles
   the over-fetching concern in Section 8 on its own.  In return it adds
   query-cost and query-depth concerns that an agent-facing deployment
   SHOULD limit.  A reader using this document with another style should
   map each point to the matching idea in that style.

1.3.  Scope and Non-Goals

   This document is informational.  It lists considerations, gives non-
   normative recommendations, and assembles a profile and a checklist.
   It does not define a protocol or a wire format.  These topics are out
   of scope:

Gaikwad                  Expires 1 January 2027                 [Page 3]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  How an agent proves its identity, authenticates, or is granted
      authority by a user.  That work is active in the IETF, including
      OAuth 2.0 Token Exchange [RFC8693], on-behalf-of authorization for
      agents [I-D.oauth-ai-agents-obo], and wider frameworks
      [I-D.klrc-aiagent-auth].  Section 16 explains the connection.

   *  The internal design of tool-calling protocols, including how those
      protocols define tools, resources, and prompts.

   *  Agent-side topics such as planning, reasoning traces, and model
      evaluation.

1.4.  Requirements Language

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in BCP
   14 [RFC2119] [RFC8174] when, and only when, they appear in all
   capitals, as shown here.  This document is informational.  These
   words give guidance to API authors.  They are not protocol
   requirements.

2.  Terminology

   Agent:  An autonomous software system, usually built on a large
      language model, that picks and calls API operations to reach a
      goal.

   Tool:  An API operation as it is shown to an agent by a tool-calling
      layer.  It has a name, a short description, and an input schema.

   API description:  A machine-readable definition of an API, such as an
      OpenAPI document [OPENAPI], that a tool layer can be built from.

   Context window:  The limited amount of text the agent's model can
      hold and read at one time.  Operation descriptions and response
      bodies use up this space.

   Affordance:  A machine-readable part of a request or response that
      tells the agent what it can or should do, in a form it can act on
      without reading prose.

3.  How an Agent Uses an API

   The advice below follows from a few facts about how an agent uses an
   API.  Stating them shows where the advice applies.

Gaikwad                  Expires 1 January 2027                 [Page 4]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  The description is input.  The agent is shown operation names,
      descriptions, and schemas while it plans and picks a tool.  Their
      wording decides which operation it picks and how it fills in the
      arguments.

   *  Selection is by similarity.  The agent picks an operation because
      its description reads close to the goal.  It does not follow fixed
      logic.  Two operations that read alike cause wrong-operation and
      wrong-argument mistakes.

   *  Space is limited.  Descriptions and responses share one budget of
      text with the task itself.  Large or low-value payloads crowd out
      the task and make later choices worse.

   *  Retries are common.  An agent retries after a timeout or an
      unclear result.  It may also send a request again as its plan
      changes.

   *  Writes are easy to trigger.  An agent can call an operation that
      changes state while it is exploring.  So an unintended or repeated
      write costs more than it would for a human-driven client.

   These facts apply most directly when operation descriptions, schemas,
   error messages, and response bodies reach a language model or a
   model-guided planner.  When something in between filters, checks, or
   shortens the data before the model sees it, the space and selection
   effects shrink but do not disappear.  The retry and side-effect
   effects usually remain.

4.  Prefer Signals the Agent Can Act On

   This is the main idea of the document.  An agent-facing API SHOULD
   give the agent machine-readable signals it can act on.  It SHOULD
   avoid relying on prose that the agent has to read and interpret.  A
   sentence such as "call this carefully" or "try again later" has to be
   understood by the model, and the model follows such sentences
   unevenly.  The same intent stated as a field or a flag can be acted
   on directly.  This swap shows up throughout the profile:

   *  an error carries a retryable flag the agent can read (Section 9);

   *  a response carries links to the operations that are valid next
      steps (Section 8);

   *  a write accepts a dry-run flag that previews its effect
      (Section 10);

   *  a schema lists allowed values as a fixed set (Section 5);

Gaikwad                  Expires 1 January 2027                 [Page 5]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  a high-risk operation carries metadata that says it needs
      confirmation (Section 10).

5.  The API Description Is the Contract

   When an API is reached through a generated tool layer, its machine-
   readable description is the single source the tools are built from.
   Anything missing from the description is missing from the tool.  So
   treat the description as a main deliverable.  Do not treat it as
   documentation written after the code.

   *  Give every operation a stable, meaningful identifier, for example
      the OpenAPI operationId.  Identifiers generated from the URL path
      produce tool names the agent picks badly.

   *  When several operations share a common verb prefix (such as get_,
      list_, create_), the verb does not help the agent distinguish
      between them.  The distinguishing information is the entity or
      resource name.  Leading with the entity groups related operations
      and lets the agent narrow the search space earlier in the
      identifier.  For example, tasks_list, task_create, task_update
      group by entity, while list_tasks, create_task, update_task group
      by verb.  When an API has many operations across many resource
      types, entity-leading identifiers reduce collisions at the start
      of the name.  For operations where the resource name is the
      complete intent (such as a health summary or an audit log), the
      verb may be omitted.  This guidance is about the operationId or
      tool name.  It does not change the HTTP method or URL structure.
      This SHOULD be treated as a consideration based on the size of the
      tool surface.  Empirical testing shows the effect varies by model.

   *  Give each operation a short summary that sets it apart from
      similar ones.  Give it a longer description that says when to use
      it and when not to.  Wording such as "Use this when ..." and "Do
      not use this when ..." works well.  It heads off the wrong-
      operation mistake from Section 3.  Appendix B shows this.

   *  Put the most important information first in the description.  The
      agent may not read all of it.

   *  State side effects in the description.  Do not leave them implied
      by the HTTP method.

   *  Type and describe every parameter and response field.  List
      allowed values as an enumeration, which is a fixed set of
      permitted values.  Set additionalProperties to false on objects,
      or use the equivalent, so the agent cannot add invented
      parameters.  Include a real example.

Gaikwad                  Expires 1 January 2027                 [Page 6]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  Put idempotency support, pagination limits, field-selection or
      verbosity controls, and deprecation status in the description
      itself.  The agent acts on the description.  Guidance kept only in
      human documentation does not reach it.

   *  Keep the description short and free of repeated prose.  Its text
      uses up the agent's space budget.

   *  Avoid common description mistakes that lead to wrong-operation or
      wrong-argument choices.  The most frequent problems include:
      restating the operation name without adding information (for
      example, "Creates a task" for an operation named create_task);
      omitting side effects; omitting "do not use this when" guidance;
      using jargon or internal names the agent has no context for; and
      describing what the operation returns rather than when to use it.
      Appendix E lists these in more detail.

   *  Test the description by running an agent against the API and
      reading where it picks the wrong operation or fills in a bad
      argument.  These wording problems are hard to predict any other
      way.

6.  Be Consistent and Predictable

   An agent learns patterns and reuses them.  Anything inconsistent
   across the API makes it guess wrong.  Keep naming, identifier
   formats, pagination, error shape, and authentication the same across
   the whole API.  For example, a status value that is pending on one
   operation, IN_PROGRESS on another, and done on a third will cause
   errors.  When an operation only works in certain states of a
   resource, document the states and the moves between them.  Then the
   agent can work out which operations are valid without guessing.  Keep
   enumerated values stable.  The agent may have seen and remembered
   them in an earlier call.

7.  The Set of Operations You Expose

   A complete resource-oriented API does not become a good tool surface
   on its own.  Turning every endpoint into its own tool gives the agent
   a surface that is large, low-level, and hard to work through.

   *  Offer composite operations that finish a whole unit of work in one
      call, where the steps behind them are common, safe, and well-
      bounded.  This saves the agent from chaining several calls, where
      each call is a separate reasoning step.  Keep resource meaning
      intact where you can.  Keep authorization, audit, and partial-
      failure behavior visible.

Gaikwad                  Expires 1 January 2027                 [Page 7]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  Curate the operations you expose.  A small set of well-described
      operations serves the agent better than a large set it has to sort
      through.  Empirical measurements suggest that tool-selection
      accuracy degrades sharply as the number of operations grows into
      the hundreds.  Keeping the exposed set small is not just a
      recommendation for clarity.  It is a practical limit on agent
      effectiveness.

   *  Some operations need extra care before an agent should reach them:
      the ones that take opaque binary input, change infrastructure, or
      cause effects that cannot be undone.  Expose these to a general-
      purpose agent only with extra controls, such as a clear schema, a
      preview, narrow authorization, a confirmation step, or human
      approval.  Do not expose deprecated operations at all.

   *  Offer batch operations that do several related actions in one
      call.  A batch operation SHOULD report one result per item, so the
      agent can see which items succeeded and which failed.

   *  When a value can be found by a human-meaningful name, accept that
      name or offer a lookup operation.  Do not force the agent to
      supply an opaque identifier it has no way to get.

8.  Keep Responses Small

   A response uses up the agent's space budget on the turn it arrives,
   and on every later turn it stays in view.  Asking for too much costs
   more each turn.  A response that is too large is also a denial-of-
   service and cost problem (see Section 17).

   *  Return the fields that carry signal.  Drop low-level details the
      agent will not use.  When clients need different amounts of data,
      support field selection or a verbosity setting.  A verbosity
      setting can be as simple as a response_format parameter with
      values such as concise and detailed, where concise returns
      display-friendly fields (name, status, assignee name) and detailed
      adds internal identifiers, timestamps, and linking fields needed
      for chaining into downstream operations.  This is simpler than
      field selection when the agent does not know which fields to ask
      for.  Appendix C shows both mechanisms.

   *  Support conditional requests on reads, for example an entity tag
      (an ETag value) with the matching conditional header.  Then an
      agent that asks for the same data again can be told it has not
      changed.  It does not have to receive and re-read an identical
      payload.

Gaikwad                  Expires 1 January 2027                 [Page 8]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  Set a bounded default page size on collections.  Document how the
      agent can narrow the results before it fetches them.  A large or
      open-ended default makes the agent spend its space budget on low-
      value items, and it can make the agent's next tool choice worse.

   *  Use cursor-based pagination.  A cursor is an opaque token the
      server returns that marks where the next page starts.  Return a
      ready-to-use continuation, either that cursor or a complete
      next_page link, so the agent does not have to compute offsets or
      build URLs.  It does both of those unreliably.

   *  Give collections a stable, documented order.  Results that change
      order between calls confuse the agent.

   *  Make values self-describing when the type alone is unclear.  For
      example, return a money amount together with its currency, not as
      a bare number.  Return a human-readable label next to an
      identifier where you can.

   *  Include links to the operations that are valid next steps on a
      returned resource.  Then the agent can see the available moves and
      does not have to guess them.

9.  Make Errors Recoverable

   An error response is not the end of the story.  It is the input to
   the agent's next decision.  An error that is unstructured or unclear
   leads the agent to retry something that cannot work, or to give up on
   something a retry would have fixed.

   Use a structured, machine-readable error format such as Problem
   Details for HTTP APIs [RFC9457], which is a standard JSON shape for
   errors.  Include a stable error code that is separate from the HTTP
   status code.

   Problem Details lets you add your own fields.  For an agent-facing
   API, say plainly whether a failed call can be retried, using a field.
   Do not leave the agent to read this off the status code.  Report
   every validation problem at once, with the field name for each one.
   A small, consistent set of fields across the API does the job: a
   boolean retryable, an optional retry-delay hint, and a list of field
   errors.  With these the agent can decide to retry, to change the
   request, or to stop, without guessing.  The field names here are only
   examples.  This document does not register them.  That would be the
   job of a later specification (see Section 19).  Here is a retryable
   rate-limit error:

Gaikwad                  Expires 1 January 2027                 [Page 9]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   HTTP/1.1 429 Too Many Requests
   Retry-After: 30
   Content-Type: application/problem+json

   {
     "type": "https://api.example.com/problems/rate-limited",
     "title": "Rate limit exceeded",
     "status": 429,
     "detail": "Request rate exceeded for this credential.",
     "code": "RATE_LIMITED",
     "retryable": true,
     "retry_after": 30
   }

         Figure 1: Error response with an explicit retry indication

   A validation error sets retryable to false and lists the fields that
   were wrong.  That tells the agent to change the request before it
   sends it again:

   HTTP/1.1 422 Unprocessable Content
   Content-Type: application/problem+json

   {
     "type": "https://api.example.com/problems/validation",
     "title": "Invalid request",
     "status": 422,
     "code": "VALIDATION_FAILED",
     "retryable": false,
     "field_errors": [
       { "field": "assignee_email", "code": "INVALID_FORMAT",
         "detail": "Not a valid email address." },
       { "field": "priority", "code": "NOT_IN_ENUM",
         "detail": "Must be one of: low, medium, high." }
     ]
   }

      Figure 2: Validation error that should not be retried unchanged

10.  Make Writes Safe to Repeat, Preview, and Undo

   Agents retry after timeouts, after unclear results, and as their plan
   changes.  So safe writing for agents covers more than one idea.  It
   covers repeating a write safely, previewing it, confirming it,
   cancelling it, and undoing it.  As a rule, prefer writes that can be
   previewed, cancelled, and reversed over writes that take effect at
   once and cannot be undone.

Gaikwad                  Expires 1 January 2027                [Page 10]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  Support a client-supplied idempotency key on operations that have
      side effects.  Idempotency means that sending the same request
      twice has the same effect as sending it once.  With a key, a retry
      that carries the same key returns the first result and does not
      run the operation again.  The Idempotency-Key HTTP header field
      [I-D.httpapi-idem] is one way to do this.  Document the mechanism,
      the length of time a key is honored, and the scope in which a key
      must be unique.  These decide whether a retry is safe.

   *  Tell a settled result apart from a temporary failure in what you
      store for a key.  A settled result is safe to return again.  A
      temporary server error is not, and returning it again as if it
      were final is a known trap.  Reject a request that reuses a key
      with a clearly different body.  Use a conflict status.

   *  For operations with large or irreversible effects, offer a
      preview, or dry-run, mode.  It reports what the operation would do
      without doing it.  In a resource-oriented API a request header
      (for example, X-Dry-Run: true) or a query parameter (for example,
      ?dry_run=true) works well.  The response lists the predicted
      changes.  Appendix D shows this.

   *  Mark high-risk operations with explicit metadata, for example a
      flag that the operation cannot be undone or that it needs
      confirmation.  You can also require a separate confirmation step
      outside the request.  The point is that the signal is machine-
      readable, not buried in warning text.

11.  Signal When to Slow Down

   Agent traffic can come in bursts.  It often lacks the natural pacing
   of a person at a keyboard.  Signal clearly when the client should
   slow down, so a well-behaved agent can hold back on its own.

   *  When you reject or delay a request for rate limiting or a
      temporary outage, include a retry-delay hint such as the Retry-
      After header field.  A client should follow it ahead of its own
      backoff timer.

   *  You MAY measure limits in units that fit agent traffic, not a flat
      request count.  One agent task can turn into many calls and large
      responses.  Counting by response size, or by a cost unit you
      define, can match real load better.  Document the unit so the
      agent can track what it has left.

Gaikwad                  Expires 1 January 2027                [Page 11]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

12.  Long-Running Operations

   An operation that takes more than a few seconds does not fit a single
   blocking request.  The connection may not stay open.  An agent that
   waits for it cannot do anything else in the meantime.

   *  Acknowledge a long-running operation at once with the right HTTP
      status [RFC9110] (often 202 Accepted).  Return an identifier for
      the operation and a link to a status resource the client can
      check.

   *  Have the status resource report a clear state, and on completion
      point to the finished resource.  Include a retry-delay hint and
      say how often to poll.  Allow the client to cancel an operation
      that has not finished.

   *  When the client can receive callbacks, you MAY send a notification
      when the operation finishes, in place of polling.  Authenticate
      the notification, protect it against replay, and give it an
      identifier the receiver can use to drop duplicate deliveries.

   *  When an operation produces output piece by piece, you MAY stream
      the partial output, for example over server-sent events.  Then the
      agent can start acting on early results before the operation
      finishes.

13.  Changing the API Over Time

   The agent's behavior comes from the API description.  So a change to
   the description is a change to the agent's tools.  Manage change
   carefully.

   *  Prefer changes that keep working for existing clients, such as
      adding an optional parameter or a new operation.  Save a new
      version for a change that would break an existing client, such as
      removing a field, changing a type, or making an optional parameter
      required.

   *  Do not change what an operation means while keeping its identifier
      the same.  An agent that learned the operation once will use it
      again and expect the old behavior.

   *  Signal deprecation in machine-readable form, for example the
      Deprecation and Sunset header fields and a link to the
      replacement.  Show it in the API description too.  Release notes
      on their own do not reach the agent.

Gaikwad                  Expires 1 January 2027                [Page 12]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  Detect breaking changes automatically by comparing each new
      version of the API description against the last one.

   *  Choose one way to express versions and use it across the whole
      API.  Mixing several versioning styles makes the API harder for
      the agent and for people to follow.

14.  Making the API Easy to Discover

   An agent does best with one machine-readable, low-noise place to
   learn what the API can do.  A complete API description [OPENAPI] is
   the main artifact for this.  Some providers also publish a short,
   plain-text index of their documentation aimed at models.  The
   llms.txt convention [LLMSTXT] is one community example, and it is not
   a standard.  Generate any such file from the same source as the human
   documentation, so the two do not drift apart.  Keep it focused on
   parameters, the meaning of errors, and authentication.

15.  Observability

   After an agent runs, an operator often needs to work out what it did.
   To let the agent's steps line up with the API's own logs, accept and
   pass along a standard correlation identifier.  The W3C Trace Context
   traceparent header field [W3C-TRACE-CONTEXT] is one such identifier,
   and a generic correlation header is another.  Record it in the API's
   logs next to the identity that acted.  This helps with debugging,
   with working out cost, and with the audit trail in Section 17.

16.  How This Relates to Identity and Authorization

   This document does not say how an agent authenticates to an API, or
   how a user grants it authority.  A single static credential that
   covers the whole API is a poor fit for an agent.  If it leaks, it
   reaches everything.  The direction the field is taking is to issue
   narrow, short-lived credentials that can be revoked, and to record
   delegation openly.  The user the agent acts for is recorded
   separately from the agent.  That keeps actions traceable.

   Authors building for agents should follow the relevant work,
   including OAuth 2.0 Token Exchange [RFC8693], protected resource
   metadata [RFC9728], resource indicators [RFC8707], dynamic client
   registration [RFC7591], on-behalf-of authorization for agents
   [I-D.oauth-ai-agents-obo], and the wider analysis in
   [I-D.klrc-aiagent-auth].

Gaikwad                  Expires 1 January 2027                [Page 13]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

17.  Security Considerations

   Building an API for agents changes its security picture.  The changes
   connect to the points above.

   Injected instructions in text.  The agent treats the text it receives
   as input to its reasoning.  So both operation descriptions and
   response bodies can carry instructions that an attacker planted.
   This is called indirect prompt injection.  Keep trusted control
   fields apart from untrusted content.  Mark natural-language content
   that came from users or third parties as data, not as instruction.
   One way is to put it in its own named field and keep a note of where
   it came from.  Do not put externally supplied text into operation
   descriptions or API documentation unless it is clearly marked as
   untrusted.  Enforce access decisions at the API.  Do not rely on
   instructions in the agent's prompt, because injected text can
   override them.

   Running out of room and money.  An API can return a payload far
   larger than expected, and so can a downstream system that has been
   compromised.  A huge payload can fill the agent's space budget and
   make the task fail.  Where use is billed, it can also run up a large,
   unexpected cost.  People often treat the limits on response size and
   the cursor-based pagination in Section 8 as performance tuning.  For
   an agent they are also a security control.  Enforce them on the
   server.  Do not count on the client to ask for less.

   Unsafe retries.  The idempotency, preview, and undo guidance in
   Section 10 is also a security matter.  Agents retry more than clients
   driven by a person, and an unsafe retry can repeat an effect that
   changes state.  Apply least privilege to operations that have real
   side effects.  Keep an audit log that records who acted and under
   what delegation.  Consider requiring a confirmation step for high-
   risk actions.

   Tool shadowing across providers.  When multiple tool providers share
   the same agent context, a provider can register operations with names
   or descriptions designed to intercept calls meant for another
   provider.  This is a consequence of selection-by-similarity
   (Section 3).  An agent that picks an operation because its
   description reads closest to the goal cannot tell a legitimate match
   from a planted one.  Mitigations include scoping tool namespaces by
   provider, pinning known-good tool sets, and verifying tool
   fingerprints.  This concern is documented in emerging threat
   taxonomies for tool-calling protocols.

Gaikwad                  Expires 1 January 2027                [Page 14]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   Wider reach when access is broad.  The discovery artifacts in
   Section 14 make the API easier for any automated client to read,
   including a hostile one.  They do not replace authorization or rate
   limiting.  Authorization is out of scope here.  Still, broad access
   together with easy discovery widens how much a tricked or compromised
   agent can reach.  Scope access narrowly to the task.  That limits the
   damage an injected instruction can do.

18.  Agent-Friendly Profile Summary

   An HTTP API meant for agents can be called agent-friendly, in the
   sense of this document, when:

   *  operation identifiers are stable and reveal intent;

   *  descriptions say when to use and when not to use each operation,
      and state side effects;

   *  input objects are strictly typed, use fixed value sets, and reject
      unknown properties;

   *  responses are small by default, with field selection or verbosity
      controls;

   *  pagination uses cursors and returns a ready-to-use continuation;

   *  reads support conditional requests, so unchanged data need not be
      sent again;

   *  collections have a stable, documented order;

   *  errors are structured, carry stable codes, and say whether a retry
      is safe;

   *  state-changing operations support idempotency, with a documented
      window and scope;

   *  high-risk writes can be previewed, cancelled, or confirmed, and
      are marked as such;

   *  rate limits, retry delays, and polling advice are machine-
      readable;

   *  deprecation and replacement operations are machine-readable and
      shown in the description;

   *  a correlation identifier is accepted, passed along, and logged;

Gaikwad                  Expires 1 January 2027                [Page 15]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   *  untrusted returned content is kept apart from trusted control
      fields and marked as data.

19.  IANA Considerations

   This document has no IANA actions.  It does not define any protocol
   element, header field, media type, or registry entry.  The field
   names used in the error examples in Section 9 are only examples.  If
   such Problem Details fields are ever standardized, registering them
   would be the job of that later specification.

20.  References

20.1.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, May 2017,
              <https://www.rfc-editor.org/info/rfc8174>.

   [RFC9110]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
              Ed., "HTTP Semantics", STD 97, RFC 9110, June 2022,
              <https://www.rfc-editor.org/info/rfc9110>.

   [RFC9457]  Nottingham, M., Wilde, E., and S. Dalal, "Problem Details
              for HTTP APIs", RFC 9457, July 2023,
              <https://www.rfc-editor.org/info/rfc9457>.

20.2.  Informative References

   [I-D.httpapi-idem]
              IETF HTTP API Working Group, "The Idempotency-Key HTTP
              Header Field", Work in Progress, Internet-Draft, draft-
              ietf-httpapi-idempotency-key-header, 2025,
              <https://datatracker.ietf.org/doc/draft-ietf-httpapi-
              idempotency-key-header/>.

   [I-D.klrc-aiagent-auth]
              Kasselman, P., Lombardo, J., Rosomakho, Y., and B.
              Campbell, "AI Agent Authentication and Authorization",
              Work in Progress, Internet-Draft, draft-klrc-aiagent-auth,
              2026, <https://datatracker.ietf.org/doc/draft-klrc-
              aiagent-auth/>.

Gaikwad                  Expires 1 January 2027                [Page 16]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   [I-D.oauth-ai-agents-obo]
              IETF, "OAuth 2.0 Extension: On-Behalf-Of User
              Authorization for AI Agents", Work in Progress, Internet-
              Draft, draft-oauth-ai-agents-on-behalf-of-user, 2025,
              <https://datatracker.ietf.org/doc/draft-oauth-ai-agents-
              on-behalf-of-user/>.

   [LLMSTXT]  Howard, J., "The /llms.txt file", 2024,
              <https://llmstxt.org/>.

   [MCP]      Model Context Protocol, "Model Context Protocol
              Specification", 2025,
              <https://modelcontextprotocol.io/specification>.

   [OPENAPI]  OpenAPI Initiative, "OpenAPI Specification", 2024,
              <https://spec.openapis.org/oas/latest.html>.

   [RFC7591]  Richer, J., Ed., "OAuth 2.0 Dynamic Client Registration
              Protocol", RFC 7591, July 2015,
              <https://www.rfc-editor.org/info/rfc7591>.

   [RFC8693]  Jones, M., Nadalin, A., Campbell, B., Ed., Bradley, J.,
              and C. Mortimore, "OAuth 2.0 Token Exchange", RFC 8693,
              January 2020, <https://www.rfc-editor.org/info/rfc8693>.

   [RFC8707]  Campbell, B., Bradley, J., and H. Tschofenig, "Resource
              Indicators for OAuth 2.0", RFC 8707, February 2020,
              <https://www.rfc-editor.org/info/rfc8707>.

   [RFC9728]  Jones, M., Hunt, P., and A. Parecki, "OAuth 2.0 Protected
              Resource Metadata", RFC 9728, April 2025,
              <https://www.rfc-editor.org/info/rfc9728>.

   [W3C-TRACE-CONTEXT]
              W3C, "Trace Context", 2021,
              <https://www.w3.org/TR/trace-context/>.

Appendix A.  Example: MCP Tools for a Project Management System

   This appendix applies the profile to a Model Context Protocol [MCP]
   server for a project management system.  The system has projects,
   tasks, and assignees.  Each tool uses a strict JSON Schema, so the
   model can find and call it without inventing parameters.  Every input
   schema sets additionalProperties to false, uses a fixed value set for
   closed choices, marks the required fields, and bounds the size of any
   collection.

Gaikwad                  Expires 1 January 2027                [Page 17]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   The examples below use verb-first names (find_projects, create_task)
   to match common convention.  An alternative is entity-first names
   (projects_find, task_create), which group related operations by
   resource and can reduce selection collisions when the tool surface is
   large.  The table at the end of this appendix shows both forms.

   An agent is often told a project by name, not by identifier.  A
   lookup tool turns the name into an identifier the other tools need.
   This follows the rule in Section 7 not to demand an identifier the
   agent cannot get:

   {
     "name": "find_projects",
     "description": "Find projects by name.",
     "inputSchema": {
       "type": "object",
       "additionalProperties": false,
       "required": ["name_contains"],
       "properties": {
         "name_contains": { "type": "string" },
         "limit": {
           "type": "integer",
           "minimum": 1, "maximum": 20, "default": 10
         }
       }
     }
   }

   A creation tool keeps a strict input schema.  Its description, kept
   short in the example, should also say that the operation notifies the
   assignee, point the agent to find_projects when it has only a name,
   and explain that reusing the idempotency_key returns the original
   task instead of making a duplicate:

Gaikwad                  Expires 1 January 2027                [Page 18]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   {
     "name": "create_task",
     "description": "Create a task in a project.",
     "inputSchema": {
       "type": "object",
       "additionalProperties": false,
       "required": ["project_id", "title"],
       "properties": {
         "project_id": { "type": "string" },
         "title": { "type": "string", "maxLength": 200 },
         "assignee_email": { "type": "string", "format": "email" },
         "priority": {
           "type": "string",
           "enum": ["low", "medium", "high"],
           "default": "medium"
         },
         "idempotency_key": { "type": "string" }
       }
     }
   }

   A search tool bounds its result size and returns an opaque cursor, so
   the agent never computes an offset.  The status filter lets it narrow
   the results before it fetches them:

   {
     "name": "find_tasks",
     "description": "Search tasks in a project (bounded page).",
     "inputSchema": {
       "type": "object",
       "additionalProperties": false,
       "required": ["project_id"],
       "properties": {
         "project_id": { "type": "string" },
         "status": {
           "type": "string",
           "enum": ["open", "in_progress", "done"]
         },
         "limit": {
           "type": "integer",
           "minimum": 1, "maximum": 50, "default": 20
         },
         "cursor": { "type": "string" }
       }
     }
   }

Gaikwad                  Expires 1 January 2027                [Page 19]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   A result is bounded.  It carries human-readable labels and a next
   action, and it gives back a cursor for the following page:

   {
     "tasks": [
       {
         "task_id": "t_8a1",
         "title": "Draft launch checklist",
         "status": "in_progress",
         "assignee": { "id": "u_42", "name": "Priya Rao" },
         "next_actions": { "complete": "update_task_status" }
       }
     ],
     "next_cursor": "eyJvIjoyMH0"
   }

   To read the next page, the agent calls the same tool again and passes
   the cursor straight back.  It does no arithmetic:

   {
     "name": "find_tasks",
     "arguments": {
       "project_id": "p1",
       "status": "open",
       "cursor": "eyJvIjoyMH0"
     }
   }

   A batch tool creates several tasks in one call.  It bounds the array
   size, and its result reports one outcome per item, so the agent can
   see which tasks were created and which were rejected:

Gaikwad                  Expires 1 January 2027                [Page 20]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   {
     "name": "create_tasks_batch",
     "description": "Create several tasks in one project.",
     "inputSchema": {
       "type": "object",
       "additionalProperties": false,
       "required": ["project_id", "tasks"],
       "properties": {
         "project_id": { "type": "string" },
         "idempotency_key": { "type": "string" },
         "tasks": {
           "type": "array",
           "maxItems": 50,
           "items": {
             "type": "object",
             "additionalProperties": false,
             "required": ["title"],
             "properties": {
               "title": { "type": "string", "maxLength": 200 },
               "priority": {
                 "type": "string",
                 "enum": ["low", "medium", "high"]
               }
             }
           }
         }
       }
     }
   }

   The batch result shows the per-item outcomes.  One task was created
   and one was rejected, and the agent can tell exactly which is which:

   {
     "results": [
       { "index": 0, "status": "created", "task_id": "t_901" },
       { "index": 1, "status": "rejected", "code": "TITLE_TOO_LONG" }
     ],
     "created_count": 1,
     "rejected_count": 1
   }

   A state-changing tool uses a fixed value set for the closed list of
   states and accepts an idempotency key.  Its description should note
   the side effect of notifying the assignee:

Gaikwad                  Expires 1 January 2027                [Page 21]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   {
     "name": "update_task_status",
     "description": "Move a task to a new workflow state.",
     "inputSchema": {
       "type": "object",
       "additionalProperties": false,
       "required": ["task_id", "status"],
       "properties": {
         "task_id": { "type": "string" },
         "status": {
           "type": "string",
           "enum": ["open", "in_progress", "done", "cancelled"]
         },
         "idempotency_key": { "type": "string" }
       }
     }
   }

   Each choice maps back to the profile.  The intent-revealing names and
   the use-when guidance reduce wrong-operation mistakes (Section 5).
   The fixed value sets and additionalProperties: false stop the agent
   from inventing values and parameters.  The bounded limit and the
   opaque cursor follow Section 8.  The idempotency key and the stated
   side effects follow Section 10.  The batch result follows the
   partial-failure rule in Section 7.

   The following table shows the verb-first and entity-first forms of
   each tool name used in this appendix.  Verb-first groups operations
   by action type.  Entity-first groups them by resource, which can
   reduce wrong-operation mistakes when the total number of tools is
   large.  Either form works.  Choose based on the size and shape of the
   tool surface and test with agent evaluation.

                +====================+====================+
                | Verb-first         | Entity-first       |
                +====================+====================+
                | find_projects      | projects_find      |
                +--------------------+--------------------+
                | create_task        | task_create        |
                +--------------------+--------------------+
                | find_tasks         | tasks_find         |
                +--------------------+--------------------+
                | update_task_status | task_status_update |
                +--------------------+--------------------+
                | create_tasks_batch | tasks_batch_create |
                +--------------------+--------------------+

                                  Table 1

Gaikwad                  Expires 1 January 2027                [Page 22]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

Appendix B.  Example: A Weak and a Strong Operation Description

   An operation described only well enough for someone who already knows
   the system leaves the agent to guess its scope and its side effects:

   # Too little for an agent
   operationId: updateUser
   summary: Updates a user

   The same operation, described for an agent, names its exact purpose,
   says when not to use it, and states the side effect:

   # Enough for an agent
   operationId: updateUserEmailAddress
   summary: Change a user's email address
   description: >
     Use this only to change an existing user's email address. Do not
     use it for other profile fields. Use updateUserProfile for those.
     Side effect: sends a verification email. The new address stays
     unverified until the user confirms it.

Appendix C.  Example: A Small Response with Field Selection

   The request selects three fields and a bounded page, so the response
   stays small.  The response gives back a ready-to-use link for the
   next page, so the agent does no offset arithmetic:

   GET /projects/p1/tasks?status=open&fields=id,title,status&limit=20
   Accept: application/json

   HTTP/1.1 200 OK
   Content-Type: application/json

   {
     "items": [
       {
         "id": "t_8a1",
         "title": "Draft launch checklist",
         "status": "open"
       }
     ],
     "next_page": "/projects/p1/tasks?status=open&cursor=eyJvIjoyMH0",
     "next_cursor": "eyJvIjoyMH0"
   }

   As an alternative to per-field selection, a response_format parameter
   offers preset levels of detail.  This is simpler when the agent does
   not know which fields to ask for:

Gaikwad                  Expires 1 January 2027                [Page 23]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   GET /tasks/42?response_format=concise
   Accept: application/json

   HTTP/1.1 200 OK
   Content-Type: application/json

   {
     "task_id": "t_42",
     "title": "Draft launch checklist",
     "status": "in_progress",
     "assignee_name": "Priya Rao"
   }

   GET /tasks/42?response_format=detailed
   Accept: application/json

   HTTP/1.1 200 OK
   Content-Type: application/json

   {
     "task_id": "t_42",
     "title": "Draft launch checklist",
     "status": "in_progress",
     "assignee": { "id": "u_42", "name": "Priya Rao",
                   "email": "priya@example.com" },
     "project_id": "p1",
     "created_at": "2026-06-01T10:00:00Z",
     "updated_at": "2026-06-08T14:30:00Z",
     "priority": "high",
     "tags": ["launch", "checklist"]
   }

   The concise form returns display-friendly fields.  The detailed form
   adds internal identifiers, timestamps, and linking fields needed for
   chaining into downstream operations.  Implementers MAY define
   additional levels beyond these two if the data warrants it.

Appendix D.  Example: Previewing a Destructive Write

   A dry-run request reports what an operation would do, without doing
   it.  The agent can check the predicted effects and decide whether to
   go ahead:

Gaikwad                  Expires 1 January 2027                [Page 24]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

   POST /projects/p1/archive
   X-Dry-Run: true
   Content-Type: application/json

   { "reason": "Project completed" }

   HTTP/1.1 200 OK
   Content-Type: application/json

   {
     "dry_run": true,
     "would_change": {
       "project_status": { "from": "active", "to": "archived" },
       "tasks_closed": 14,
       "members_notified": 6
     },
     "reversible": true
   }

   Sending the same request without the X-Dry-Run header performs the
   operation.  The predicted-effects shape is the same, so the agent can
   use it to decide whether to go ahead or to ask for confirmation
   first.

Appendix E.  Example: Common Description Anti-Patterns

   Studies of tool descriptions across MCP servers find that most have
   at least one description problem.  The following anti-patterns lead
   to wrong-operation and wrong-argument mistakes.  Each one is followed
   by the fix.

   Restating the name without adding information.  Bad: "Creates a task"
      for an operation named create_task.  Fix: Say what kind of task,
      in which system, with what effect.  "Create a task in the project
      tracker.  Notifies the assignee by email."

   Omitting side effects.  Bad: a description of a delete operation that
      does not mention it also cancels pending notifications.  Fix:
      State every side effect.  "Deletes the task and cancels any
      pending reminder notifications for it."

   Omitting "do not use this when" guidance.  Bad: an updateUser
      operation that handles only email changes but does not say so.
      Fix: "Use this only to change the email address.  Do not use it
      for other profile fields.  Use updateUserProfile for those."

   Using jargon or internal names the agent has no context for.  Bad:

Gaikwad                  Expires 1 January 2027                [Page 25]
Internet-Draft       Agent-Friendly HTTP API Profile           June 2026

      "Triggers a ZK reconciliation on the specified ledger partition."
      Fix: Use plain terms or define the jargon in the description.
      "Rebalances the account ledger for the given partition."

   Describing what the operation returns rather than when to use it.
      Bad: "Returns a list of task objects with id, title, and status."
      Fix: Lead with the purpose.  "Find tasks in a project, filtered by
      status.  Returns id, title, and status for each match."

   Failing to state the purpose of the operation.  Bad: a tool with a
      name like proc_handler_v2 and a description that says "Handles
      processing."  Fix: State what it does, for what entity, and why an
      agent would call it.

Acknowledgments

   This document gathers considerations discussed across the API design
   and AI agent engineering communities.  The author thanks the authors
   of the referenced specifications and drafts, whose work covers the
   identity and authorization topics this document leaves to them, and
   the reviewers whose feedback shaped the profile structure, the worked
   examples, and the treatment of context exhaustion and observability.

Author's Address

   Madhava Gaikwad
   Independent
   Bengaluru
   India
   Email: gaikwad.madhav@gmail.com

Gaikwad                  Expires 1 January 2027                [Page 26]