Skip to main content

Errors

Most error responses use a structured error envelope, so your automation can branch on typed codes rather than parsing prose. A few do not; see Responses without the envelope. This page covers the envelope shape, common HTTP statuses, typed error codes, and how to handle them well.

On this page: the envelope, common statuses, responses without the envelope, error codes, handling errors well.

The envelope​

{
"error": {
"code": "FIELD_VALIDATION_ERROR",
"message": "Human-readable description of what went wrong",
"details": { "errors": [ { "field": "name", "error": "must be 1 to 300 characters", "value": "" } ] },
"timestamp": "2026-05-31T10:00:00Z"
}
}

code and message are always present; timestamp records when the error occurred. Some codes add a structured details object (see below). Branch on error.code, not on the human-readable message.

Common statuses​

HTTPMeaningWhat to do
400Request failed validationInspect error.code and details, fix the offending field, retry
401Missing or expired tokenFetch a new token (see Authentication)
403Token valid but lacks permissionUse a Super User service account for writes
404Resource or configuration version not foundVerify the ID and configurationVersion
409Conflict (for example, publishing an empty draft, a concurrent rule edit, or another publish in progress)Inspect error.code: CONFLICT is often safe to ignore, PUBLISH_IN_PROGRESS is safe to retry after a short wait
413Request body or uploaded file too largeReduce the payload; see System limits. Branch on the status: an oversized request body gets the gateway's body, not this envelope
422Well-formed request the server cannot act onInspect the message and adjust the request
429Tenant rate limit exceededWait 60 seconds, then retry every 15 seconds. The body is the gateway's, not this envelope; pace calls with the RateLimit-Remaining header. See System limits
500Server error, or a response too large to return (RESPONSE_TOO_LARGE)Retry with backoff; for RESPONSE_TOO_LARGE, request a smaller limit and continue with the cursor. If the error persists, contact support
501Operation not supported for the objects you namedDo not retry; inspect error.code

Responses without the envelope​

ResponseBody
401The authentication layer's own response
413 for an oversized request bodyThe API gateway's body
429The API gateway's body: { "_error": { "code", "message", "_request_id" } }

Branch on the HTTP status first, then on error.code when the body carries the envelope.

Error codes​

The error.code is a typed discriminator. Some codes add a structured details object you can act on programmatically:

error.codeHTTPdetails
VALIDATION_ERROR400none (generic validation failure)
FIELD_VALIDATION_ERROR400details.errors[], each with field, error, optional index and value
CONTIGUITY_VIOLATION400details.sectionId, details.ruleIds (rules of a section not contiguous)
INCOMPLETE_ARRAY400details.missingRules, details.missingSections (positions array omits existing items)
NOT_FOUND404none
CONFIGURATION_VERSION_NOT_FOUND404none (the configurationVersion you asked for does not exist)
FIELD_REFERENCE_NOT_FOUND404details.errors[] (a referenced rule, section, or anchor ID does not exist)
FORBIDDEN403none
UNSUPPORTED_OPERATION501none
PARTIAL_PUBLISH_POLICY_UNSUPPORTED501details.errors[] (a partial publish named a rule or section)
PARTIAL_PUBLISH_TYPE_UNSUPPORTED501details.errors[] (a partial publish named an object type it does not support)
CONFLICT409none (the request conflicts with the current state of the resource)
PUBLISH_IN_PROGRESS409none (another publish or draft reset holds the draft, so nothing was published)
REQUEST_ENTITY_TOO_LARGE413none (an uploaded file exceeds its size limit)
UNPROCESSABLE_ENTITY422none (well-formed request the server cannot act on)
INTERNAL_ERROR500none
RESPONSE_TOO_LARGE500none (the response exceeds the service limit; request a smaller page)
PROVIDER_IN_USE409details naming what still references the cloud storage provider

The bulk device and user actions add their own codes: DEVICES_NOT_FOUND, USERS_NOT_FOUND, INVALID_DEVICE_ID, INVALID_USER_ID, INVALID_STATUS_TRANSITION, UNEXPECTED_DEVICE_STATUS, CANNOT_DELETE_SUSPENDED_DEVICE. A request with more device or user IDs than an action accepts returns VALIDATION_ERROR; see Devices and Users for the limits.

The code vocabulary is open: handle unknown codes by falling back to the HTTP status.

Handling errors well​

  • Treat 4xx as actionable, 5xx as retryable. For 400, read error.code and, for field errors, details.errors[].field; for 401, refresh the token; for 403, check the service account's role. For 500, retry with exponential backoff.
  • Retry 429, not other 4xx. A 429 clears on its own: wait, then retry slowly. Do not retry 501: the operation is not available for that tenant or those objects.
  • Branch on error.code and HTTP status, not on message. The human-readable text can change.
note

Every endpoint returns this envelope for its own errors (401 and 429 excepted), including devices, users, user groups, device groups, cloud storage and User requests. The details object is populated on the policy and object endpoints; elsewhere the response carries error.code and error.message only.