General Interview: How Would You Design an HTTP API That AI Agents Can Use Reliably?
Prompt and scope
Turn a project-management API designed for human developers into one that AI agents can call reliably. Explain operation descriptions, inputs, outputs, pagination, errors, write confirmation, rate limits, and security. The prompt references the IETF June 2026 “Agent-Friendly HTTP API Profile” Internet-Draft. It is Informational and still work in progress; it defines no new protocol, identity, or authorization mechanism.
What the interviewer is testing
- Treating the machine-readable description as a contract rather than after-the-fact documentation.
- Reducing wrong choices with stable names, strict schemas, bounded responses, and cursor pagination.
- Making errors, retries, idempotency, previews, and undo actionable signals.
- Separating API usability from agent identity, authorization, and prompt-injection security.
Questions to clarify before answering
- Will agents discover the API through OpenAPI, an MCP tool layer, or a custom catalog?
- Which operations are read-only and which notify, charge, or mutate state?
- Do responses need field selection, cursor pagination, and a maximum page size?
- Can clients provide an idempotency key and retrieve the original result after a timeout?
- Which returned fields contain untrusted user content that must be isolated from control fields?
30-second answer framework
Treat the API description and HTTP behavior as one input contract. Keep operation names stable and intent-revealing, reject unknown input properties, return small responses with field selection, and paginate collections with cursors. Errors carry stable codes, retryability, and next actions; writes support idempotency keys, preview, confirmation, and undo. The server enforces limits, authorization, and audit; it cannot delegate security decisions to the agent. The IETF document is a draft checklist, not an authentication protocol.
Step-by-step deep dive
1. Separate the API and tool layers
OpenAPI and similar machine-readable descriptions belong to the API layer; MCP and other tool-calling protocols belong to the tool layer. Build a stable, verifiable API contract first so multiple tool layers can reuse it. Do not make one agent’s prompt or tool name the only security boundary.
2. Design distinguishable operations
Operation IDs should be stable, short, and intent-revealing. On a large tool surface, entity-first names such as taskcreate and taskupdate can be easier to distinguish than a shared create_ prefix. Descriptions should state when and when not to use an operation, its side effects, and which lookup operation obtains a missing identifier.
3. Constrain inputs and outputs
Input schemas should define required fields, closed enums, lengths, and array limits, and reject unknown properties. Responses should be small by default and support field selection or verbosity. Do not rely on a client to request less; the server still controls cost and context use.
{
"name": "task_create",
"description": "Create a task; notifies the assignee.",
"inputSchema": {
"type": "object",
"additionalProperties": false,
"required": ["project_id", "title", "idempotency_key"],
"properties": {
"project_id": {"type": "string"},
"title": {"type": "string", "maxLength": 200},
"priority": {"type": "string", "enum": ["low", "medium", "high"]},
"idempotency_key": {"type": "string", "maxLength": 128}
}
}
}4. Make reads and pagination recoverable
Return an opaque cursor instead of asking an agent to calculate offsets. Bind the cursor to the query, expire it, and return next_cursor with a ready-to-use next action. Stable ordering, conditional requests, and field selection reduce duplicate transfer and context use.
5. Make errors machine-actionable
Return stable codes, structured details, and a retryable flag; include a next-operation link when useful. A 429 response should provide a retry delay, validation errors should identify fields, and long-running jobs should provide a status URL. Natural language helps people, but it cannot be the only control semantic.
{
"type": "https://api.example/problems/rate-limit",
"title": "Too many requests",
"status": 429,
"code": "RATE_LIMITED",
"retryable": true,
"retry_after_seconds": 30
}6. Protect writes
Writes accept an idempotency key with a documented window and scope. A retry after a timeout returns the original result instead of creating a duplicate. High-risk writes provide dry-run, confirmation, or undo and state notification, charging, and other side effects. The server still performs authorization, quota, and audit checks.
7. Set security and observability boundaries
Mark user- or third-party text as data and keep it separate from trusted control fields to reduce indirect prompt injection. Limit response size, page size, polling, and tool namespaces; require least privilege and human confirmation for high-risk operations. Record a correlation ID, actor, delegation, result, and retries without logging sensitive content.
8. Validate and iterate
Use fixed task sets to measure operation-selection accuracy, parameter errors, duplicate writes, recoverable errors, average response size, context use, success after 429, and confirmation coverage. Version descriptions, schemas, errors, and responses. Turn draft recommendations into an internal checklist rather than promising standards compatibility.
High-quality sample answer
I would treat the API description as the primary contract and design HTTP behavior around it. Operation IDs are stable and express entity and intent; descriptions state use conditions, forbidden cases, and side effects. Input schemas reject unknown fields and bound enums, lengths, arrays, and pages. Collections use opaque cursors and stable ordering, while responses are small and field-selectable.
Errors carry a stable code, retryability, retry_after, and a next action. Writes require idempotency keys and return the original result after a timeout; high-risk writes support preview, confirmation, or undo. The server enforces authorization, rate limits, size, and audit, rather than trusting the agent to follow prose. User content is isolated from control fields, and tool providers use separate namespaces with correlation IDs.
Finally, evaluate a task set for wrong choices, parameter errors, duplicate writes, response size, retry success, and confirmation coverage. The IETF document is an Informational June 2026 draft with no authentication or authorization protocol, so I would use it as a design checklist with internal versioning and rollback.
Common mistakes
- Calling the profile a new identity or authorization protocol.
- Optimizing prompts while leaving OpenAPI, schemas, errors, and side effects underspecified.
- Asking the agent to limit response size or calculate pagination offsets.
- Omitting idempotency, preview, confirmation, or undo from writes that can be retried.
- Putting returned user text into trusted instruction fields and ignoring indirect prompt injection.
Follow-up questions and responses
Why not just write more detailed documentation?
An agent chooses from machine-readable descriptions and responses on each step. Stable fields, enums, error flags, and cursors are easier to execute than advice scattered through prose; documentation remains useful for people and migration.
Which layer owns security, the API or MCP?
The API must enforce authentication, authorization, rate limits, and audit. A tool layer can limit exposure, namespaces, and confirmation, but it cannot replace server-side access control.
How do you decide which writes need confirmation?
Classify by irreversibility, amount, data disclosure, external notification, and privilege scope. High-risk operations expose dry-run or a confirmation token; low-risk idempotent updates may run automatically, but the server always validates them.
What if descriptions are polluted by third-party content?
Place third-party text in explicit data fields and prevent it from changing tool definitions or permissions. Isolate provider namespaces, pin fingerprints, audit versions, and recheck authorization on the server.