API Design

Rule

Rules for HTTP APIs, tRPC routers, and server actions.

Design Principles

  • MUSTConsistent error format across all endpoints (see Error Shape below).
  • SHOULDVersion via URL prefix (/v1/) only when introducing breaking changes.
  • SHOULDPrefer cursor-based pagination over offset-based.

HTTP Conventions

  • MUSTUse appropriate status codes — 201 for creation, 204 for deletion, 409 for conflicts, 422 for semantic errors.
  • MUST401 for missing/invalid auth, 403 for insufficient permissions. Never conflate them.

Error Shape

All API errors MUST return:

{
  "error": {
    "code": "auth/token-expired",
    "message": "Your session has expired. Please sign in again.",
    "details": {}
  }
}
  • MUSTcode is machine-readable, namespaced (domain/error-name).
  • MUSTmessage is human-readable, safe to display.
  • SHOULDdetails provides structured context (field errors, limits, etc.).

tRPC

  • MUSTUse @trpc/tanstack-react-query with queryOptions/mutationOptions.
  • MUSTZod for all input validation.
  • MUSTUse queryKey() for cache invalidation — never manual string arrays.
  • SHOULDOrganize routers by domain (user, posts, billing).
  • SHOULDUse superjson as transformer for Date/Map/Set serialization.
  • SHOULDPrefer optimistic updates for mutations that modify displayed data.
  • See integrations.md for adapter error handling rules.

OpenAPI

  • MUSTGenerate OpenAPI specs from code — never hand-write them.
  • SHOULDUse zod-openapi for Zod-first HTTP APIs, trpc-openapi for tRPC REST exposure.
  • SHOULDServe the spec at /api/openapi.json for tooling and agent consumption.
  • SHOULDDocument rate limits, auth requirements, and pagination in the spec.

CLI Surface

Every project with an API SHOULD ship a CLI that exposes it. See cli.md.