Skip to content
SP StackPractices
intermediate By Mathias Paulenko

API Error Response Template

A reusable template for consistent, informative, and developer-friendly API error responses that reduce debugging time.

Topics: api

Note: This guide follows English-language naming conventions and terminology standards common in international development teams. Examples use English identifiers and comments to maximize compatibility across codebases and tooling.

Template Structure

Use this template to build consistent, actionable error responses for any REST or HTTP API.


{
  "type": "https://api.example.com/errors/invalid-request",
  "title": "Invalid Request",
  "status": 400,
  "detail": "The 'email' field must be a valid email address.",
  "instance": "/orders/123e4567-e89b-12d3-a456-426614174000",
  "errors": [
    {
      "field": "email",
      "message": "must be a valid email address",
      "code": "invalid_format"
    }
  ]
}

Field Reference

FieldRequiredDescription
typeYesURI that identifies the error type and human-readable documentation
titleYesShort, human-readable summary of the problem
statusYesHTTP status code (must match the actual response status)
detailNoDetailed, human-readable explanation specific to this occurrence
instanceNoURI reference that identifies the specific occurrence of the problem
errorsNoArray of field-level validation errors for 400 Bad Request

Legacy Simple Format

For internal APIs or backward compatibility, use this lightweight structure:

{
  "error": {
    "code": "INVALID_PARAMETER",
    "message": "The 'page_size' parameter must be between 1 and 100.",
    "request_id": "req_abc123xyz"
  }
}

Error Code Catalog (Example)

HTTP StatusError CodeWhen to Use
400INVALID_REQUESTGeneric malformed request
400VALIDATION_ERRORSchema or business rule validation failed
401UNAUTHORIZEDMissing or invalid authentication token
403FORBIDDENAuthenticated user lacks permission
404RESOURCE_NOT_FOUNDRequested resource does not exist
409CONFLICTResource already exists or state conflict
422UNPROCESSABLE_ENTITYSemantic validation failed
429RATE_LIMIT_EXCEEDEDToo many requests
500INTERNAL_ERRORUnexpected server-side failure
503SERVICE_UNAVAILABLETemporary outage or maintenance

Best Practices

  • Always return a body — Never send an empty body for 4xx or 5xx responses
  • Use RFC 7807 for public APIs — Consumers expect standard formats; libraries can parse them automatically
  • Include a request ID — Essential for correlating client reports with server logs
  • Do not leak stack traces — Internal details belong in logs, not in responses
  • Localize detail if needed — Use Accept-Language to return localized messages, but keep title stable
  • Link to documentation — The type URI should lead to a docs page explaining the error and how to fix it
  • Be specific in validation errors — Say "phone must match E.164 format" instead of "invalid input"

Common Mistakes

  • Returning 500 with a plain HTML page — breaks API clients expecting JSON
  • Including stack traces or SQL queries in error bodies — security risk
  • Using generic "error": "something went wrong" for every failure — impossible to debug
  • Changing error field names between versions — breaks client parsing logic
  • Not logging the full error context server-side — you lose the ability to investigate

Frequently Asked Questions

Should I use RFC 7807 for internal APIs?

Yes, even for internal APIs. The small overhead of adding type and title pays off when another team needs to integrate, and it forces you to document error cases.

What if an error has multiple causes?

Use the errors array with one object per cause. Each object should include field, message, and optionally code. This pattern is common in validation failures where multiple fields are invalid.

How do I handle errors from downstream services?

Wrap downstream errors in your own format. Do not proxy raw third-party error bodies directly. Map the downstream failure to one of your documented error codes, log the original upstream response, and return a sanitized message to the client.