Skip to main content

Systems

A System is what the edge agent (or a polling source) connects to: a PLC, an OPC UA server, a folder of CSV exports. It owns every tag it sends. A machine lives inside a System and is made of the tags assigned to it; alerts, health, OEE and predictions stay per machine. A reading names its System by identifier (system_identifier, or machine_identifier under its earlier name) and is routed to a machine by its tag.

All endpoints require a bearer JWT, the Systems page (administrators have it by default; it can be granted per role or per user), and access to every machine: a user limited to some machine groups gets 403, because a System's tags can feed machines outside their groups. Creating, changing and assigning also need the administrator tier and the systems.write action; deleting needs systems.delete. Every write is recorded in the audit log under the resource system.

Endpoints​

MethodPathDescription
GET/api/v1/systemsList Systems
GET/api/v1/systems/summaryUnassigned tags across the company
POST/api/v1/systemsCreate a System
GET/api/v1/systems/{system_id}Get a System
PATCH/api/v1/systems/{system_id}Update a System
DELETE/api/v1/systems/{system_id}Delete a System
GET/api/v1/systems/{system_id}/tagsList a System's tags
POST/api/v1/systems/{system_id}/tags/assignAssign tags to a machine
POST/api/v1/systems/{system_id}/tags/unassignUnassign tags
POST/api/v1/systems/{system_id}/tags/assign-unassignedAssign every unassigned tag to a machine

The System object​

{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"tenant_id": "3f2504e0-4f89-41d3-9a0c-0305e82c3301",
"name": "Line 3 PLC",
"system_identifier": "LINE-3-PLC",
"protocol": "s7",
"location": "Hall B",
"is_active": true,
"machine_count": 2,
"unassigned_tag_count": 5,
"last_seen_at": "2026-10-08T09:41:00Z",
"status": "receiving",
"created_at": "2026-10-08T08:00:00Z",
"updated_at": "2026-10-08T08:00:00Z"
}

status is receiving (data in the last 24 hours), silent (data once, none since) or never_seen.

List Systems​

GET /api/v1/systems

ParameterTypeDefaultDescription
pageinteger1Page number
page_sizeinteger20Items per page (max 100)
searchstringMatch name or identifier

Returns { "items": [System, …], "pagination": { "total", "page", "page_size" } }.

Unassigned tags​

GET /api/v1/systems/summary returns { "unassigned_tags": 3 }: tags, across every active System, that belong to no machine yet.

Create a System​

POST /api/v1/systems

FieldTypeRequiredDescription
namestringYes1–255 chars
system_identifierstringYesWhat the agent sends; unique per company (1–255 chars)
protocolstringYesOne of opc_ua, modbus_tcp, modbus_rtu, s7, ethernet_ip, melsec, fins, ads, bacnet_ip, mqtt, sparkplug_b, pi_web_api, csv, json
locationstringNoUp to 500 chars

A System's protocol is a label for how it is read. Two other settings name protocols with their own spellings: a polled source's protocol (opcua or modbus, see Sensor Data) and an Edge Agent source's type (modbus, modbus_rtu, opcua, s7, ethernet_ip, melsec, fins, ads, bacnet, mqtt, sparkplug_b, pi_web_api, csv, json, see Edge Agent configuration). Use the spelling each field lists.

Returns 201 Created with the System; 409 if the identifier is taken. A new System has no machines; every tag it sends waits, unassigned, until you assign it. Add machines to it with POST /api/v1/machines and system_id (see Machines).

Get, update and delete​

GET /api/v1/systems/{system_id} returns one System (404 if it is not yours). PATCH takes any of the create fields (409 on a taken identifier). DELETE returns 204 No Content, or 409 while the System still has machines: delete or move them first. A deleted System's tags and history stay, its polling sources stop, and its identifier can be given to a new System.

A System's tags​

GET /api/v1/systems/{system_id}/tags

ParameterTypeDefaultDescription
filterstringallall, unassigned or assigned
machine_iduuidOnly the tags of this machine
searchstringMatch the tag, its metric or its name
page, page_sizeinteger1, 20Paging (max 100)

Unassigned tags come first.

{
"items": [
{
"id": "1b4e28ba-2fa1-11d2-883f-0016d3cca427",
"system_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"tag": "DB10.DBD4:REAL",
"is_raw": true,
"metric_name": "oil_temp",
"unit": "celsius",
"machine_id": null,
"machine_name": null,
"standardized_name": null,
"is_confirmed": false,
"last_seen_at": "2026-10-08T09:41:00Z",
"assigned_at": null,
"state": "receiving"
}
],
"pagination": { "total": 1, "page": 1, "page_size": 20 }
}

A tag's state is receiving or silent (nothing in the last 24 hours).

Assign and unassign​

POST /api/v1/systems/{system_id}/tags/assign

{ "tag_ids": ["1b4e28ba-2fa1-11d2-883f-0016d3cca427"], "machine_id": "550e8400-e29b-41d4-a716-446655440000" }

Up to 500 tags per request. Returns { "assigned": 1, "history_moving": 1 }.

POST /api/v1/systems/{system_id}/tags/unassign takes { "tag_ids": [...] }; POST /api/v1/systems/{system_id}/tags/assign-unassigned takes { "machine_id": "…" } and assigns every tag the System has waiting.

What happens to readings already stored:

  • Assigning a tag that was unassigned moves its waiting readings to the machine, in the background (history_moving counts those tags). They feed the machine's baselines at the next baseline run; they raise no alerts.
  • Reassigning a tag to another machine, or unassigning it, changes only what happens next: readings already stored stay with the machine they belonged to.
  • If a move is interrupted (a restart, say), a background sweep finishes it within a few minutes.

Errors

StatusWhen
404A tag is not on this System, or the machine is not one of yours
409The machine belongs to another System
409The machine would have two tags recording the same metric. The whole request is refused; the message names the metric and the tags