This is a development version of the documentation. Content may change without notice.
Voke Documentation
ReferenceREST API

Sub Devices

Plant-scoped physical components and decoded telemetry

List sub-devices for a plant

GET
/api/v1/plants/{plantId}/sub-devices

Path Parameters

plantId*string

Query Parameters

page?number

Page number (1-indexed)

Default1
Range1 <= value
limit?number

Items per page

Default20
Range1 <= value <= 100
type?string
Value in"CABINET" | "METER" | "INVERTER" | "BATTERY"
status?string
Value in"ONLINE" | "OFFLINE" | "DEGRADED" | "UNKNOWN"
search?string

Search externalId, name or serial number

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://loading/api/v1/plants/string/sub-devices"
{
  "data": [
    {
      "createdAt": "2019-08-24T14:15:22Z",
      "externalId": "string",
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "lastSeenAt": "2019-08-24T14:15:22Z",
      "metadata": {},
      "name": "string",
      "organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
      "plantId": "bb17678d-82fa-43da-92e5-df833ebe5344",
      "serialNumber": "string",
      "status": "ONLINE",
      "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",
      "type": "CABINET",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "meta": {
    "limit": 0,
    "page": 0,
    "total": 0,
    "totalPages": 0
  }
}
{
  "code": "VALIDATION_ERROR",
  "details": {},
  "error": "Bad Request",
  "message": "Invalid UUID or query parameters",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "PLANT_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Plant not found",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}

Create a sub-device under a plant

POST
/api/v1/plants/{plantId}/sub-devices

Path Parameters

plantId*string

Request Body

application/json

externalId*string

Short, URL-safe, unique-per-plant identifier (e.g. "R1", "E2", "M1")

MatchEXTERNAL_ID_REGEX
metadata?
name*string

Operator-assigned display name

Lengthlength <= 255
serialNumber?string

Physical hardware serial (audit only)

Lengthlength <= 64
templateId?string

Device template to decode payloads with

Formatuuid
type*string
Value in"CABINET" | "METER" | "INVERTER" | "BATTERY"

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://loading/api/v1/plants/string/sub-devices" \  -H "Content-Type: application/json" \  -d '{    "externalId": "R1",    "name": "string",    "type": "CABINET"  }'
{
  "createdAt": "2019-08-24T14:15:22Z",
  "externalId": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "lastSeenAt": "2019-08-24T14:15:22Z",
  "metadata": {},
  "name": "string",
  "organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
  "plantId": "bb17678d-82fa-43da-92e5-df833ebe5344",
  "serialNumber": "string",
  "status": "ONLINE",
  "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",
  "type": "CABINET",
  "updatedAt": "2019-08-24T14:15:22Z"
}
{
  "code": "VALIDATION_ERROR",
  "details": {},
  "error": "Bad Request",
  "message": "Invalid payload or externalId format",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "PLANT_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Plant or template not found",
  "statusCode": 400
}
{
  "code": "SUB_DEVICE_EXTERNAL_ID_TAKEN",
  "details": {},
  "error": "Conflict",
  "message": "externalId already taken within this plant",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}

Get a single sub-device by its externalId

GET
/api/v1/plants/{plantId}/sub-devices/{externalId}

Path Parameters

plantId*string
externalId*string

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://loading/api/v1/plants/string/sub-devices/string"
{
  "createdAt": "2019-08-24T14:15:22Z",
  "externalId": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "lastSeenAt": "2019-08-24T14:15:22Z",
  "metadata": {},
  "name": "string",
  "organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
  "plantId": "bb17678d-82fa-43da-92e5-df833ebe5344",
  "serialNumber": "string",
  "status": "ONLINE",
  "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",
  "type": "CABINET",
  "updatedAt": "2019-08-24T14:15:22Z"
}
{
  "code": "INVALID_UUID",
  "details": {},
  "error": "Bad Request",
  "message": "Invalid UUID",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "SUB_DEVICE_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Sub-device or plant not found",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}

Update a sub-device

PATCH
/api/v1/plants/{plantId}/sub-devices/{externalId}

Path Parameters

plantId*string
externalId*string

Request Body

application/json

metadata?
name?string
Lengthlength <= 255
serialNumber?|
Lengthlength <= 64
templateId?|
Formatuuid

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PATCH "https://loading/api/v1/plants/string/sub-devices/string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "createdAt": "2019-08-24T14:15:22Z",
  "externalId": "string",
  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  "lastSeenAt": "2019-08-24T14:15:22Z",
  "metadata": {},
  "name": "string",
  "organizationId": "7bc05553-4b68-44e8-b7bc-37be63c6d9e9",
  "plantId": "bb17678d-82fa-43da-92e5-df833ebe5344",
  "serialNumber": "string",
  "status": "ONLINE",
  "templateId": "196100ac-4eec-4fb6-a7f7-86c8b584771d",
  "type": "CABINET",
  "updatedAt": "2019-08-24T14:15:22Z"
}
{
  "code": "VALIDATION_ERROR",
  "details": {},
  "error": "Bad Request",
  "message": "Invalid payload",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "SUB_DEVICE_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Sub-device not found",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}

Delete a sub-device

DELETE
/api/v1/plants/{plantId}/sub-devices/{externalId}

Path Parameters

plantId*string
externalId*string

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X DELETE "https://loading/api/v1/plants/string/sub-devices/string"
{
  "message": "string"
}
{
  "code": "INVALID_UUID",
  "details": {},
  "error": "Bad Request",
  "message": "Invalid UUID",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "SUB_DEVICE_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Sub-device not found",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}

Send a command to a sub-device via its parent plant

POST
/api/v1/plants/{plantId}/sub-devices/{externalId}/commands

Path Parameters

plantId*string
externalId*string

Request Body

application/json

action*string

Action key (must match one declared in the device template)

Lengthlength <= 64
params?

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://loading/api/v1/plants/string/sub-devices/string/commands" \  -H "Content-Type: application/json" \  -d '{    "action": "string"  }'
{
  "message": "string"
}
{
  "code": "COMMAND_ACTION_NOT_IN_TEMPLATE",
  "details": {},
  "error": "Bad Request",
  "message": "Action not in template or invalid params",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "SUB_DEVICE_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Sub-device or plant not found",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}

Snapshot of the latest decoded signal values

GET
/api/v1/plants/{plantId}/sub-devices/{externalId}/signals/latest

Path Parameters

plantId*string
externalId*string

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://loading/api/v1/plants/string/sub-devices/string/signals/latest"
{
  "metric": "string",
  "time": "2019-08-24T14:15:22Z",
  "unit": "string",
  "value": 0
}
{
  "code": "INVALID_UUID",
  "details": {},
  "error": "Bad Request",
  "message": "Invalid UUID",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "SUB_DEVICE_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Sub-device not found",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}

Historical telemetry for a sub-device (auto-selects CAGG)

GET
/api/v1/plants/{plantId}/sub-devices/{externalId}/telemetry

Path Parameters

plantId*string
externalId*string

Query Parameters

from*string

ISO start timestamp

Formatdate-time
to*string

ISO end timestamp

Formatdate-time
metric?string

Filter by metric key (signal key)

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://loading/api/v1/plants/string/sub-devices/string/telemetry?from=2019-08-24T14%3A15%3A22Z&to=2019-08-24T14%3A15%3A22Z"
{
  "avgValue": 0,
  "bucket": "2019-08-24T14:15:22Z",
  "count": 0,
  "maxValue": 0,
  "metric": "string",
  "minValue": 0
}
{
  "code": "VALIDATION_ERROR",
  "details": {},
  "error": "Bad Request",
  "message": "Invalid time range",
  "statusCode": 400
}
{
  "code": "UNAUTHORIZED",
  "details": {},
  "error": "Unauthorized",
  "message": "Unauthorized",
  "statusCode": 400
}
{
  "code": "FORBIDDEN",
  "details": {},
  "error": "Forbidden",
  "message": "Forbidden",
  "statusCode": 400
}
{
  "code": "SUB_DEVICE_NOT_FOUND",
  "details": {},
  "error": "Not Found",
  "message": "Sub-device not found",
  "statusCode": 400
}
{
  "code": "INTERNAL_SERVER_ERROR",
  "details": {},
  "error": "Internal Server Error",
  "message": "Internal server error",
  "statusCode": 400
}