flashman
← All guides

Problem Details contracts for HTTP APIs

Design consistent application/problem+json errors with stable type identifiers, safe extensions, gateway coverage, localization, observability, and client fallbacks.

2026-09-18 · 8 min read

  • api
  • problem-details
  • http

Problem Details standardizes a small HTTP API error object so each endpoint does not invent a new envelope. Its base members describe a problem category and one occurrence, while extension members carry domain-specific machine data.

Consistency requires more than serializing five familiar keys. Status codes, media types, type identifiers, gateway-generated failures, documentation, privacy, and client fallback behavior form one contract.

Separate category from occurrence

Use type to identify a stable problem category. Use title as a short category summary, detail for occurrence-specific human context, and instance when the contract provides an identifier for this occurrence.

  • Keep the HTTP status line authoritative.
  • Use a stable type identifier under publisher control or the defined default.
  • Do not make clients parse title or detail text.
  • Avoid exposing stack traces, secrets, or private record data.

Design extensions as an API

Extensions such as field errors, limits, balances, or retry information need names, types, optionality, and evolution rules. Prefer predictable arrays or maps over embedding another unrelated legacy envelope.

Clients should ignore unknown extensions and validate the members they consume. Producers should avoid changing an existing member's type because that turns a compatible addition into a runtime failure.

Cover infrastructure failures

Authentication middleware, rate limiters, routers, gateways, and upstream-timeout handlers often bypass the application's exception serializer. Configure and test those layers so expected API failures use the documented format where feasible.

Clients still need a fallback for empty bodies, plain text, HTML, malformed JSON, and network failures. Logging should retain the transport status and safe identifiers even when parsing fails.

Build a contract fixture suite

Use Flashman's JSON formatter for bodies, URL tool for type and instance identifiers, timestamp converter for retry metadata, diff for contract versions, and case converter to catch extension-name drift.

Test validation, authentication, authorization, not found, conflict, rate limiting, overload, upstream timeout, malformed input, localization, unknown extensions, status mismatch, wrong media type, gateway HTML, empty responses, and redaction of sensitive details.

Try these tools