Skip to main content

Response format and status codes

Response format and status codes

Base success response (200, 201, 202)

{
  "data": {
    "user_id": 123,
    "user_name": "john_doe"
  },
  "message": "User retrieved successfully."
}

Base collection response (200)

{
  "data": [
    { "user_id": 123, "user_name": "john_doe" },
    { "user_id": 456, "user_name": "jane_doe" }
  ],
  "pagination": {
    "page": 1,
    "page_size": 10,
    "total_pages": 5
  },
  "message": "Users retrieved successfully."
}
Empty response must be an empty array:
{
  "data": [],
  "pagination": {
    "page": 1,
    "page_size": 10,
    "total_pages": null
  },
  "message": "Users retrieved successfully."
}

Base error response (400-500)

{
  "error": {
    "key": "USER_NOT_FOUND",
    "message": "The specified user does not exist."
  }
}
Rules:
  • error.key is mandatory and machine-readable
  • error.message is human-readable and should be localized

Base deleted response (204)

HTTP 204 responses have no body.

Base validation error response (422)

{
  "errors": [
    {
      "parameter": "user_name",
      "message": "User name is not long enough.",
      "key": "USER_NAME_NOT_LONG_ENOUGH"
    }
  ]
}
Rules:
  • parameter should use snake_case and match the request field name where possible
  • message should be localized
  • key should be stable and machine-readable

Base OPTIONS response

OPTIONS responses should rely on headers, not a body. Example headers:
HTTP/1.1 200 OK
Allow: GET,HEAD,POST,OPTIONS
Content-Length: 0

HTTP status codes

CodeMeaningUse when
200OKStandard GET, PUT, PATCH, DELETE
201CreatedNew resource created (POST)
202AcceptedAsync operation started
204No ContentSuccessful with no body
400Bad RequestValidation error or bad input
401UnauthorizedAuth missing or invalid
403ForbiddenNo permission
404Not FoundResource does not exist
409ConflictDuplicate or inconsistent data
422Unprocessable EntitySemantic validation failure
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected backend failure

Rate limiting

All REST APIs should expose standardized rate-limit information via HTTP response headers. Headers:
HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed within the time window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUNIX timestamp (seconds) when the window resets
Retry-AfterSeconds to wait before retrying (429 only)
Example:
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 742
X-RateLimit-Reset: 1705228800
Rate limit exceeded example:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705228800
{
  "error": {
    "key": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests. Please retry after the rate limit window resets."
  }
}