xPlantAPI
API referenceDevices

Record a device event

Records something that happened on a device — an alert, an error, a firmware update or a configuration change — with whatever detail you put in payload. Send it with the device's own token, which may only write about that device, or with a workspace key.

POST/api/v1/device-events
Scope write:device_eventsAccepts a device token

Events are not deduplicated: a request retried after a dropped response is recorded twice.

Request body

FieldTypeRequiredDescription
device_idstring (uuid)YesThe device the event is about.
event_type"heartbeat" | "alert" | "firmware_update" | "config_change" | "error" | "other"YesWhat kind of event this is.
payloadobjectNoAny JSON object describing the event. Default {}.
occurred_atstring (date-time)NoWhen it happened, as an ISO 8601 timestamp in UTC ending in Z. Defaults to the time the request arrives.

Example

curl -X POST https://app.xplantpro.com/api/v1/device-events \
  -H "Authorization: Bearer $XPLANT_DEVICE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": "8e3b1f52-6c0d-4a7e-9b21-5f4d8c2a7e13",
    "event_type": "alert",
    "payload": {
      "reason": "humidity_high",
      "humidity_percent": 94
    },
    "occurred_at": "2026-09-25T13:58:00.000Z"
  }'

Response

201 with { "ok": true, "data": … }. data holds the result.

FieldTypeRequiredDescription
idstring (uuid)Yes—
device_idstring (uuid)Yes—
team_idstring (uuid)YesThe id of the workspace the event belongs to.
event_typestringYesOne of heartbeat, alert, firmware_update, config_change, error, other.
payloadobjectYes—
occurred_atstringYesWhen it happened, as an ISO 8601 timestamp.
created_atstringYes—
Response
{
  "ok": true,
  "data": {
    "id": "c7d2a9e4-1b6f-4c3a-8e5d-0f9b2a7c4e61",
    "device_id": "8e3b1f52-6c0d-4a7e-9b21-5f4d8c2a7e13",
    "team_id": "5d2e8b17-9c4a-4e3f-b6d0-1a7c9e2f4b83",
    "event_type": "alert",
    "payload": {
      "reason": "humidity_high",
      "humidity_percent": 94
    },
    "occurred_at": "2026-09-25T13:58:00.000Z",
    "created_at": "2026-09-25T13:58:01.000Z"
  }
}
Response headerMeaning
X-Request-IdIdentifies this request. Include it when you contact support.

Errors

StatusCodeWhen
400VALIDATION_ERRORThe request body is not valid JSON.
401UNAUTHORIZEDThe key is missing, malformed or revoked, or its owner is no longer a member of the workspace.
402PAID_PLAN_REQUIREDThe workspace has no paid plan. Connecting devices is included with every paid plan.
403FORBIDDENThe key lacks a scope this operation requires, or its owner's current role in the workspace cannot use it — a key never does more than its owner can in xPlant. error names the scope, and for a role, the role it needs.
403DEVICE_TOKEN_WRONG_DEVICEA device token was used to write about a device other than its own.
404NOT_FOUNDdevice_id does not name a device in the workspace.
422VALIDATION_ERRORA field failed validation. error names the first one, for example event_type: Invalid enum value.
429RATE_LIMIT_EXCEEDEDToo many requests for this key, device token or workspace. Wait Retry-After seconds.
500DEVICE_EVENT_CREATE_FAILEDThe event could not be saved. Retry later.

Branch on code, never on the error text. See Errors.

On this page