API Design

An API Error Taxonomy Shared by Users, Clients, and Operators

Layer transport, authentication, validation, conflict, quota, dependency, and internal failures into stable codes, HTTP status, retry guidance, and safe user copy.

A capability stays maintainable only when the team can explain every state, retry, and piece of residual data—not merely show one successful run. HTTP status carries generic semantics and application code carries stable cause. Clients never branch on localized, mutable, potentially unsafe messages.

An API contract includes units, defaults, idempotency, error classes, and version windows—not only field types. Clients distinguish retryable, user-action, and permanent outcomes to avoid duplicate side effects.

Questions the design must answer

This capability crosses clients, networks, and servers, so a local optimization can create a system failure. Decisions must constrain both endpoints, persisted truth, and operating budgets together.

  • Responses contain code, safeMessage, requestId, and optional retryAfter/details; documentation defines retryability, user action, metrics, and unknown-code fallback.
  • Separate protocol facts, user intent, and automatic recovery; automation may restore facts but never overturn an explicit choice.
  • Use explicit capability negotiation so older clients receive an explained fallback instead of a half-working state.

The delivery standard for An API Error Taxonomy Shared by Users, Clients, and Operators is a usable normal path, convergent failures, bounded resources, and a state users can understand. The result is a production capability that can be explained, degraded safely, and rolled back—not a demo that works once.

Edge cases are part of the feature

Production failures often appear when two individually valid actions overlap. Inspect stale messages, duplicate effects, exhausted resources, and mixed versions instead of patching only the current stack frame.

  • Returning 200 for every error breaks proxies and monitoring, while raw database or TURN text leaks internals and couples clients to vendor wording.
  • A boolean failure cannot distinguish retryable, user-action, and permanent refusal, producing an endless loop.
  • An untested fallback receives all traffic during a primary failure and becomes the slower, more expensive bottleneck.

Prove that it works with evidence

Build golden cases from known inputs and controlled faults, then align production metrics with those results. Verification extends to production only when signals detect the same degradation early.

  1. Generate validation, unauthorized, conflict, rate-limit, and internal failures for every endpoint; contract tests verify status, code, redaction, and UI action.
  2. Run one hundred start, fail, retry, and cancel cycles; handles, listeners, queues, and temporary data must return to baseline.
  3. Use fault injection to prove alerts precede user reports and operators can locate the failing phase from bounded evidence.

The release bar is clear: users understand the current state, failures stop or recover, resources stay bounded, and operators can identify the phase from minimum necessary evidence.

Put the guide to work

Open uCopy and connect two devices securely from the browser.

Start for free