Reference
Error Codes Canonical list of every ApiErrorCode returned by the Voke API.
Voke returns a stable error envelope on every 4xx/5xx:
{
"statusCode" : 400 ,
"message" : "human-readable summary" ,
"error" : "Bad Request" ,
"code" : "DEVICE_TEMPLATE_SIGNAL_INVALID" ,
"details" : [ "signals.0.bit: must be an integer >= 0" ]
}
The code field is the stable machine-readable contract — prefer it over message when handling errors programmatically. details is optional and may be an array of strings or a structured object depending on the error source.
HTTP status codes follow the NestJS exception convention (400 = BadRequestException, 401 = UnauthorizedException, 403 = ForbiddenException, 404 = NotFoundException, 409 = ConflictException, 429 = TooManyRequestsException, 503 = ServiceUnavailableException, 500 = InternalServerErrorException).
Code HTTP Description BAD_REQUEST400 Generic bad request; used when no more-specific 400 code applies. VALIDATION_ERROR400 Request body or query DTO failed class-validator validation. INVALID_UUID400 A path or query parameter that must be a UUID v4 is malformed. NOT_FOUND404 Generic not-found fallback; used when no more-specific 404 code applies. CONFLICT409 Generic conflict (e.g. duplicate unique constraint) when no more-specific code applies. TOO_MANY_REQUESTS429 Rate limit exceeded. SERVICE_UNAVAILABLE503 A downstream dependency (MQTT broker, queue, external ESM) is temporarily unreachable. INTERNAL_SERVER_ERROR500 Unhandled server error.
Code HTTP Description UNAUTHORIZED401 Request lacks a valid JWT or the session has expired. FORBIDDEN403 Authenticated but not allowed to perform this action. ORG_CONTEXT_REQUIRED403 The x-org-id header is missing; the endpoint requires an active org context. ORG_MEMBERSHIP_REQUIRED403 The authenticated user is not a member of the org specified in x-org-id. INSUFFICIENT_ORG_PERMISSIONS403 The user's role within the org does not grant permission for this operation. SUPER_ADMIN_REQUIRED403 The endpoint is restricted to platform super-admins.
Code HTTP Description INVALID_CREDENTIALS401 Email/password combination is incorrect during login. ACCOUNT_LOCKED403 Account has been temporarily locked after too many failed login attempts. EMAIL_ALREADY_REGISTERED409 Registration or invite-accept was attempted with an email that already has an account.
Code HTTP Description INVITATION_TOKEN_MISSING400 An invite-based endpoint was called without an invitation token in the request. INVITATION_NOT_FOUND404 No pending invitation exists for the supplied token. INVITATION_EXPIRED403 The invitation token exists but has passed its expiry date. INVITATION_ALREADY_ACCEPTED409 The invitation has already been accepted and cannot be used again.
Code HTTP Description ORGANIZATION_NOT_FOUND404 No organization found for the given ID or slug. MEMBER_NOT_FOUND404 No membership record found for the specified user within the target organization.
Code HTTP Description PLANT_NOT_FOUND404 No plant found for the given ID within the org context. PLANT_ALREADY_EXISTS409 A plant with the same unique identifier already exists in the organization. PLANT_INVALID_STATE400 The requested operation is not valid for the plant's current state (e.g. provisioning vs. active). PLANT_NOT_LINKED_TO_ESM400 The plant has no external_plant_id and cannot participate in ESM trading sync.
Code HTTP Description DEVICE_TEMPLATE_NOT_FOUND404 No device template found for the given ID within the org context. DEVICE_TEMPLATE_IN_USE409 Cannot delete a device template that is currently assigned to one or more sub-devices. DEVICE_TEMPLATE_SIGNAL_INVALID400 A signal definition in the template body failed Zod validation (check details for field paths). DEVICE_TEMPLATE_ACTION_INVALID400 An action definition in the template body failed Zod validation (check details for field paths). DEVICE_TEMPLATE_SYSTEM_READONLY403 The template is a system-level template and cannot be modified or deleted by org users. DEVICE_TEMPLATE_WRONG_LEVEL400 A plant-level assignment referenced a template whose level is not PLANT.
Code HTTP Description SUB_DEVICE_NOT_FOUND404 No sub-device found for the given ID within the plant context. SUB_DEVICE_EXTERNAL_ID_TAKEN409 Another sub-device in the same plant already uses the requested externalId. SUB_DEVICE_EXTERNAL_ID_INVALID400 The provided externalId does not match the required format (short alphanumeric, e.g. R1, M1).
Code HTTP Description COMMAND_ACTION_NOT_IN_TEMPLATE400 The requested action key is not defined in the sub-device's device template. COMMAND_PARAMS_INVALID400 The command payload does not satisfy the action's parameter schema in the device template.
Code HTTP Description API_KEY_NOT_FOUND404 No API key found for the given ID, or the key has been revoked.
Code HTTP Description TRADING_NOT_ENABLED400 The organization has not enabled the trading partner integration (reserved). TRADING_CONFIG_INCOMPLETE400 The trading partner configuration exists but is missing required credentials (client ID / secret / URL). ESM_NOT_CONFIGURED400 No ESM endpoint URL has been configured for this organization. ESM_URL_NOT_ALLOWED400 The provided ESM URL does not match the allowlist of permitted ESM host patterns (reserved).
Code HTTP Description VOKE_ESM_DISABLED— Startup-only guard thrown when VOKE_ESM_ENABLED is absent in production. Never emitted on HTTP responses; only appears in API boot logs.