From halopsa
Manages HaloPSA assets: tracking devices, configuration items, hardware lifecycle, and asset relationships with clients, sites, and RMM integration for MSP CMDB operations.
How this skill is triggered — by the user, by Claude, or both
Slash command
/halopsa:assetsWhen to use
When tracking devices, managing configuration items, hardware lifecycle, and asset relationships. Use when: halopsa asset, halo asset, configuration item halopsa, ci halopsa, device management halo, hardware tracking halopsa, halopsa cmdb, asset lifecycle, halo inventory, or halopsa device.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Assets (also called Configuration Items or CIs) in HaloPSA represent managed devices, software, and other trackable items. Effective asset management is crucial for MSPs to track what's deployed at client sites, manage hardware lifecycle, and link service tickets to affected equipment.
Assets (also called Configuration Items or CIs) in HaloPSA represent managed devices, software, and other trackable items. Effective asset management is crucial for MSPs to track what's deployed at client sites, manage hardware lifecycle, and link service tickets to affected equipment.
The primary entity representing a managed device or configuration item.
| Field | Type | Required | Description |
|---|---|---|---|
id | int | System | Unique identifier |
inventory_number | string | No | Internal asset tag |
client_id | int | Yes | Associated client |
site_id | int | No | Physical location |
user_id | int | No | Assigned user |
devicetype_id | int | No | Asset type category |
status_id | int | No | Asset status |
| Field | Type | Required | Description |
|---|---|---|---|
devicename | string(255) | Yes | Device hostname/name |
serialnumber | string | No | Manufacturer serial |
assettag | string | No | Company asset tag |
barcode | string | No | Barcode identifier |
macaddress | string | No | Network MAC address |
| Field | Type | Required | Description |
|---|---|---|---|
manufacturer | string | No | Device manufacturer |
model | string | No | Device model |
operatingsystem | string | No | OS name/version |
operatingsystemversion | string | No | OS detailed version |
ipaddress | string | No | IP address |
| Field | Type | Required | Description |
|---|---|---|---|
purchasedate | date | No | Date acquired |
purchaseprice | decimal | No | Purchase cost |
warrantyexpires | date | No | Warranty end date |
lastauditdate | datetime | No | Last RMM sync |
inactive | bool | No | Active status |
| Field | Type | Required | Description |
|---|---|---|---|
contract_id | int | No | Associated contract |
supplier_id | int | No | Vendor/supplier |
notes | text | No | Asset notes |
Common asset types in HaloPSA:
| Type ID | Name | Examples |
|---|---|---|
| 1 | Workstation | Desktop, laptop |
| 2 | Server | Physical/virtual server |
| 3 | Network Device | Router, switch, firewall |
| 4 | Printer | Network/local printer |
| 5 | Mobile Device | Phone, tablet |
| 6 | Software | License, subscription |
| 7 | Other | Miscellaneous |
Note: Asset types are configurable per instance. Query /api/AssetType for your values.
| Status ID | Name | Description |
|---|---|---|
| 1 | Active | In production use |
| 2 | Spare | Available backup |
| 3 | In Repair | Under maintenance |
| 4 | Retired | End of life |
| 5 | On Order | Pending delivery |
| 6 | Lost/Stolen | Missing |
Note: Status IDs are configurable per instance. Query /api/AssetStatus for your values.
POST /api/Asset
Authorization: Bearer {token}
Content-Type: application/json
[
{
"devicename": "ACME-WS-001",
"client_id": 123,
"site_id": 456,
"user_id": 789,
"devicetype_id": 1,
"status_id": 1,
"manufacturer": "Dell",
"model": "OptiPlex 7090",
"serialnumber": "ABC123XYZ",
"assettag": "ACME-001",
"operatingsystem": "Windows 11 Pro",
"operatingsystemversion": "22H2",
"ipaddress": "192.168.1.100",
"macaddress": "00:1A:2B:3C:4D:5E",
"purchasedate": "2024-01-15",
"purchaseprice": 1299.99,
"warrantyexpires": "2027-01-15"
}
]
{
"assets": [
{
"id": 5001,
"devicename": "ACME-WS-001",
"client_id": 123,
"client_name": "Acme Corporation",
"site_name": "Acme HQ",
"status_id": 1,
"status_name": "Active"
}
]
}
By client:
GET /api/Asset?client_id=123
By site:
GET /api/Asset?site_id=456
By type:
GET /api/Asset?devicetype_id=1
Active assets only:
GET /api/Asset?inactive=false
Search by name:
GET /api/Asset?search=ACME-WS
Warranty expiring soon:
GET /api/Asset?warrantyexpires_before=2024-03-31
GET /api/Asset/5001
With related data:
GET /api/Asset/5001?includedetails=true
POST /api/Asset
Authorization: Bearer {token}
Content-Type: application/json
[
{
"id": 5001,
"status_id": 3,
"notes": "Sent to vendor for motherboard repair"
}
]
[
{ "id": 5001, "status_id": 1 },
{ "id": 5002, "status_id": 1 },
{ "id": 5003, "status_id": 4, "inactive": true }
]
When creating or updating a ticket, reference the asset:
[
{
"summary": "Workstation not booting",
"client_id": 123,
"asset_id": 5001,
"tickettype_id": 1,
"status_id": 1
}
]
Parent-child relationships (e.g., server and its VMs):
[
{
"id": 5010,
"parent_id": 5009,
"notes": "VM hosted on ACME-SRV-001"
}
]
Track changes via the audit log or custom fields.
HaloPSA integrates with RMM tools to auto-sync assets.
When integrated with an RMM, these fields typically auto-populate:
devicenameoperatingsystemoperatingsystemversionipaddressmacaddresslastauditdate| Field | Description |
|---|---|
ncentral_device_id | N-central device ID |
datto_device_id | Datto RMM device ID |
connectwise_device_id | Automate device ID |
async function matchOrCreateAsset(rmmDevice) {
// 1. Try to match by RMM ID
let asset = await findAssetByRmmId(rmmDevice.id);
if (!asset) {
// 2. Try to match by serial number
asset = await findAssetBySerial(rmmDevice.serialNumber);
}
if (!asset) {
// 3. Try to match by hostname + client
asset = await findAssetByHostname(
rmmDevice.hostname,
rmmDevice.clientId
);
}
if (asset) {
// Update existing
return updateAsset(asset.id, rmmDevice);
} else {
// Create new
return createAsset(rmmDevice);
}
}
Create asset as "On Order"
[{ "devicename": "New Laptop", "status_id": 5, "client_id": 123 }]
Receive and configure
Deploy to user
user_id and site_idIdentify aging assets
GET /api/Asset?purchasedate_before=2020-01-01&inactive=false
Generate refresh report
Plan replacement
Find expiring warranties
GET /api/Asset?warrantyexpires_before=2024-06-30&warrantyexpires_after=2024-01-01
Generate renewal quotes
Update warranty dates after renewal
async function auditClientAssets(clientId) {
const assets = await getClientAssets(clientId);
const report = {
total: assets.length,
active: 0,
noWarranty: [],
missingSerial: [],
oldOS: []
};
assets.forEach(asset => {
if (!asset.inactive) report.active++;
if (!asset.warrantyexpires || new Date(asset.warrantyexpires) < new Date()) {
report.noWarranty.push(asset);
}
if (!asset.serialnumber) {
report.missingSerial.push(asset);
}
if (asset.operatingsystem?.includes('Windows 10') &&
new Date(asset.purchasedate) < new Date('2020-01-01')) {
report.oldOS.push(asset);
}
});
return report;
}
| Code | Message | Resolution |
|---|---|---|
| 400 | devicename required | Asset must have a name |
| 400 | client_id required | Asset must be linked to client |
| 400 | Invalid devicetype_id | Query /api/AssetType for valid IDs |
| 404 | Asset not found | Verify asset ID exists |
| 409 | Duplicate serial number | Serial already in use |
function validateAsset(asset) {
const errors = [];
if (!asset.devicename || asset.devicename.trim() === '') {
errors.push('Device name is required');
}
if (!asset.client_id) {
errors.push('Client ID is required');
}
if (asset.macaddress && !isValidMac(asset.macaddress)) {
errors.push('Invalid MAC address format');
}
if (asset.ipaddress && !isValidIP(asset.ipaddress)) {
errors.push('Invalid IP address format');
}
return {
isValid: errors.length === 0,
errors
};
}
GET /api/Asset?groupby=devicetype_id&count=true
GET /api/Asset?groupby=client_id&count=true
async function getAssetValueByClient() {
const clients = await fetchAllClients();
const results = [];
for (const client of clients) {
const assets = await getClientAssets(client.id);
const totalValue = assets.reduce(
(sum, a) => sum + (a.purchaseprice || 0), 0
);
results.push({
client_id: client.id,
client_name: client.name,
asset_count: assets.length,
total_value: totalValue
});
}
return results.sort((a, b) => b.total_value - a.total_value);
}
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin halopsaManages Syncro MSP assets including hardware, software, and devices. Covers asset fields, RMM integration, patch management, and inventory operations via the Syncro API.
Manages Hudu assets including CRUD operations, asset layout templates, custom fields, and linking assets to companies.
Queries and manages SuperOps.ai RMM assets including inventory, asset details, scripts, patches, and client/site associations. For MSP technicians managing endpoints.