Interacting with the Leverege API
Overview
The Leverege API allows you to programmatically interact with projects, devices, blueprints, users, and other resources in the Leverege Stack. This guide covers authentication, common operations, and real-world patterns for internal development.
Note: For Python, ensure you’re using a compatible version. Version 0.3.x and 1.0.x are not compatible with each other.
How to Authenticate
Method 1: API Key/Secret with JWT (Recommended)
This is the recommended approach for backend services and scripts. API keys don’t expire and can be scoped to specific permissions.
Step 1: Generate API credentials
In Architect, go to Settings > Add Api Access to create an API key and secret.
Step 2: Initialize the API client (Node.js)
const Api = require('@leverege/api')
const api = Api.init({
host: 'https://dev-projectname-imagine-api.leverege.com',
apiKey: 'YOUR_API_KEY',
secret: 'YOUR_API_SECRET'
})
Step 3: Create a JWT for direct REST calls
If you need to make raw HTTP requests (e.g., from Postman or a non-JS service), generate a JWT:
const JWT = require('jsonwebtoken')
const apiAccess = {
id: 'YOUR_API_KEY',
secret: 'YOUR_API_SECRET'
}
function createAuthToken() {
const payload = {
type: 'apiAccess',
iss: apiAccess.id,
prj: 'YOUR_PROJECT_ID', // e.g., '1Je8Y7dNlfthv7ixV8oEfZ'
aud: 'https://prd-projectname-imagine-api.leverege.com'
}
const jwt = JWT.sign(payload, apiAccess.secret, { expiresIn: '1h' })
return `Bearer ${jwt}`
}
Method 2: Username/Password
Use this for scripts that run as a specific user. Tokens expire after 24 hours.
const Api = require('@leverege/api')
const api = Api.init({
host: 'https://dev-projectname-imagine-api.leverege.com'
})
// Login returns a token valid for 24 hours
await api.login(username, password, projectId)
Important: Users must have explicit permissions on systems or devices to access data.
How to Get Devices
Get a single device by ID
const device = await api.device(deviceId).get()
The response includes both header data (id, name, blueprintId) and device data.
Get a device with project context
const device = await api.project(projectId).device(deviceId).get()
Get device metadata
Device metadata includes timestamps for when each field was last updated:
const device = await api.device(deviceId).get()
// Metadata is available at device.dataMetadata
// Each field has: { source: { userId }, updated: <timestamp> }
console.log(device.dataMetadata)
How to Search Devices
The interface method searches devices by blueprint within a system.
Basic search
const { items, total } = await api
.interface(systemId, 'blueprintName')
.search({
limit: 100,
offset: 0
})
Search with equals filter
const { items } = await api.interface(systemId, 'vehicle').search({
filter: {
type: 'equals',
field: 'data/status',
value: 'active'
}
})
Search with multiple conditions (AND)
const { items } = await api.interface(systemId, 'sensor').search({
filter: {
type: 'logical',
operator: 'and',
conditions: [
{
type: 'equals',
field: 'data/type',
value: 'temperature'
},
{
type: 'comparison',
field: 'data/reading',
comparator: '>',
value: 100
}
]
}
})
Search by network alias
const { items } = await api.interface(systemId, 'device').search({
filter: {
type: 'equals',
field: 'networkAliases/networkName/deviceId',
value: 'DEVICE-123'
}
})
Search with regex pattern
const { items } = await api.interface(systemId, 'inventory').search({
filter: {
type: 'expression',
kind: 'regexp',
field: 'data/name',
value: 'Quinn.*',
ignoreCase: true
}
})
Search with wildcard
const { items } = await api.interface(systemId, 'tag').search({
filter: {
type: 'expression',
kind: 'queryString',
analyzeWildcard: true,
field: 'data/uniqueDeviceId',
value: 'ZSD-TAG*'
}
})
Search with date range
const { items } = await api.interface(systemId, 'service').search({
filter: {
type: 'comparison',
field: 'data/createdAt',
comparator: '[]', // between
value1: '2024-01-01T00:00:00.000Z',
value2: '2024-12-31T23:59:59.999Z',
isDate: true,
timezone: 'America/New_York'
}
})
Search for field existence
const { items } = await api.interface(systemId, 'task').search({
filter: {
type: 'exists',
field: 'data/completedAt',
not: true // Find devices where field does NOT exist
}
})
How to Search Related Devices
Search within a parent-child relationship:
// Get all children of a specific parent
const { items } = await api
.interface(systemId, 'parentBlueprint')
.obj(parentDeviceId)
.grp('childRelationshipName')
.search({
limit: 100
})
// Example: Get all geofences for a boat
const { items: geofences } = await api
.interface(systemId, 'boat')
.obj(boatId)
.grp('geofence')
.search()
How to Create Devices
Create a standalone device
const newDevice = await api
.interface(systemId, 'blueprintName')
.create({
name: 'My New Device',
data: {
field1: 'value1',
field2: 123
}
})
Create a device as a child of another device
const childDevice = await api
.interface(systemId, 'parentBlueprint')
.obj(parentDeviceId)
.grp('childRelationshipName')
.create({
name: 'Child Device',
data: { /* device data */ }
})
// Example: Create a geofence for a boat
await api
.interface(systemId, 'boat')
.obj(boatId)
.grp('geofence')
.create(geofenceData)
How to Update Devices
Update device data
await api.device(deviceId).update({
data: {
status: 'inactive',
lastUpdated: Date.now()
}
})
Wait for data to be written (transponder-write-await)
For cases where you need to confirm data was persisted:
await api.device(deviceId).update(
{ data: { /* updates */ } },
{
resolveOnWrite: true // Wait for RT transponder (ES + Firebase)
}
)
// Or specify which transponders to wait for:
await api.device(deviceId).update(
{ data: { /* updates */ } },
{
resolveOnWrite: {
writers: ['rt', 'timescale'],
maxWaitTime: 5000 // ms
}
}
)
How to Work with Blueprints
List all blueprints in a project
const { items: blueprints } = await api
.project(projectId)
.blueprints()
.list()
Get a specific blueprint
const blueprint = await api.blueprint(blueprintId).get()
How to Work with Users and Permissions
List project users
const { items: users } = await api
.project(projectId)
.accounts()
.list({
perPage: 100,
role: { name: 'RoleName', projectId }
})
Get a user’s roles on a device
const roles = await api
.project(projectId)
.account(userId)
.roles()
List users on a device
const { items: users } = await api