On this page
The core idea
A useful error contract separates a stable machine-readable code from a human-readable explanation. The response should include enough context to locate the problem without exposing internal implementation or secrets. Consistency matters because clients often handle errors across many endpoints through shared logic.
A practical approach
Step 1
Define error categories around client actions: invalid input, unauthenticated, forbidden, missing resource, conflict, rate limit and dependency failure.
Step 2
Return field-level details for validation problems and a correlation identifier for support. Keep internal stack traces in protected logs.
Step 3
Document which errors are retryable and under what conditions. Pair retry guidance with idempotency for operations that change state.
Worked example
An enrollment endpoint rejects a request because the selected course is no longer available. A stable code such as course_unavailable lets the interface offer another course. A generic ‘something went wrong’ message gives neither the learner nor the client application a useful next step.
A mistake to avoid
Returning HTTP success for every response and hiding failures inside arbitrary text makes shared client handling harder. Also avoid exposing whether a private record exists when the requester is not allowed to know.
Try it yourself
Choose five failure cases for one endpoint. Write the status, stable error code, safe message and client recovery action for each, then review them together for consistency.
Your implementation checklist
- Error codes are stable and documented.
- Messages avoid internal secrets.
- Clients know which failures are retryable.
- Validation errors identify actionable fields.
Share or cite this guide
Innovate with Ajay Editorial (2026-10-04). Design API Errors Clients Can Recover From. https://innovatewithajay.com/blogs/design-api-errors-for-recovery
