Skip to main content

RESTful API

The RESTful API uses header-based authentication and resource-oriented URLs. Use it for backend jobs, services, and production-grade integrations.

Plan requirement

RESTful API access requires a Pro plan or higher.

Base URL

https://app.vwire.io/external/api/v1

Authentication

Create a User API Key in Dashboard -> Account -> API Keys -> New API Key.

Use that key on every request through the X-API-Key header:

X-API-Key: vwk_7f3a1c9e2b844d6fa913c5e28f01b774

User API keys are prefixed with vwk_.


GET /devices — List all devices

GET /external/api/v1/devices
X-API-Key: vwk_xxx
Query paramTypeDescription
limitnumberMax results (default: 50, max: 100)
offsetnumberPagination offset (default: 0)
onlinetrue | falseFilter by online status

Response:

{
"success": true,
"data": [
{
"id": "uuid",
"name": "Greenhouse Sensor",
"description": null,
"hardwareType": "ESP32",
"isOnline": true,
"lastSeenAt": "2026-03-18T10:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z"
}
],
"meta": { "total": 5, "limit": 50, "offset": 0 }
}

GET /devices/:id — Get device details

GET /external/api/v1/devices/{deviceId}
X-API-Key: vwk_xxx

Response:

{
"success": true,
"data": {
"id": "uuid",
"name": "Greenhouse Sensor",
"description": null,
"hardwareType": "ESP32",
"isOnline": true,
"lastSeenAt": "2026-03-18T10:00:00.000Z",
"createdAt": "2026-01-01T00:00:00.000Z"
}
}

GET /devices/:id/pins — Get all pins

GET /external/api/v1/devices/{deviceId}/pins
X-API-Key: vwk_xxx

Response:

{
"success": true,
"data": [
{ "pin": "V0", "value": "23.5", "label": "Temperature", "updatedAt": "2026-03-18T10:00:00.000Z" },
{ "pin": "V1", "value": "1", "label": "Relay", "updatedAt": "2026-03-18T09:55:00.000Z" }
]
}

GET /devices/:id/pins/:pin — Get a single pin

GET /external/api/v1/devices/{deviceId}/pins/V0
X-API-Key: vwk_xxx

Response:

{
"success": true,
"data": {
"pin": "V0",
"value": "23.5",
"label": "Temperature",
"updatedAt": "2026-03-18T10:00:00.000Z"
}
}

PUT /devices/:id/pins/:pin — Set a pin value

PUT /external/api/v1/devices/{deviceId}/pins/V0
X-API-Key: vwk_xxx
Content-Type: application/json

{ "value": "25.0" }

Response:

{
"success": true,
"data": {
"pin": "V0",
"value": "25.0",
"delivered": true,
"updatedAt": "2026-03-18T10:05:00.000Z"
}
}

PATCH /devices/:id/pins — Batch update pins

PATCH /external/api/v1/devices/{deviceId}/pins
X-API-Key: vwk_xxx
Content-Type: application/json

{
"pins": [
{ "pin": "V0", "value": "25.0" },
{ "pin": "V1", "value": "0" }
]
}

Max 50 pins per request. Protected pins are skipped and returned with delivered: false.

Response:

{
"success": true,
"data": {
"updated": 2,
"results": [
{ "pin": "V0", "delivered": true },
{ "pin": "V1", "delivered": true }
]
}
}

GET /devices/:id/status — Device status

GET /external/api/v1/devices/{deviceId}/status
X-API-Key: vwk_xxx

Response:

{
"success": true,
"data": {
"deviceId": "uuid",
"isOnline": true,
"lastSeenAt": "2026-03-18T10:00:00.000Z",
"hardwareType": "ESP32",
"firmwareVersion": "1.2.0",
"ipAddress": "192.168.1.100"
}
}

GET /devices/:id/history/:pin — Pin history

GET /external/api/v1/devices/{deviceId}/history/V0
X-API-Key: vwk_xxx
Query paramDescription
fromStart date in ISO 8601 format
toEnd date in ISO 8601 format
limitMax data points (default: 100, max: 1000)

Response:

{
"success": true,
"data": [
{ "value": "23.5", "timestamp": "2026-03-18T10:00:00.000Z" },
{ "value": "22.8", "timestamp": "2026-03-18T09:55:00.000Z" }
],
"meta": { "count": 2, "pin": "V0" }
}

POST /devices/:id/notify — Send notification

POST /external/api/v1/devices/{deviceId}/notify
X-API-Key: vwk_xxx
Content-Type: application/json

{
"title": "Alert",
"message": "Temperature exceeded 30°C",
"priority": "high"
}

Response:

{
"success": true,
"data": { "notificationId": "uuid" }
}

Errors and rate limits

All errors follow this shape:

{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid or expired API key."
}
}
HTTPCodeMeaning
400INVALID_PIN / VALUE_TOO_LONGRequest payload is invalid
401MISSING_API_KEY / INVALID_API_KEYInvalid API key
403PLAN_FEATURE_UNAVAILABLEPlan upgrade required
403PIN_LOCKEDPin is protected by a Keypad widget lock
404DEVICE_NOT_FOUNDDevice not found or not owned by the API key owner
404PIN_NOT_FOUNDPin has no recorded value
429RATE_LIMIT_EXCEEDEDToo many requests

Rate limit headers are included on every response:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1710756060
PlanRequests per minuteRequests per day
FreeNo access
Pro6010,000
Pro Plus300100,000
Enterprise1,000Unlimited

Example

const deviceId = "your-device-uuid";
const apiKey = "vwk_your_api_key";

await fetch(`https://app.vwire.io/external/api/v1/devices/${deviceId}/pins/V0`, {
method: "PUT",
headers: {
"X-API-Key": apiKey,
"Content-Type": "application/json"
},
body: JSON.stringify({ value: "25.0" })
});