standards

Errors

The unified error model — envelope shape, codes, and HTTP statuses.

Every error the API returns shares one envelope, so you can handle failures uniformly across endpoints.

The error envelope

A failed request — here, a lookup of a missing record — returns a body like this:

{
  "success": false,
  "statusCode": 404,
  "message": "Record \"abc123\" not found.",
  "code": "SCHEMA_RECORD_NOT_FOUND"
}
FieldDescription
successAlways false for errors.
statusCodeThe HTTP status, mirrored in the body.
messageA human-readable explanation. 5xx messages are masked to "Internal server error" outside development.
codeA stable machine-readable error code (see below). Absent for errors that don't map to a registered code, such as request-body validation failures.

When request-body parsing fails, message is always "Validation failed" and no code is set. The envelope then includes an errors array, where each entry is a { path, message } pair pointing at the invalid field — path is an array, since it can point into nested fields:

{
  "success": false,
  "statusCode": 400,
  "message": "Validation failed",
  "errors": [{ "path": ["limit"], "message": "Expected number, received string" }]
}

Validation that happens at the schema level — a value that doesn't match its attribute's type or constraints — returns SCHEMA_VALIDATION_FAILED instead.

Common error codes

All codes come from a single platform-wide registry. The ones you'll encounter most often:

CodeHTTPMeaning
SCHEMA_VALIDATION_FAILED400Input failed schema validation.
SCHEMA_INVALID_OBJECT_NAME400The object name is malformed.
SCHEMA_INVALID_ATTRIBUTE_NAME400An attribute name is malformed.
SCHEMA_FORBIDDEN403The actor lacks permission.
SCHEMA_PROTECTED_OBJECT403The object is system-protected.
SCHEMA_SYSTEM_ENTITY_IMMUTABLE403A system entity cannot be modified.
SCHEMA_RECORD_NOT_FOUND404No record with that id.
SCHEMA_OBJECT_NOT_FOUND404No object with that name.
SCHEMA_ATTRIBUTE_NOT_FOUND404No such attribute.
SCHEMA_ROLE_NOT_FOUND404No such role.
SCHEMA_PLAN_NOT_FOUND404No schema plan with that id.
SCHEMA_TIMEOUT408The operation timed out.
SCHEMA_DUPLICATE_OBJECT409An object with that name already exists.
SCHEMA_DUPLICATE_ATTRIBUTE409An attribute with that name already exists.
SCHEMA_CONFLICT409The request conflicts with current state.
DOCUMENT_MIME_NOT_ACCEPTED400The file matches no entry of the document attribute's accepts list (MIME glob, exact MIME type, or extension).
DOCUMENT_MULTIPLE_NOT_ALLOWED400The document attribute doesn't accept multiple files.
DOCUMENT_SIZE_EXCEEDED400The file exceeds the document attribute's maxFileSize.
DOCUMENT_NOT_FOUND_FOR_OPERATION404The target document doesn't exist.

The platform derives the HTTP status from the error code; any code without an explicit mapping falls back to 500.

Rate limits

Rate limiting is disabled by default. When enabled, the default is 100 requests per minute per client IP. Two exceptions: file uploads are limited to 20 per minute, and the schema endpoints are not rate-limited.

Exceeding a limit returns a 429 in the same envelope, without a code field:

{ "success": false, "statusCode": 429, "message": "ThrottlerException: Too Many Requests" }

Treat a 429 like a transient failure: back off and retry.

Handling errors

Branch on code for precise handling. Fall back to statusCode for coarse categories: 4xx means the request is wrong — fix it before retrying; 5xx is server-side and safe to retry with backoff. The two exceptions are 408 and 429, which are safe to retry as-is after backing off.