This document describes the REST API endpoints available in the Kaizely application.
Kaizely API supports two authentication methods that can be used interchangeably:
API keys provide long-lived, revocable credentials ideal for machine-to-machine communication such as Kepware, PLCs, and SCADA systems.
Include the API key in the X-API-Key header for authenticated requests:
X-API-Key: kzly_your_api_key_here
curl -X POST https://kaizely.com/api/AssetDowntimeTracker/offline \
-H "X-API-Key: kzly_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"assetId": 123, "reasonName": "Planned Maintenance"}'
JWT tokens are ideal for user-driven applications and short-lived sessions.
Authenticate and receive a JWT token.
{
"username": "string",
"password": "string"
}
{
"token": "jwt_token_here",
"expiration": "2025-12-27T09:42:11.0000000Z"
}
No authentication required
Include the token in the Authorization header for authenticated requests:
Authorization: Bearer your_jwt_token_here
JWT tokens expire after 1 hour by default. You'll need to refresh or re-authenticate after expiration.
Manage assets within an organization.
Get all assets for the user's organization. Optional query parameter: onlineOnly=true
Authentication Required: API Key or JWT Bearer Token
Get a specific asset by ID.
JWT Authentication Required
Get assets by code (case-insensitive).
JWT Authentication Required
Create a new asset.
{
"name": "string",
"code": "string",
"description": "string",
"parentId": number,
"assetType": number,
"sortOrder": number,
"isOnline": boolean
}
JWT Authentication Required
Update an existing asset.
{
"name": "string",
"code": "string",
"description": "string",
"parentId": number,
"assetType": number,
"sortOrder": number,
"isOnline": boolean
}
JWT Authentication Required
Delete an asset. Requires SiteAdmin role.
JWT Authentication Required (SiteAdmin role)
Manage losses within an organization.
Get all losses for the user's organization.
JWT Authentication Required
Get a specific loss by ID.
JWT Authentication Required
Create a new loss.
JWT Authentication Required
Update an existing loss.
JWT Authentication Required
Delete a loss.
JWT Authentication Required
Manage daily machine quality losses (QualityLossDaily) within an organization.
Get quality loss daily rows for the user's organization. Optional filters:
start (date)end (date)assetId (int)defectModeId (int)JWT Authentication Required
Get a specific quality loss daily row by ID.
JWT Authentication Required
Create a new quality loss daily row. OrgId is forced server-side.
{
"assetId": 123,
"defectModeId": 1,
// OR (if defectModeId is not provided)
// "defectModeName": "rework",
"day": "2025-12-31",
"occurrences": 2,
"externalSource": "MES",
"externalId": "abc-123"
}
Note: You can provide either defectModeId or defectModeName. If defectModeId is missing/0 and defectModeName is provided, the server will look up the defect mode by name (case-insensitive, org-scoped). If the name is unknown, the API returns 400 BadRequest.
Note: If TotalCost is not supplied, the server calculates it from AssetDefectModeCost (or UnitCostOverride if provided).
JWT Authentication Required
Update an existing quality loss daily row. Row must belong to the caller's organization.
JWT Authentication Required
Delete a quality loss daily row. Row must belong to the caller's organization.
JWT Authentication Required
Manage loss types within an organization.
Get all loss types for the user's organization.
JWT Authentication Required
Get a specific loss type by ID.
JWT Authentication Required
Create a new loss type.
{
"name": "string"
}
JWT Authentication Required
Update an existing loss type.
{
"id": number,
"name": "string"
}
JWT Authentication Required
Delete a loss type.
JWT Authentication Required
Track asset downtime. Perfect for Kepware integration!
Get a downtime tracking record by ID.
Authentication Required: API Key or JWT Bearer Token
Get all assets currently offline for the user's organization.
Authentication Required: API Key or JWT Bearer Token
Set an asset offline and start downtime tracking. Ideal for Kepware/PLC integration.
{
"assetId": number, // Required: ID of the asset to set offline
"reasonId": number, // Optional: ID of downtime reason (preferred if provided)
"reasonName": "string", // Optional: Name of downtime reason (case-insensitive, used if reasonId not provided)
"startTimeUtc": "datetime" // Optional: Start time (defaults to current UTC time if not provided)
}
Note: Either reasonId or reasonName can be provided, but reasonId is preferred when available. Both are optional - downtime can be tracked without a specific reason.
Authentication Required: API Key or JWT Bearer Token
Set an asset online and end downtime tracking. Ideal for Kepware/PLC integration.
{
"assetId": number, // Required: ID of the asset to set online
"downtimeTrackingId": number, // Optional: Specific downtime record ID (if not provided, finds most recent open record)
"endTimeUtc": "datetime" // Optional: End time (defaults to current UTC time if not provided)
}
Authentication Required: API Key or JWT Bearer Token
NEW! High-performance batch endpoint optimized for Kepware IoT Gateway integration. Processes multiple asset state changes in a single API call with automatic deduplication and state validation.
Batch update asset online/offline status from Kepware IoT Gateway. This endpoint is specifically designed to work with Kepware's native IoT Gateway JSON format.
{
"timestamp": 1770143088685, // Optional: Unix milliseconds (not used, per-tag timestamps take precedence)
"values": [
{
"id": "PLC.Line1.PRESS-001", // Tag path - asset code extracted from last segment
"v": 5, // Value: -1 = online, >0 = reason ID for offline
"q": true, // Quality: true = good, false = bad (bad quality skipped)
"t": 1770143088685 // Tag timestamp: Unix milliseconds
},
{
"id": "Building.Floor2.WELD-003",
"v": -1, // -1 means bring asset online
"q": true,
"t": 1770143089865
}
]
}
The endpoint extracts the asset code from the last segment of the tag path (after the final period):
"PLC.Line1.PRESS-001" → Asset code: PRESS-001"Building.Floor2.WELD-003" → Asset code: WELD-003"STMP" → Asset code: STMPNote: Asset code matching is case-insensitive. The asset must exist in your organization.
| Value | Meaning | Action |
|---|---|---|
-1 |
Asset is online | Closes open downtime record, calculates cost, marks asset online |
> 0 |
Asset is offline | Creates downtime record with reason ID = value, marks asset offline |
0 |
Invalid | Skipped with error message |
When multiple updates for the same asset appear in a single batch request:
t) is processedExample: If you send 3 updates for "PRESS-001" with timestamps 100, 200, 150, only the update with timestamp 200 will be processed.
Records with "q": false (bad quality) are automatically filtered out and not processed. Only good quality data ("q": true) affects asset state.
{
"success": true, // Overall success (false if any errors occurred)
"processedCount": 2, // Number of assets successfully updated
"skippedCount": 0, // Number of assets skipped (errors, invalid state, etc.)
"errors": [], // Array of error messages
"updates": [
{
"tagId": "PLC.Line1.PRESS-001",
"assetCode": "PRESS-001",
"assetId": 123,
"previousState": "online", // State before this update
"newState": "offline", // State after this update
"status": "offline", // (Deprecated, use newState)
"stateTransition": "online → offline", // Visual representation
"reason": "Unplanned Breakdown", // Downtime reason (if going offline)
"timestamp": "2026-03-02T18:31:28.685Z",
"downtimeTrackingId": 456 // ID of created/closed downtime record
},
{
"tagId": "Building.Floor2.WELD-003",
"assetCode": "WELD-003",
"assetId": 124,
"previousState": "offline",
"newState": "online",
"status": "online",
"stateTransition": "offline → online",
"timestamp": "2026-03-02T18:31:29.865Z",
"downtimeTrackingId": 789
}
]
}
| Error | Cause | Solution |
|---|---|---|
| Asset 'STMP' not found | Asset code doesn't exist in organization | Create asset in Kaizely with exact code |
| Asset already online | Trying to set online when already online | No action needed - skip is normal |
| Asset already offline | Trying to set offline when already offline | No action needed - skip is normal |
| Downtime reason ID 5 not found | Reason ID doesn't exist in organization | Create reason in Admin → Manage Downtime Reasons |
| No open downtime record | Trying to set online but no downtime was started | Ensure asset was set offline before bringing online |
1. Configure Kepware Tag Structure:
// In your PLC/Kepware, create tags like:
PLC.Line1.PRESS-001 // Integer: -1=online, >0=reason ID
PLC.Line1.WELD-003 // Integer: -1=online, >0=reason ID
Building.STMP // Integer: -1=online, >0=reason ID
2. Configure IoT Gateway:
https://your-kaizely-instance.com/api/KepwareDowntime/batchContent-Type: application/json
X-API-Key: kzly_your_api_key_here
3. PLC Logic Example:
// In PLC ladder logic or structured text:
IF machine_running THEN
status_tag := -1 // Online
ELSIF breakdown_detected THEN
status_tag := 5 // Offline with reason ID 5 (Unplanned Breakdown)
ELSIF maintenance_mode THEN
status_tag := 3 // Offline with reason ID 3 (Planned Maintenance)
END_IF
Every successful state change generates detailed log entries:
// Going offline:
Asset PRESS-001 successfully transitioned online → offline with reason 'Unplanned Breakdown' (ID: 5)
// Coming back online:
Asset PRESS-001 successfully transitioned offline → online,
closed downtime ID 456, duration: 2.35 hours, cost: $47.50
errors array in responses for configuration issuesAuthentication Required: API Key or JWT Bearer Token