This is a development version of the documentation. Content may change without notice.
Voke Documentation
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).

Codes

Generic

CodeHTTPDescription
BAD_REQUEST400Generic bad request; used when no more-specific 400 code applies.
VALIDATION_ERROR400Request body or query DTO failed class-validator validation.
INVALID_UUID400A path or query parameter that must be a UUID v4 is malformed.
NOT_FOUND404Generic not-found fallback; used when no more-specific 404 code applies.
CONFLICT409Generic conflict (e.g. duplicate unique constraint) when no more-specific code applies.
TOO_MANY_REQUESTS429Rate limit exceeded.
SERVICE_UNAVAILABLE503A downstream dependency (MQTT broker, queue, external ESM) is temporarily unreachable.
INTERNAL_SERVER_ERROR500Unhandled server error.

Auth (UNAUTHORIZED, FORBIDDEN, permissions)

CodeHTTPDescription
UNAUTHORIZED401Request lacks a valid JWT or the session has expired.
FORBIDDEN403Authenticated but not allowed to perform this action.
ORG_CONTEXT_REQUIRED403The x-org-id header is missing; the endpoint requires an active org context.
ORG_MEMBERSHIP_REQUIRED403The authenticated user is not a member of the org specified in x-org-id.
INSUFFICIENT_ORG_PERMISSIONS403The user's role within the org does not grant permission for this operation.
SUPER_ADMIN_REQUIRED403The endpoint is restricted to platform super-admins.

Auth flow (AUTH_*, EMAIL_*, ACCOUNT_*)

CodeHTTPDescription
INVALID_CREDENTIALS401Email/password combination is incorrect during login.
ACCOUNT_LOCKED403Account has been temporarily locked after too many failed login attempts.
EMAIL_ALREADY_REGISTERED409Registration or invite-accept was attempted with an email that already has an account.

Invitations (INVITATION_*)

CodeHTTPDescription
INVITATION_TOKEN_MISSING400An invite-based endpoint was called without an invitation token in the request.
INVITATION_NOT_FOUND404No pending invitation exists for the supplied token.
INVITATION_EXPIRED403The invitation token exists but has passed its expiry date.
INVITATION_ALREADY_ACCEPTED409The invitation has already been accepted and cannot be used again.

Organizations (ORGANIZATION_*, MEMBER_*)

CodeHTTPDescription
ORGANIZATION_NOT_FOUND404No organization found for the given ID or slug.
MEMBER_NOT_FOUND404No membership record found for the specified user within the target organization.

Plants (PLANT_*)

CodeHTTPDescription
PLANT_NOT_FOUND404No plant found for the given ID within the org context.
PLANT_ALREADY_EXISTS409A plant with the same unique identifier already exists in the organization.
PLANT_INVALID_STATE400The requested operation is not valid for the plant's current state (e.g. provisioning vs. active).
PLANT_NOT_LINKED_TO_ESM400The plant has no external_plant_id and cannot participate in ESM trading sync.

Device templates (DEVICE_TEMPLATE_*)

CodeHTTPDescription
DEVICE_TEMPLATE_NOT_FOUND404No device template found for the given ID within the org context.
DEVICE_TEMPLATE_IN_USE409Cannot delete a device template that is currently assigned to one or more sub-devices.
DEVICE_TEMPLATE_SIGNAL_INVALID400A signal definition in the template body failed Zod validation (check details for field paths).
DEVICE_TEMPLATE_ACTION_INVALID400An action definition in the template body failed Zod validation (check details for field paths).
DEVICE_TEMPLATE_SYSTEM_READONLY403The template is a system-level template and cannot be modified or deleted by org users.
DEVICE_TEMPLATE_WRONG_LEVEL400A plant-level assignment referenced a template whose level is not PLANT.

Sub-devices (SUB_DEVICE_*)

CodeHTTPDescription
SUB_DEVICE_NOT_FOUND404No sub-device found for the given ID within the plant context.
SUB_DEVICE_EXTERNAL_ID_TAKEN409Another sub-device in the same plant already uses the requested externalId.
SUB_DEVICE_EXTERNAL_ID_INVALID400The provided externalId does not match the required format (short alphanumeric, e.g. R1, M1).

Commands (COMMAND_*)

CodeHTTPDescription
COMMAND_ACTION_NOT_IN_TEMPLATE400The requested action key is not defined in the sub-device's device template.
COMMAND_PARAMS_INVALID400The command payload does not satisfy the action's parameter schema in the device template.

API keys (API_KEY_*)

CodeHTTPDescription
API_KEY_NOT_FOUND404No API key found for the given ID, or the key has been revoked.

Trading / ESM (TRADING_*, ESM_*)

CodeHTTPDescription
TRADING_NOT_ENABLED400The organization has not enabled the trading partner integration (reserved).
TRADING_CONFIG_INCOMPLETE400The trading partner configuration exists but is missing required credentials (client ID / secret / URL).
ESM_NOT_CONFIGURED400No ESM endpoint URL has been configured for this organization.
ESM_URL_NOT_ALLOWED400The provided ESM URL does not match the allowlist of permitted ESM host patterns (reserved).

Voke ESM (VOKE_ESM_*)

CodeHTTPDescription
VOKE_ESM_DISABLEDStartup-only guard thrown when VOKE_ESM_ENABLED is absent in production. Never emitted on HTTP responses; only appears in API boot logs.

On this page