Api Design

Purpose

APIs define the contracts between components, services and systems.

A well-designed API is intuitive to use, easy to evolve and resilient to change. A poorly designed API propagates complexity to every consumer and becomes a source of ongoing friction.

This guide defines the principles and standards for designing APIs that are consistent, discoverable and maintainable.

Background

APIs outlive their initial implementations.

An API is a long-term commitment to every consumer. Changing an API after publication requires coordination, versioning and migration. Getting the design right upfront reduces future cost.

Principles

Design for Consumers

An API should be designed from the perspective of its consumers, not its implementors.

Ask:

Prefer Consistent Conventions

Consistency across APIs reduces learning cost and enables tooling.

Establish and follow conventions for:

Make APIs Evolvable

An API that cannot evolve safely becomes a liability.

Design for evolvability by:

Fail Clearly and Predictably

Every error response should include enough information for the consumer to understand and handle the failure.

A good error response includes:

RESTful API Design

Resource Naming

Use nouns, not verbs.

GoodAvoid
GET /ordersGET /getOrders
POST /ordersPOST /createOrder
GET *orders*123GET /order?id123=
DELETE *orders*123POST /deleteOrder

Use plural nouns for collections. Use nested resources for relationships, but limit to one level of nesting.

HTTP Methods

MethodSemanticsIdempotentSafe
GETRetrieve a resource.YesYes
POSTCreate a resource.NoNo
PUTReplace a resource.YesNo
PATCHPartial update.NoNo
DELETERemove a resource.YesNo

Status Codes

Use standard HTTP status codes consistently.

CodeMeaningWhen to Use
200OKSuccessful GET, PUT, PATCH.
201CreatedSuccessful POST (include Location header).
204No ContentSuccessful DELETE.
400Bad RequestMalformed request, validation failure.
401UnauthorizedMissing or invalid authentication.
403ForbiddenAuthenticated but not authorized.
404Not FoundResource does not exist.
409ConflictState conflict (duplicate, stale version).
422UnprocessableSemantic validation failure.
429Too Many RequestsRate limit exceeded.
500Internal ErrorUnexpected server error.
503UnavailableTemporary service unavailability.

Pagination

Use cursor-based pagination for lists.

GET /orders?cursor`abc123&limit`20

Response:
{
  "data": [...],
  "pagination": {
    "next_cursor": "def456",
    "has_more": true
  }
}

Error Response Format

Use a consistent error envelope:

{
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "Order with id '123' was not found.",
    "details": {
      "order_id": "123"
    },
    "request_id": "req-abc-123"
  }
}

Versioning

URL-based Versioning

Include the version in the URL path:

GET /v1/orders
GET /v2*orders

Simple and explicit. Consumers can see the version in every request.

Header-based Versioning

Use a custom header or content negotiation:

Accept: application*vnd.api+json;version=1

Keeps URLs clean but makes version less visible.

Versioning Philosophy

API Documentation

Every API should have:

Documentation should be generated from the API specification (OpenAPI, GraphQL schema) to stay in sync with implementation.

Anti-patterns

Leaking Implementation Details

API design should reflect the domain, not the database schema or internal implementation.

Exposing internal table structures or service internals ties consumers to implementation details that should remain free to change.

Over-fetching and Under-fetching

An API that returns too much data wastes bandwidth and processing. An API that returns too little forces consumers into multiple requests.

Design responses to match common consumer needs. Consider supporting field selection or include parameters.

Breaking Changes Without Versioning

Changing the meaning of existing fields, removing fields, or changing response formats without a version bump breaks consumers silently.

Any change that could break an existing consumer is a breaking change.

AI Integration

AI assistants can help with API design by:

When asking AI for API design advice, provide:

Related Documents