Skip to content
Mock APIs

Guides

Errors

Every error uses the same JSON shape and an accurate HTTP status code, so you can write one error handler for the whole API.

Error format

404 Not Found
{
  "message": "User with id 999999 not found",
  "status": 404,
  "code": "RESOURCE_NOT_FOUND",
  "path": "/api/v1/users/999999",
  "requestId": "6f1c2a9e-3b7d-4c51-9a0e-2d8f4b6c1e73"
}
Error fields
FieldDescription
messageHuman-readable explanation. Safe to show to developers; do not parse it.
statusThe HTTP status code, repeated for convenience.
codeStable machine-readable error code. Branch on this.
pathThe request path (without query string).
requestIdMatches the X-Request-Id response header. Include it in bug reports.
errorsOnly for validation and conflict errors: a list of { path, message } per field.

Validation errors

422 responses list every problem at once, keyed by field path, which maps neatly onto form field errors:

422 Unprocessable Entity
{
  "message": "Validation failed: email: email is required",
  "status": 422,
  "code": "VALIDATION_ERROR",
  "path": "/api/v1/users",
  "requestId": "6f1c2a9e-3b7d-4c51-9a0e-2d8f4b6c1e73",
  "errors": [
    {
      "path": "email",
      "message": "email is required"
    }
  ]
}

Status and error codes

Error codes
StatusCodeMeaning
400INVALID_PARAMETERA query or path parameter is missing, unknown, or out of range.
400INVALID_IDA path ID is not a positive integer.
400INVALID_JSONThe request body is not valid JSON.
401MISSING_TOKEN / INVALID_AUTH_HEADERAuthorization header missing or malformed.
401INVALID_TOKEN / TOKEN_EXPIREDBearer token invalid or expired.
401INVALID_CREDENTIALSLogin failed.
403FORBIDDENAuthenticated, but not allowed.
404RESOURCE_NOT_FOUNDNo record with that ID (or category).
404ROUTE_NOT_FOUNDNo endpoint at that path.
405METHOD_NOT_ALLOWEDThe path exists but not for this method. See the Allow header.
409CONFLICTA unique value (email, username) is already taken.
413PAYLOAD_TOO_LARGEThe body exceeds 100 KB.
415UNSUPPORTED_MEDIA_TYPEThe body is not sent as application/json.
422VALIDATION_ERRORThe JSON body is well-formed but fails validation. See the errors array.
429RATE_LIMIT_EXCEEDEDToo many requests. Wait for Retry-After seconds.
500INTERNAL_ERRORUnexpected server error. No internal details are exposed.
503SERVICE_UNAVAILABLE / REQUEST_TIMEOUTThe database is unavailable or the request took too long. Retry later.

Handling errors in your client

  • Check the HTTP status first. fetch does not throw on 4xx/5xx; Axios and Dio do.
  • Branch on code, not on message.
  • Retry only 429 and 503, after the Retry-After delay.
  • Want to test your error UI? /test/status/:code returns any common status on demand.