Skip to content

Error Handling

All error responses follow the JSON:API error format, providing structured information about what went wrong.

Error Response Structure

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "detail": "This field is required.",
      "source": {"pointer": "/data/attributes/email"}
    }
  ]
}
Field Description
status HTTP status code as a string
title Short, human-readable summary of the error
detail Specific explanation of what went wrong
source.pointer JSON pointer to the request field that caused the error (when applicable)

Common Error Codes

400 -- Bad Request

Malformed requests or request-body validation failures detected while parsing the JSON:API document and validating request attributes. This includes both structural issues and semantic or value validation errors raised while handling the request body.

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "detail": "This field is required.",
      "source": {"pointer": "/data/attributes/email"}
    }
  ]
}

When more than one request field is invalid, the response may include multiple error objects. For example:

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "detail": "Ensure this value is greater than or equal to 1.",
      "source": {"pointer": "/data/attributes/extra-guest-fee"},
      "code": "min_value"
    },
    {
      "status": "400",
      "title": "Bad Request",
      "detail": "Ensure this value is greater than or equal to 1.",
      "source": {"pointer": "/data/attributes/extra-guest-threshold"},
      "code": "min_value"
    }
  ]
}

Token request errors: When requesting a token at /o/token/, you may receive an error if user_id references a user that doesn't exist or isn't owned by your application, credential_id does not belong to the provided user_id, user_id is provided with app-level scopes such as user:write, or user-level scopes are requested without user_id when your application requires user-scoped tokens. These return a standard OAuth2 error response, not JSON:API format, with "error": "invalid_scope".

Request ID Header

You may send an optional X-Request-ID header on any Public API request to make log correlation easier when debugging with Beyond support.

  • If you send a valid UUID, the API uses that value after normalizing it to the canonical lowercase hyphenated form.
  • If you omit the header, or send it blank or whitespace-only, the API generates a UUID for the request.
  • Every response except the /healthz fast-path includes the effective X-Request-ID header so you can log or report the exact value the server used.
  • If you send a non-empty X-Request-ID that is not a valid UUID, the request is rejected with 400 Bad Request.

For JSON:API endpoints, the error response identifies the header explicitly:

{
  "errors": [
    {
      "status": "400",
      "title": "Bad Request",
      "detail": "X-Request-ID header must be a valid UUID.",
      "source": {"header": "X-Request-ID"}
    }
  ]
}

For non-JSON:API endpoints such as /o/token/, the API returns a simpler JSON error body:

{
  "error": "X-Request-ID header must be a valid UUID."
}

401 -- Unauthorized

Missing or invalid authentication token.

{
  "errors": [
    {
      "status": "401",
      "title": "Unauthorized",
      "detail": "Authentication credentials were not provided."
    }
  ]
}

Tip

If you receive a 401, check that your access token has not expired. Tokens are valid for 1 hour. See Token Refresh.

403 -- Forbidden

The token is valid but lacks the required scope for this operation, or the token is scoped to a different user.

{
  "errors": [
    {
      "status": "403",
      "title": "Forbidden",
      "detail": "You do not have permission to perform this action."
    }
  ]
}

Common causes:

  • Missing scope: The token doesn't include the required scope for this endpoint.
  • User-scoped token restriction: A user-scoped token attempted an app-level operation (e.g., creating or deleting a user).
  • Cross-user access: A user-scoped token attempted to access resources belonging to a different user.
  • Source IP not allowed: Your application has an IP allowlist configured and the request origin IP is not in that allowlist (applies to both /o/* OAuth2 endpoints and /api/v1/* resource endpoints).

404 -- Not Found

The requested resource does not exist or is not accessible to your application.

{
  "errors": [
    {
      "status": "404",
      "title": "Not Found",
      "detail": "Listing 12345 not found"
    }
  ]
}

422 -- Unprocessable Entity

The JSON:API document is structurally valid and request-body validation has already passed, but the operation is still rejected during downstream domain or integration processing. This includes channel-specific validation or authentication failures that are not simple request-body field errors.

{
  "errors": [
    {
      "status": "422",
      "source": {"pointer": "/data/attributes/credentials"},
      "title": "Invalid Credentials",
      "detail": "Channel 'hostaway': Invalid client credentials",
      "meta": {"channel": "hostaway", "code": "invalid_credentials"}
    }
  ]
}

429 -- Too Many Requests

Rate limit exceeded. See Rate Limiting for details on handling this error.

500 -- Internal Server Error

An unexpected server error. If this persists, contact [api-support@beyondpricing.com](mailto:api-support@beyondpricing.com).

Best Practices

  • Check the status field to determine the error category
  • Use source.pointer to identify which request field caused validation errors
  • Expect multiple error objects when more than one request attribute is invalid
  • Log the full error response for debugging
  • Implement retry logic with exponential backoff for 429 and 5xx errors
  • Do not retry 400, 401, 403, 404, or 422 errors without changing the request