svix-id, svix-timestamp, and svix-signature headers, not in the body. There is no event or data envelope to unwrap: a field like command sits at the top level, so you read body.command, never body.data.command.
Device connection events
Connection events track a device’s link to your account. They carry the device identifiers plus atimestamp, and device.disconnected adds a reconnectionUrl when the OEM’s auth flow supports re-entry.
device.connected
Fires when a new device finishes registration through the Auth Journey.
device.reconnected
Fires when an already-registered device’s credentials are refreshed.
device.disconnected
Fires when stored credentials become invalid. The body carries a reconnectionUrl pointing at the Auth Journey in reconnection mode when the OEM’s auth flow supports re-entry.
Action events
Webhooks are only sent for actions that reach a terminal state (completed or failed). When an action is first created, it starts in the acknowledged state, but no webhook is sent at that time. You can check the action status by polling the API at GET /actions/{actionId} (one device-agnostic route for every device type), but webhooks are only delivered when the action completes or fails.
push.completed
Fires when an action completes successfully. This webhook is only sent when the action reaches the completed terminal state. The body mirrors the dispatch and the read response: the canonical command, the constraints-only parameters, the clean deviceType, and a result.
push.failed
Fires when an action fails to complete. This webhook is only sent when the action reaches the failed terminal state. The body adds top-level errorCode and errorMessage, and result carries the OEM error envelope (result.success is false).
Action states
When you send a push command via the API, the action goes through the following states:acknowledged- The action has been created and is being processed immediately. No webhook is sent at this stage.scheduled- The action has astarttime and will execute at that time. Scheduled actions (battery, EV charger, or HVAC) can be cancelled viaPOST /actions/{actionId}/cancel.completed- The action completed successfully. Apush.completedwebhook is sent.failed- The action failed to complete. Apush.failedwebhook is sent.cancelled- The action was cancelled before execution. No webhook is sent.
Common error codes
Device is currently offline and cannot receive commands
The requested command is not supported by this device model
The command timed out waiting for device response
Too many commands sent to the device in a short period
Authentication with the OEM failed
Webhook payload fields
The body is flat. These are the top-level fields a push event carries.Identifier of the action that reached a terminal state. Dedupe push events by this value, or by the
svix-id header.Identifier of the device the action targeted.
The clean device type, for example
battery, hvac, or ev_charger.The canonical command that was dispatched, for example
charge or auto.balanced.The constraints-only parameters for the command, or
null.The OEM result envelope.
result.success is true on push.completed and false on push.failed.ISO 8601 timestamp for the terminal transition on a
push.completed event.Machine-readable failure code, present on
push.failed.Human-readable failure description, present on
push.failed.ISO 8601 timestamp for the terminal transition on a
push.failed event.Handling webhooks
Idempotency
The per-delivery ID arrives in thesvix-id header. Use it as the idempotency key to drop duplicates. Push events can also be deduped by actionId.
Response requirements
Your webhook endpoint must:- Return
200 OKfor successful processing - Respond within 30 seconds
- Handle duplicate deliveries gracefully
Next steps
Webhook Overview
Learn about webhook setup
Security
Verify webhook signatures