Documentation ·Docs
API design guidelines

Errors

One error envelope with a code, a message, a request ID and a documentation link, the status codes it goes with, and the retry headers.

Read this page in العربية

On this page

At a glance#

An error response carries the status code that says what happened and a JSON body with one error object. The body is the same for every API, so a client parses it once.

{
  "error": {
    "code": "quota_exceeded",
    "message": "Your quota is exhausted. Retry after the time given in Retry-After, or upgrade your subscription.",
    "request_id": "3f6d0c1e-9a47-4b3f-8d0e-5a1c7b2e9f10",
    "docs_url": "https://api360.sa/docs/consumer/errors-and-retries#quota_exceeded"
  }
}
FieldTypeMeaning
codestringA stable, machine-readable snake_case code. A client branches on it, so it never changes meaning.
messagestringA sentence for a person. An API that serves Arabic and English answers in the language of the Accept-Language header. The text can be reworded; the code cannot.
request_idstringThe value of the X-Request-Id response header, so a report to support points at one call.
docs_urlstringThe page that explains the code.

code, message and request_id are always present. A provider that cannot link a page for a code still sends docs_url with the page of its API reference.

Status codes#

StatusUse it whenNotes
400The request is malformed or a parameter is out of rangeIncludes a per_page above the maximum
401The credential is missing or not valid
403The caller is known and not allowed
404The resource or the route does not exist
409The request conflicts with the current state, or an Idempotency-Key is still in flight
422The request is well formed and cannot be processed, or an Idempotency-Key was reused with another request
429A quota or a rate limit is used upSends Retry-After and the RateLimit-* headers
500, 502, 503, 504The service failed503 sends Retry-After; a client retries 502, 503 and 504 with backoff

Use the status that fits; never answer 200 with an error body.

Headers#

HeaderOnValue
Retry-After429, 503Seconds until a retry can succeed
RateLimit-Limit, RateLimit-Remaining, RateLimit-ResetResponses that carry a quota or a rate limitThe limit, what is left, seconds to the reset
X-Request-IdEvery responseThe value in request_id
Content-LanguageEvery errorThe language of message

In the specification#

Declare the error responses an operation can return, with one shared component, so the file describes the envelope once:

components:
  responses:
    Error:
      description: The error envelope.
      content:
        application/json:
          schema:
            type: object
            required: [error]
            properties:
              error:
                type: object
                required: [code, message, request_id]
                properties:
                  code: { type: string }
                  message: { type: string }
                  request_id: { type: string }
                  docs_url: { type: string }

Each operation lists at least one error response (400, 401, 404 and so on, or default) that points at it.

Planned

The gateway answers every error it produces itself, such as a missing key, an unknown route or an exhausted quota, in this envelope on all environments, with the error codes published as one catalogue. An error that a provider's own service returns is passed through unchanged.

Checked by#

RuleSeverityChecks
api360-error-envelope-schemaerrorA declared 4xx, 5xx or default response with a JSON body describes the envelope: an error object with string code, message, request_id and docs_url, the first three required
api360-error-responses-declaredwarnEvery operation declares at least one error response

See also#

Was this page helpful?
Updated 2026-10-17