Errors
Understand HTTP Status Codes
Every response includes an HTTP status code indicating the result of the request.
| Code | Meaning |
|---|---|
| 200 | OK — request succeeded |
| 204 | No Content — request succeeded with no response body, such as deleting a file |
| 400 | Bad Request — malformed request or conflicting credential sources |
| 401 | Unauthorized — invalid or expired credentials, or no credentials on an endpoint that requires a signed-in user |
| 402 | Payment Required — the operation would exceed a license limit, or the instance's license is locked |
| 403 | Forbidden — insufficient permissions |
| 404 | Not Found — item or collection does not exist, or your permissions exclude the item |
| 422 | Unprocessable Entity — invalid query parameters or input values |
| 500 | Internal Server Error |
Read the Error Response
When a request fails, the API returns a JSON body with the EngineError shape:
{
"message": "Query failed",
"source": {
"message": "No record found"
}
}
| Field | Type | Description |
|---|---|---|
message | string | Human-readable error description |
code | string (optional) | Stable error code, present on errors that define one, such as license limit errors |
source | EngineError (optional) | Nested error providing deeper context. Chains recursively. |
meta | Record<string, unknown> (optional) | Additional structured metadata about the error |
The source field chains recursively — an error can contain a source that itself has a source, providing a full error chain from the outermost context down to the root cause.
Handle Errors in REST
Check response.ok before parsing the body. On failure, parse the error body to read the message and optional source chain.
const response = await fetch('https://example.monospace.io/api/blog/items/Articles?fields=*', {
headers: {
Authorization: 'Bearer YOUR_API_KEY',
},
});
if (!response.ok) {
const error = await response.json();
console.error(`${response.status}: ${error.message}`);
if (error.source) {
console.error('Caused by:', error.source.message);
}
throw new Error(error.message);
}
const { data } = await response.json();
Handle Errors in the SDK
The SDK throws a MonospaceError for every API error response. Two statuses map to subclasses:
| Class | HTTP Status | Extra Properties |
|---|---|---|
MonospaceAuthError | 401 | — |
MonospacePermissionError | 403 | — |
MonospaceError | Any other status | .meta |
See Advanced — Error Handling for the complete error class reference, instanceof patterns, and source chain access.
Handle License Errors
A 402 Payment Required response has one of two causes.
An operation that would exceed a hard limit of the instance's license is rejected. The body carries a code from 6001 to 6008 that identifies the entitlement, and meta.violations gives the usage the operation would produce and the limit:
{
"message": "The requested operation would exceed licensed hard limits",
"code": "6004",
"meta": {
"violations": [
{ "entitlement": "seats", "usage": 4, "hard_limit": 3 }
]
}
}
A locked license rejects every item request with System is locked. Please contact system administrator. and no code. Reading data resumes once an organization administrator resolves the license.
See Licensing for the code table and the operations each code applies to.
Fix Common Errors
Use this table to diagnose the most frequent error scenarios.
| Status | Context | Likely Cause |
|---|---|---|
| 401 | Any request | API key or access token is expired, invalid, or malformed |
| 401 | Endpoints that require a signed-in user, such as /api/system/api-keys | The request has no credentials |
| 402 | Create, invite, or read audit logs | The operation would exceed a license limit; code identifies the entitlement |
| 402 | Any item request | The instance's license is locked |
| 403 | List or get items | Role lacks read permission on the collection. A request without credentials uses the Public role |
| 404 | Get single item | The item does not exist, or your permissions exclude it |
| 404 | Any request | Collection or endpoint does not exist |
| 422 | Create or update | A required input field is missing or an input value has the wrong type |
See Also
- Authentication — set up API keys and authenticate requests
- Writing Data — handle validation errors on create and update
- Licensing — license limits, error codes, and the locked state