Lesson 12 / 25
Describing Errors Consistently
Model error responses with Problem Details and reusable responses.
Errors are part of the contract
Clients spend much of their integration effort on errors, so describe them as carefully as success responses. Use one consistent error format across the API. A widely adopted standard is Problem Details for HTTP APIs (RFC 9457, which obsoletes RFC 7807), with media type application/problem+json and fields type (a URI identifying the problem type), title, status, detail and instance, plus extension members such as errors for field-level validation messages or traceId. Define the error schema once in components/schemas and reusable responses (BadRequest, Unauthorized, Forbidden, NotFound, Conflict, ValidationProblem, TooManyRequests, ServerError) in components/responses, then reference them from every operation. Include examples of real error bodies. Document headers relevant to errors, such as Retry-After on 429 and 503. Avoid leaking internal details (stack traces, SQL) in error messages, and keep type URIs stable so clients can branch on them.
Problem Details schema and reusable error responses
One error shape everywhere, with field-level validation details.
components:
schemas:
Problem:
type: object
required: [type, title, status]
properties:
type: { type: string, format: uri, examples: ['https://api.example.com/problems/validation'] }
title: { type: string }
status: { type: integer }
detail: { type: string }
instance: { type: string }
traceId: { type: string }
errors:
type: array
items:
type: object
required: [field, message]
properties:
field: { type: string, examples: ['items[0].quantity'] }
message: { type: string, examples: ['must be between 1 and 99'] }
responses:
ValidationProblem:
description: The request body or parameters are invalid
content:
application/problem+json:
schema: { $ref: '#/components/schemas/Problem' }
examples:
badQuantity:
value:
type: https://api.example.com/problems/validation
title: Invalid request
status: 422
errors: [{ field: 'items[0].quantity', message: 'must be between 1 and 99' }]
TooManyRequests:
description: Rate limit exceeded
headers:
Retry-After: { schema: { type: integer }, description: Seconds to wait }
content:
application/problem+json:
schema: { $ref: '#/components/schemas/Problem' }Use a default response sparingly
A default response can catch undocumented errors, but it is no substitute for listing the specific status codes clients must handle. Specific codes generate clearer SDK types and documentation.
Quick check: Which RFC defines Problem Details for HTTP APIs in its current version?
- RFC 9457
- RFC 2616
- RFC 6749
- RFC 7519
Answer
RFC 9457 — RFC 9457 is the current Problem Details standard, obsoleting RFC 7807.